Merge branch 'admin-relay-api' into 'main'
Add an API to manage admin relays See merge request soapbox-pub/ditto!178
This commit is contained in:
commit
443cede73e
|
@ -77,6 +77,7 @@ import { auth19, requirePubkey } from '@/middleware/auth19.ts';
|
||||||
import { auth98, requireProof, requireRole } from '@/middleware/auth98.ts';
|
import { auth98, requireProof, requireRole } from '@/middleware/auth98.ts';
|
||||||
import { cache } from '@/middleware/cache.ts';
|
import { cache } from '@/middleware/cache.ts';
|
||||||
import { csp } from '@/middleware/csp.ts';
|
import { csp } from '@/middleware/csp.ts';
|
||||||
|
import { adminRelaysController } from '@/controllers/api/ditto.ts';
|
||||||
|
|
||||||
interface AppEnv extends HonoEnv {
|
interface AppEnv extends HonoEnv {
|
||||||
Variables: {
|
Variables: {
|
||||||
|
@ -187,11 +188,14 @@ app.get('/api/v1/favourites', requirePubkey, favouritesController);
|
||||||
app.get('/api/v1/bookmarks', requirePubkey, bookmarksController);
|
app.get('/api/v1/bookmarks', requirePubkey, bookmarksController);
|
||||||
app.get('/api/v1/blocks', requirePubkey, blocksController);
|
app.get('/api/v1/blocks', requirePubkey, blocksController);
|
||||||
|
|
||||||
app.get('/api/v1/admin/accounts', adminAccountsController);
|
app.get('/api/v1/admin/accounts', requireRole('admin'), adminAccountsController);
|
||||||
app.get('/api/v1/pleroma/admin/config', requireRole('admin'), configController);
|
app.get('/api/v1/pleroma/admin/config', requireRole('admin'), configController);
|
||||||
app.post('/api/v1/pleroma/admin/config', requireRole('admin'), updateConfigController);
|
app.post('/api/v1/pleroma/admin/config', requireRole('admin'), updateConfigController);
|
||||||
app.delete('/api/v1/pleroma/admin/statuses/:id', requireRole('admin'), pleromaAdminDeleteStatusController);
|
app.delete('/api/v1/pleroma/admin/statuses/:id', requireRole('admin'), pleromaAdminDeleteStatusController);
|
||||||
|
|
||||||
|
app.get('/api/v1/admin/ditto/relays', requireRole('admin'), adminRelaysController);
|
||||||
|
app.put('/api/v1/admin/ditto/relays', requireRole('admin'), adminRelaysController);
|
||||||
|
|
||||||
// Not (yet) implemented.
|
// Not (yet) implemented.
|
||||||
app.get('/api/v1/custom_emojis', emptyArrayController);
|
app.get('/api/v1/custom_emojis', emptyArrayController);
|
||||||
app.get('/api/v1/filters', emptyArrayController);
|
app.get('/api/v1/filters', emptyArrayController);
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
import { NostrEvent } from '@nostrify/nostrify';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { AppController } from '@/app.ts';
|
||||||
|
import { Conf } from '@/config.ts';
|
||||||
|
import { eventsDB } from '@/storages.ts';
|
||||||
|
import { AdminSigner } from '@/signers/AdminSigner.ts';
|
||||||
|
|
||||||
|
const relaySchema = z.object({
|
||||||
|
url: z.string().url(),
|
||||||
|
read: z.boolean(),
|
||||||
|
write: z.boolean(),
|
||||||
|
});
|
||||||
|
|
||||||
|
type RelayEntity = z.infer<typeof relaySchema>;
|
||||||
|
|
||||||
|
export const adminRelaysController: AppController = async (c) => {
|
||||||
|
const [event] = await eventsDB.query([
|
||||||
|
{ kinds: [10002], authors: [Conf.pubkey], limit: 1 },
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!event) {
|
||||||
|
return c.json([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.json(renderRelays(event));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const adminSetRelaysController: AppController = async (c) => {
|
||||||
|
const relays = relaySchema.array().parse(await c.req.json());
|
||||||
|
|
||||||
|
const event = await new AdminSigner().signEvent({
|
||||||
|
kind: 10002,
|
||||||
|
tags: relays.map(({ url, read, write }) => ['r', url, read && write ? '' : read ? 'read' : 'write']),
|
||||||
|
content: '',
|
||||||
|
created_at: Math.floor(Date.now() / 1000),
|
||||||
|
});
|
||||||
|
|
||||||
|
await eventsDB.event(event);
|
||||||
|
|
||||||
|
return c.json(renderRelays(event));
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Render Ditto API relays from a NIP-65 event. */
|
||||||
|
function renderRelays(event: NostrEvent): RelayEntity[] {
|
||||||
|
return event.tags.reduce((acc, [name, url, marker]) => {
|
||||||
|
if (name === 'r') {
|
||||||
|
const relay: RelayEntity = {
|
||||||
|
url,
|
||||||
|
read: !marker || marker === 'read',
|
||||||
|
write: !marker || marker === 'write',
|
||||||
|
};
|
||||||
|
acc.push(relay);
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, [] as RelayEntity[]);
|
||||||
|
}
|
Loading…
Reference in New Issue