refactor: view info about all reports

This commit is contained in:
P. Reis 2024-05-05 14:20:13 -03:00
parent d903a2d0fb
commit 7890504add
5 changed files with 27 additions and 45 deletions

View File

@ -1,11 +1,12 @@
import { type AppController } from '@/app.ts';
import { createEvent, parseBody } from '@/utils/api.ts';
import { Conf } from '@/config.ts';
import { hydrateEvents } from '@/storages/hydrate.ts';
import { NSchema as n } from '@nostrify/nostrify'; import { NSchema as n } from '@nostrify/nostrify';
import { renderReport } from '@/views/mastodon/reports.ts';
import { z } from 'zod'; import { z } from 'zod';
import { type AppController } from '@/app.ts';
import { Conf } from '@/config.ts';
import { createEvent, parseBody } from '@/utils/api.ts';
import { hydrateEvents } from '@/storages/hydrate.ts';
import { renderAdminReport } from '@/views/mastodon/reports.ts'; import { renderAdminReport } from '@/views/mastodon/reports.ts';
import { renderReport } from '@/views/mastodon/reports.ts';
const reportsSchema = z.object({ const reportsSchema = z.object({
account_id: n.id(), account_id: n.id(),
@ -54,17 +55,11 @@ const reportsController: AppController = async (c) => {
/** https://docs.joinmastodon.org/methods/admin/reports/#get */ /** https://docs.joinmastodon.org/methods/admin/reports/#get */
const viewAllReportsController: AppController = async (c) => { const viewAllReportsController: AppController = async (c) => {
const store = c.get('store'); const store = c.get('store');
const allMastodonReports = []; const reports = await store.query([{ kinds: [1984], '#P': [Conf.pubkey] }])
.then((events) => hydrateEvents({ storage: store, events: events, signal: c.req.raw.signal }))
.then((events) => Promise.all(events.map((event) => renderAdminReport(event, { viewerPubkey: c.get('pubkey') }))));
const allReports = await store.query([{ kinds: [1984], '#P': [Conf.pubkey] }]); return c.json(reports);
await hydrateEvents({ storage: store, events: allReports, signal: AbortSignal.timeout(2000) });
for (const report of allReports) {
allMastodonReports.push(await renderAdminReport(report, { viewerPubkey: c.get('pubkey') }));
}
return c.json(allMastodonReports);
}; };
export { reportsController, viewAllReportsController }; export { reportsController, viewAllReportsController };

View File

@ -25,14 +25,13 @@ export interface DittoEvent extends NostrEvent {
repost?: DittoEvent; repost?: DittoEvent;
quote_repost?: DittoEvent; quote_repost?: DittoEvent;
reacted?: DittoEvent; reacted?: DittoEvent;
/** The account being reported. /** The profile being reported.
* Must be a kind 0 hydrated. * Must be a kind 0 hydrated.
* https://github.com/nostr-protocol/nips/blob/master/56.md * https://github.com/nostr-protocol/nips/blob/master/56.md
*/ */
target_account?: DittoEvent; reported_profile?: DittoEvent;
/** The statuses being reported. /** The notes being reported.
* Nostr only support reporting one note, the array of reported notes can be found in the `status_ids` field after JSON.parsing the `content` of a kind 1984.
* https://github.com/nostr-protocol/nips/blob/master/56.md * https://github.com/nostr-protocol/nips/blob/master/56.md
*/ */
reported_statuses?: DittoEvent[]; reported_notes?: DittoEvent[];
} }

View File

@ -42,11 +42,11 @@ async function hydrateEvents(opts: HydrateOpts): Promise<DittoEvent[]> {
cache.push(event); cache.push(event);
} }
for (const event of await gatherTargetAccounts({ events: cache, storage, signal })) { for (const event of await gatherReportedProfiles({ events: cache, storage, signal })) {
cache.push(event); cache.push(event);
} }
for (const event of await gatherReportedStatuses({ events: cache, storage, signal })) { for (const event of await gatherReportedNotes({ events: cache, storage, signal })) {
cache.push(event); cache.push(event);
} }
@ -101,12 +101,7 @@ function assembleEvents(
if (event.kind === 1984) { if (event.kind === 1984) {
const targetAccountId = event.tags.find(([name]) => name === 'p')?.[1]; const targetAccountId = event.tags.find(([name]) => name === 'p')?.[1];
if (targetAccountId) { if (targetAccountId) {
event.target_account = b.find((e) => matchFilter({ kinds: [0], authors: [targetAccountId] }, e)); event.reported_profile = b.find((e) => matchFilter({ kinds: [0], authors: [targetAccountId] }, e));
if (event.target_account) {
event.target_account.user = b.find((e) =>
matchFilter({ kinds: [30361], authors: [admin], '#d': [event.pubkey] }, e)
);
}
} }
const reportedEvents: DittoEvent[] = []; const reportedEvents: DittoEvent[] = [];
@ -118,7 +113,7 @@ function assembleEvents(
if (reportedEvent) reportedEvents.push(reportedEvent); if (reportedEvent) reportedEvents.push(reportedEvent);
} }
} }
event.reported_statuses = reportedEvents; event.reported_notes = reportedEvents;
} }
} }
@ -206,8 +201,8 @@ function gatherUsers({ events, storage, signal }: HydrateOpts): Promise<DittoEve
); );
} }
/** Collect reported statuses from the events. */ /** Collect reported notes from the events. */
function gatherReportedStatuses({ events, storage, signal }: HydrateOpts): Promise<DittoEvent[]> { function gatherReportedNotes({ events, storage, signal }: HydrateOpts): Promise<DittoEvent[]> {
const ids = new Set<string>(); const ids = new Set<string>();
for (const event of events) { for (const event of events) {
if (event.kind === 1984) { if (event.kind === 1984) {
@ -226,8 +221,8 @@ function gatherReportedStatuses({ events, storage, signal }: HydrateOpts): Promi
); );
} }
/** Collect target accounts (the ones being reported) from the events. */ /** Collect reported profiles from the events. */
function gatherTargetAccounts({ events, storage, signal }: HydrateOpts): Promise<DittoEvent[]> { function gatherReportedProfiles({ events, storage, signal }: HydrateOpts): Promise<DittoEvent[]> {
const pubkeys = new Set<string>(); const pubkeys = new Set<string>();
for (const event of events) { for (const event of events) {

View File

@ -1,18 +1,11 @@
import { type DittoEvent } from '@/interfaces/DittoEvent.ts'; import { type DittoEvent } from '@/interfaces/DittoEvent.ts';
import { nostrDate } from '@/utils.ts'; import { nostrDate } from '@/utils.ts';
import { accountFromPubkey, renderAccount } from '@/views/mastodon/accounts.ts'; import { renderAccount } from '@/views/mastodon/accounts.ts';
/** Expects a kind 0 fully hydrated or a kind 30361 hydrated with `d_author` */ /** Expects a kind 0 fully hydrated or a kind 30361 hydrated with `d_author` */
async function renderAdminAccount(event: DittoEvent) { async function renderAdminAccount(event: DittoEvent) {
let account; const account = await renderAccount(event);
if (event && event.kind === 0 && event.user) {
account = await renderAccount(event);
} else {
const d = event.tags.find(([name]) => name === 'd')?.[1]!;
account = event.d_author ? await renderAccount({ ...event.d_author, user: event }) : await accountFromPubkey(d);
}
return { return {
id: account.id, id: account.id,

View File

@ -45,8 +45,8 @@ async function renderAdminReport(reportEvent: DittoEvent, opts: RenderAdminRepor
} = JSON.parse(reportEvent.content); } = JSON.parse(reportEvent.content);
const statuses = []; const statuses = [];
if (reportEvent.reported_statuses) { if (reportEvent.reported_notes) {
for (const status of reportEvent.reported_statuses) { for (const status of reportEvent.reported_notes) {
statuses.push(await renderStatus(status, { viewerPubkey })); statuses.push(await renderStatus(status, { viewerPubkey }));
} }
} }
@ -60,7 +60,7 @@ async function renderAdminReport(reportEvent: DittoEvent, opts: RenderAdminRepor
forwarded: forward, forwarded: forward,
created_at: nostrDate(reportEvent.created_at).toISOString(), created_at: nostrDate(reportEvent.created_at).toISOString(),
account: await renderAdminAccount(reportEvent.author as DittoEvent), account: await renderAdminAccount(reportEvent.author as DittoEvent),
target_account: await renderAdminAccount(reportEvent.target_account as DittoEvent), target_account: await renderAdminAccount(reportEvent.reported_profile as DittoEvent),
assigned_account: null, assigned_account: null,
action_taken_by_account: null, action_taken_by_account: null,
statuses, statuses,