From 394599734f5750b80bd4dde9fcfd3eeb5e478e46 Mon Sep 17 00:00:00 2001 From: "P. Reis" Date: Sun, 5 May 2024 15:45:24 -0300 Subject: [PATCH] fix(reports): put notes in tag & only let comment in event.content --- src/controllers/api/reports.ts | 18 +++++++++++------- src/storages/hydrate.ts | 16 +++++++--------- src/views/mastodon/reports.ts | 32 ++++++++++++++------------------ 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/controllers/api/reports.ts b/src/controllers/api/reports.ts index b49486c..3486550 100644 --- a/src/controllers/api/reports.ts +++ b/src/controllers/api/reports.ts @@ -12,7 +12,6 @@ const reportsSchema = z.object({ account_id: n.id(), status_ids: n.id().array().default([]), comment: z.string().max(1000).default(''), - forward: z.boolean().default(false), category: z.string().default('other'), // TODO: rules_ids[] is not implemented }); @@ -31,7 +30,6 @@ const reportsController: AppController = async (c) => { account_id, status_ids, comment, - forward, category, } = result.data; @@ -40,13 +38,19 @@ const reportsController: AppController = async (c) => { await hydrateEvents({ events: [profile], storage: store }); } + const tags = [ + ['p', account_id, category], + ['P', Conf.pubkey], + ]; + + for (const status of status_ids) { + tags.push(['e', status, category]); + } + const event = await createEvent({ kind: 1984, - content: JSON.stringify({ account_id, status_ids, comment, forward, category }), - tags: [ - ['p', account_id, category], - ['P', Conf.pubkey], - ], + content: comment, + tags, }, c); return c.json(await renderReport(event, profile)); diff --git a/src/storages/hydrate.ts b/src/storages/hydrate.ts index ced61e6..41670aa 100644 --- a/src/storages/hydrate.ts +++ b/src/storages/hydrate.ts @@ -105,13 +105,11 @@ function assembleEvents( } const reportedEvents: DittoEvent[] = []; - const { status_ids } = JSON.parse(event.content); - if (status_ids && Array.isArray(status_ids)) { + const status_ids = event.tags.filter(([name]) => name === 'e').map((tag) => tag[1]); + if (status_ids.length > 0) { for (const id of status_ids) { - if (typeof id === 'string') { - const reportedEvent = b.find((e) => matchFilter({ kinds: [1], ids: [id] }, e)); - if (reportedEvent) reportedEvents.push(reportedEvent); - } + const reportedEvent = b.find((e) => matchFilter({ kinds: [1], ids: [id] }, e)); + if (reportedEvent) reportedEvents.push(reportedEvent); } event.reported_notes = reportedEvents; } @@ -206,10 +204,10 @@ function gatherReportedNotes({ events, storage, signal }: HydrateOpts): Promise< const ids = new Set(); for (const event of events) { if (event.kind === 1984) { - const { status_ids } = JSON.parse(event.content); - if (status_ids && Array.isArray(status_ids)) { + const status_ids = event.tags.filter(([name]) => name === 'e').map((tag) => tag[1]); + if (status_ids.length > 0) { for (const id of status_ids) { - if (typeof id === 'string') ids.add(id); + ids.add(id); } } } diff --git a/src/views/mastodon/reports.ts b/src/views/mastodon/reports.ts index 453151d..7e3460d 100644 --- a/src/views/mastodon/reports.ts +++ b/src/views/mastodon/reports.ts @@ -6,25 +6,24 @@ import { renderStatus } from '@/views/mastodon/statuses.ts'; /** Expects a `reportEvent` of kind 1984 and a `profile` of kind 0 of the person being reported */ async function renderReport(reportEvent: DittoEvent, profile: DittoEvent) { - const { - account_id, - status_ids, - comment, - forward, - category, - } = JSON.parse(reportEvent.content); + // The category is present in both the 'e' and 'p' tag, however, it is possible to report a user without reporting a note, so it's better to get the category from the 'p' tag + const category = reportEvent.tags.find(([name]) => name === 'p')?.[2] as string; + + const status_ids = reportEvent.tags.filter(([name]) => name === 'e').map((tag) => tag[1]) ?? []; + + const reported_profile_pubkey = reportEvent.tags.find(([name]) => name === 'p')?.[1] as string; return { - id: account_id, + id: reportEvent.id, action_taken: false, action_taken_at: null, category, - comment, - forwarded: forward, + comment: reportEvent.content, + forwarded: false, created_at: nostrDate(reportEvent.created_at).toISOString(), status_ids, rules_ids: null, - target_account: profile ? await renderAccount(profile) : await accountFromPubkey(account_id), + target_account: profile ? await renderAccount(profile) : await accountFromPubkey(reported_profile_pubkey), }; } @@ -38,11 +37,8 @@ interface RenderAdminReportOpts { async function renderAdminReport(reportEvent: DittoEvent, opts: RenderAdminReportOpts) { const { viewerPubkey } = opts; - const { - comment, - forward, - category, - } = JSON.parse(reportEvent.content); + // The category is present in both the 'e' and 'p' tag, however, it is possible to report a user without reporting a note, so it's better to get the category from the 'p' tag + const category = reportEvent.tags.find(([name]) => name === 'p')?.[2] as string; const statuses = []; if (reportEvent.reported_notes) { @@ -56,8 +52,8 @@ async function renderAdminReport(reportEvent: DittoEvent, opts: RenderAdminRepor action_taken: false, action_taken_at: null, category, - comment, - forwarded: forward, + comment: reportEvent.content, + forwarded: false, created_at: nostrDate(reportEvent.created_at).toISOString(), account: await renderAdminAccount(reportEvent.author as DittoEvent), target_account: await renderAdminAccount(reportEvent.reported_profile as DittoEvent),