Refactor reports more, add reopen endpoint

This commit is contained in:
Alex Gleason
2024-06-09 11:03:46 -05:00
parent 177f25ad96
commit 8a7cae9841
5 changed files with 153 additions and 37 deletions

View File

@@ -1,12 +1,13 @@
import { NostrEvent } from '@nostrify/nostrify';
import { NostrEvent, NostrFilter, NSchema as n } from '@nostrify/nostrify';
import { z } from 'zod';
import { AppController } from '@/app.ts';
import { Conf } from '@/config.ts';
import { booleanParamSchema } from '@/schema.ts';
import { AdminSigner } from '@/signers/AdminSigner.ts';
import { Storages } from '@/storages.ts';
import { hydrateEvents } from '@/storages/hydrate.ts';
import { createEvent } from '@/utils/api.ts';
import { createEvent, paginated, paginationSchema } from '@/utils/api.ts';
import { renderNameRequest } from '@/views/ditto.ts';
const markerSchema = z.enum(['read', 'write']);
@@ -87,14 +88,98 @@ export const nameRequestController: AppController = async (c) => {
return c.json(nameRequest);
};
const nameRequestsSchema = z.object({
approved: booleanParamSchema.optional(),
rejected: booleanParamSchema.optional(),
});
export const nameRequestsController: AppController = async (c) => {
const store = await Storages.db();
const signer = c.get('signer')!;
const pubkey = await signer.getPublicKey();
const events = await store.query([{ kinds: [3036], authors: [pubkey], limit: 20 }])
.then((events) => hydrateEvents({ events, store }));
const params = paginationSchema.parse(c.req.query());
const { approved, rejected } = nameRequestsSchema.parse(c.req.query());
const nameRequests = await Promise.all(events.map(renderNameRequest));
return c.json(nameRequests);
const filter: NostrFilter = {
kinds: [30383],
authors: [Conf.pubkey],
'#k': ['3036'],
'#p': [pubkey],
...params,
};
if (approved) {
filter['#n'] = ['approved'];
}
if (rejected) {
filter['#n'] = ['rejected'];
}
const orig = await store.query([filter]);
const ids = new Set<string>();
for (const event of orig) {
const d = event.tags.find(([name]) => name === 'd')?.[1];
if (d) {
ids.add(d);
}
}
const events = await store.query([{ kinds: [3036], ids: [...ids] }])
.then((events) => hydrateEvents({ store, events: events, signal: c.req.raw.signal }));
const nameRequests = await Promise.all(
events.map((event) => renderNameRequest(event)),
);
return paginated(c, orig, nameRequests);
};
const adminNameRequestsSchema = z.object({
account_id: n.id().optional(),
approved: booleanParamSchema.optional(),
rejected: booleanParamSchema.optional(),
});
export const adminNameRequestsController: AppController = async (c) => {
const store = await Storages.db();
const params = paginationSchema.parse(c.req.query());
const { account_id, approved, rejected } = adminNameRequestsSchema.parse(c.req.query());
const filter: NostrFilter = {
kinds: [30383],
authors: [Conf.pubkey],
'#k': ['3036'],
...params,
};
if (account_id) {
filter['#p'] = [account_id];
}
if (approved) {
filter['#n'] = ['approved'];
}
if (rejected) {
filter['#n'] = ['rejected'];
}
const orig = await store.query([filter]);
const ids = new Set<string>();
for (const event of orig) {
const d = event.tags.find(([name]) => name === 'd')?.[1];
if (d) {
ids.add(d);
}
}
const events = await store.query([{ kinds: [3036], ids: [...ids] }])
.then((events) => hydrateEvents({ store, events: events, signal: c.req.raw.signal }));
const nameRequests = await Promise.all(
events.map((event) => renderNameRequest(event)),
);
return paginated(c, orig, nameRequests);
};

View File

@@ -7,7 +7,6 @@ import { createEvent, paginationSchema, parseBody, updateEventInfo } from '@/uti
import { hydrateEvents } from '@/storages/hydrate.ts';
import { renderAdminReport } from '@/views/mastodon/reports.ts';
import { renderReport } from '@/views/mastodon/reports.ts';
import { getTagSet } from '@/utils/tags.ts';
import { booleanParamSchema } from '@/schema.ts';
const reportSchema = z.object({
@@ -71,6 +70,7 @@ const adminReportsController: AppController = async (c) => {
const filter: NostrFilter = {
kinds: [30383],
authors: [Conf.pubkey],
'#k': ['1984'],
...params,
};
@@ -98,15 +98,7 @@ const adminReportsController: AppController = async (c) => {
.then((events) => hydrateEvents({ store, events: events, signal: c.req.raw.signal }));
const reports = await Promise.all(
events.map((event) => {
const internal = orig.find(({ tags }) => tags.some(([name, value]) => name === 'd' && value === event.id));
const names = getTagSet(internal?.tags ?? [], 'n');
return renderAdminReport(event, {
viewerPubkey,
actionTaken: names.has('closed'),
});
}),
events.map((event) => renderAdminReport(event, { viewerPubkey })),
);
return c.json(reports);
@@ -153,11 +145,39 @@ const adminReportResolveController: AppController = async (c) => {
}
await updateEventInfo(eventId, { open: false, closed: true }, c);
await hydrateEvents({ events: [event], store, signal });
const report = await renderAdminReport(event, { viewerPubkey: pubkey, actionTaken: true });
const report = await renderAdminReport(event, { viewerPubkey: pubkey });
return c.json(report);
};
export { adminReportController, adminReportResolveController, adminReportsController, reportController };
const adminReportReopenController: AppController = async (c) => {
const eventId = c.req.param('id');
const { signal } = c.req.raw;
const store = c.get('store');
const pubkey = await c.get('signer')?.getPublicKey();
const [event] = await store.query([{
kinds: [1984],
ids: [eventId],
limit: 1,
}], { signal });
if (!event) {
return c.json({ error: 'Not found' }, 404);
}
await updateEventInfo(eventId, { open: true, closed: false }, c);
await hydrateEvents({ events: [event], store, signal });
const report = await renderAdminReport(event, { viewerPubkey: pubkey });
return c.json(report);
};
export {
adminReportController,
adminReportReopenController,
adminReportResolveController,
adminReportsController,
reportController,
};