Add admin name approve/reject endpoints

This commit is contained in:
Alex Gleason 2024-06-09 11:57:10 -05:00
parent 594f37ea33
commit 2a2f43d106
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
3 changed files with 73 additions and 2 deletions

View File

@ -30,7 +30,15 @@ import { adminAccountsController, adminActionController } from '@/controllers/ap
import { appCredentialsController, createAppController } from '@/controllers/api/apps.ts'; import { appCredentialsController, createAppController } from '@/controllers/api/apps.ts';
import { blocksController } from '@/controllers/api/blocks.ts'; import { blocksController } from '@/controllers/api/blocks.ts';
import { bookmarksController } from '@/controllers/api/bookmarks.ts'; import { bookmarksController } from '@/controllers/api/bookmarks.ts';
import { adminRelaysController, adminSetRelaysController, nameRequestController } from '@/controllers/api/ditto.ts'; import {
adminNameApproveController,
adminNameRejectController,
adminNameRequestsController,
adminRelaysController,
adminSetRelaysController,
nameRequestController,
nameRequestsController,
} from '@/controllers/api/ditto.ts';
import { emptyArrayController, emptyObjectController, notImplementedController } from '@/controllers/api/fallback.ts'; import { emptyArrayController, emptyObjectController, notImplementedController } from '@/controllers/api/fallback.ts';
import { instanceController } from '@/controllers/api/instance.ts'; import { instanceController } from '@/controllers/api/instance.ts';
import { markersController, updateMarkersController } from '@/controllers/api/markers.ts'; import { markersController, updateMarkersController } from '@/controllers/api/markers.ts';
@ -245,6 +253,12 @@ app.get('/api/v1/admin/ditto/relays', requireRole('admin'), adminRelaysControlle
app.put('/api/v1/admin/ditto/relays', requireRole('admin'), adminSetRelaysController); app.put('/api/v1/admin/ditto/relays', requireRole('admin'), adminSetRelaysController);
app.post('/api/v1/ditto/names', requireSigner, nameRequestController); app.post('/api/v1/ditto/names', requireSigner, nameRequestController);
app.get('/api/v1/ditto/names', requireSigner, nameRequestsController);
app.get('/api/v1/admin/ditto/names', requireRole('admin'), adminNameRequestsController);
app.post('/api/v1/admin/ditto/names/:id{[0-9a-f]{64}}/approve', requireRole('admin'), adminNameApproveController);
app.post('/api/v1/admin/ditto/names/:id{[0-9a-f]{64}}/reject', requireRole('admin'), adminNameRejectController);
app.post('/api/v1/ditto/zap', requireSigner, zapController); app.post('/api/v1/ditto/zap', requireSigner, zapController);
app.post('/api/v1/reports', requireSigner, reportController); app.post('/api/v1/reports', requireSigner, reportController);

View File

@ -7,7 +7,7 @@ import { booleanParamSchema } from '@/schema.ts';
import { AdminSigner } from '@/signers/AdminSigner.ts'; import { AdminSigner } from '@/signers/AdminSigner.ts';
import { Storages } from '@/storages.ts'; import { Storages } from '@/storages.ts';
import { hydrateEvents } from '@/storages/hydrate.ts'; import { hydrateEvents } from '@/storages/hydrate.ts';
import { createEvent, paginated, paginationSchema } from '@/utils/api.ts'; import { createAdminEvent, createEvent, paginated, paginationSchema, updateEventInfo } from '@/utils/api.ts';
import { renderNameRequest } from '@/views/ditto.ts'; import { renderNameRequest } from '@/views/ditto.ts';
const markerSchema = z.enum(['read', 'write']); const markerSchema = z.enum(['read', 'write']);
@ -183,3 +183,58 @@ export const adminNameRequestsController: AppController = async (c) => {
return paginated(c, orig, nameRequests); return paginated(c, orig, nameRequests);
}; };
export const adminNameApproveController: AppController = async (c) => {
const eventId = c.req.param('id');
const store = await Storages.db();
const [event] = await store.query([{ kinds: [3036], ids: [eventId] }]);
if (!event) {
return c.json({ error: 'Event not found' }, 404);
}
const r = event.tags.find(([name]) => name === 'r')?.[1];
if (!r) {
return c.json({ error: 'NIP-05 not found' }, 404);
}
if (!z.string().email().safeParse(r).success) {
return c.json({ error: 'Invalid NIP-05' }, 400);
}
const [existing] = await store.query([{ kinds: [30360], authors: [Conf.pubkey], '#d': [r], limit: 1 }]);
if (existing) {
return c.json({ error: 'NIP-05 already granted to another user' }, 400);
}
await createAdminEvent({
kind: 30360,
tags: [
['d', r],
['L', 'nip05.domain'],
['l', r.split('@')[1], 'nip05.domain'],
['p', event.pubkey],
],
}, c);
await updateEventInfo(eventId, { pending: false, approved: true, rejected: false }, c);
await hydrateEvents({ events: [event], store });
const nameRequest = await renderNameRequest(event);
return c.json(nameRequest);
};
export const adminNameRejectController: AppController = async (c) => {
const eventId = c.req.param('id');
const store = await Storages.db();
const [event] = await store.query([{ kinds: [3036], ids: [eventId] }]);
if (!event) {
return c.json({ error: 'Event not found' }, 404);
}
await updateEventInfo(eventId, { pending: false, approved: false, rejected: true }, c);
await hydrateEvents({ events: [event], store });
const nameRequest = await renderNameRequest(event);
return c.json(nameRequest);
};

View File

@ -223,6 +223,8 @@ class EventsDB implements NStore {
return event.content; return event.content;
case 30009: case 30009:
return EventsDB.buildTagsSearchContent(event.tags.filter(([t]) => t !== 'alt')); return EventsDB.buildTagsSearchContent(event.tags.filter(([t]) => t !== 'alt'));
case 30360:
return event.tags.find(([name]) => name === 'd')?.[1] || '';
default: default:
return ''; return '';
} }