diff --git a/src/controllers/api/reports.ts b/src/controllers/api/reports.ts index 351c1c2..b49486c 100644 --- a/src/controllers/api/reports.ts +++ b/src/controllers/api/reports.ts @@ -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 { renderReport } from '@/views/mastodon/reports.ts'; 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 { renderReport } from '@/views/mastodon/reports.ts'; const reportsSchema = z.object({ account_id: n.id(), @@ -54,17 +55,11 @@ const reportsController: AppController = async (c) => { /** https://docs.joinmastodon.org/methods/admin/reports/#get */ const viewAllReportsController: AppController = async (c) => { 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] }]); - - 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); + return c.json(reports); }; export { reportsController, viewAllReportsController }; diff --git a/src/interfaces/DittoEvent.ts b/src/interfaces/DittoEvent.ts index f6810d3..32c6e93 100644 --- a/src/interfaces/DittoEvent.ts +++ b/src/interfaces/DittoEvent.ts @@ -25,14 +25,13 @@ export interface DittoEvent extends NostrEvent { repost?: DittoEvent; quote_repost?: DittoEvent; reacted?: DittoEvent; - /** The account being reported. + /** The profile being reported. * Must be a kind 0 hydrated. * https://github.com/nostr-protocol/nips/blob/master/56.md */ - target_account?: DittoEvent; - /** The statuses 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. + reported_profile?: DittoEvent; + /** The notes being reported. * https://github.com/nostr-protocol/nips/blob/master/56.md */ - reported_statuses?: DittoEvent[]; + reported_notes?: DittoEvent[]; } diff --git a/src/storages/hydrate.ts b/src/storages/hydrate.ts index ca439bd..ced61e6 100644 --- a/src/storages/hydrate.ts +++ b/src/storages/hydrate.ts @@ -42,11 +42,11 @@ async function hydrateEvents(opts: HydrateOpts): Promise { 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); } - for (const event of await gatherReportedStatuses({ events: cache, storage, signal })) { + for (const event of await gatherReportedNotes({ events: cache, storage, signal })) { cache.push(event); } @@ -101,12 +101,7 @@ function assembleEvents( if (event.kind === 1984) { const targetAccountId = event.tags.find(([name]) => name === 'p')?.[1]; if (targetAccountId) { - event.target_account = 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) - ); - } + event.reported_profile = b.find((e) => matchFilter({ kinds: [0], authors: [targetAccountId] }, e)); } const reportedEvents: DittoEvent[] = []; @@ -118,7 +113,7 @@ function assembleEvents( if (reportedEvent) reportedEvents.push(reportedEvent); } } - event.reported_statuses = reportedEvents; + event.reported_notes = reportedEvents; } } @@ -206,8 +201,8 @@ function gatherUsers({ events, storage, signal }: HydrateOpts): Promise { +/** Collect reported notes from the events. */ +function gatherReportedNotes({ events, storage, signal }: HydrateOpts): Promise { const ids = new Set(); for (const event of events) { 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. */ -function gatherTargetAccounts({ events, storage, signal }: HydrateOpts): Promise { +/** Collect reported profiles from the events. */ +function gatherReportedProfiles({ events, storage, signal }: HydrateOpts): Promise { const pubkeys = new Set(); for (const event of events) { diff --git a/src/views/mastodon/admin-accounts.ts b/src/views/mastodon/admin-accounts.ts index b344608..411a655 100644 --- a/src/views/mastodon/admin-accounts.ts +++ b/src/views/mastodon/admin-accounts.ts @@ -1,18 +1,11 @@ import { type DittoEvent } from '@/interfaces/DittoEvent.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` */ async function renderAdminAccount(event: DittoEvent) { - let account; - - 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); - } + const account = await renderAccount(event); return { id: account.id, diff --git a/src/views/mastodon/reports.ts b/src/views/mastodon/reports.ts index 50fea46..453151d 100644 --- a/src/views/mastodon/reports.ts +++ b/src/views/mastodon/reports.ts @@ -45,8 +45,8 @@ async function renderAdminReport(reportEvent: DittoEvent, opts: RenderAdminRepor } = JSON.parse(reportEvent.content); const statuses = []; - if (reportEvent.reported_statuses) { - for (const status of reportEvent.reported_statuses) { + if (reportEvent.reported_notes) { + for (const status of reportEvent.reported_notes) { statuses.push(await renderStatus(status, { viewerPubkey })); } } @@ -60,7 +60,7 @@ async function renderAdminReport(reportEvent: DittoEvent, opts: RenderAdminRepor forwarded: forward, created_at: nostrDate(reportEvent.created_at).toISOString(), 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, action_taken_by_account: null, statuses,