Merge branch 'admin-report-mark-as-resolved' into 'main'

Implement Mastodon API - mark a report as resolved

Closes #112

See merge request soapbox-pub/ditto!230
This commit is contained in:
Alex Gleason 2024-05-08 13:17:28 +00:00
commit fd05e4c5c4
3 changed files with 45 additions and 5 deletions

View File

@ -44,7 +44,12 @@ import {
} from '@/controllers/api/pleroma.ts'; } from '@/controllers/api/pleroma.ts';
import { preferencesController } from '@/controllers/api/preferences.ts'; import { preferencesController } from '@/controllers/api/preferences.ts';
import { relayController } from '@/controllers/nostr/relay.ts'; import { relayController } from '@/controllers/nostr/relay.ts';
import { adminReportController, adminReportsController, reportsController } from '@/controllers/api/reports.ts'; import {
adminReportController,
adminReportResolveController,
adminReportsController,
reportsController,
} from '@/controllers/api/reports.ts';
import { searchController } from '@/controllers/api/search.ts'; import { searchController } from '@/controllers/api/search.ts';
import { import {
bookmarkController, bookmarkController,
@ -209,7 +214,13 @@ app.put('/api/v1/admin/ditto/relays', requireRole('admin'), adminSetRelaysContro
app.post('/api/v1/reports', requirePubkey, reportsController); app.post('/api/v1/reports', requirePubkey, reportsController);
app.get('/api/v1/admin/reports', requirePubkey, requireRole('admin'), adminReportsController); app.get('/api/v1/admin/reports', requirePubkey, requireRole('admin'), adminReportsController);
app.get('/api/v1/admin/reports/:id', requirePubkey, requireRole('admin'), adminReportController); app.get('/api/v1/admin/reports/:id{[0-9a-f]{64}}', requirePubkey, requireRole('admin'), adminReportController);
app.post(
'/api/v1/admin/reports/:id{[0-9a-f]{64}}/resolve',
requirePubkey,
requireRole('admin'),
adminReportResolveController,
);
// Not (yet) implemented. // Not (yet) implemented.
app.get('/api/v1/custom_emojis', emptyArrayController); app.get('/api/v1/custom_emojis', emptyArrayController);

View File

@ -88,4 +88,32 @@ const adminReportController: AppController = async (c) => {
return c.json(await renderAdminReport(event, { viewerPubkey: pubkey })); return c.json(await renderAdminReport(event, { viewerPubkey: pubkey }));
}; };
export { adminReportController, adminReportsController, reportsController }; /** https://docs.joinmastodon.org/methods/admin/reports/#resolve */
const adminReportResolveController: AppController = async (c) => {
const eventId = c.req.param('id');
const { signal } = c.req.raw;
const store = c.get('store');
const pubkey = c.get('pubkey');
const [event] = await store.query([{
kinds: [1984],
ids: [eventId],
limit: 1,
}], { signal });
if (!event) {
return c.json({ error: 'This action is not allowed' }, 403);
}
await hydrateEvents({ events: [event], storage: store, signal });
await createEvent({
kind: 5,
tags: [['e', event.id]],
content: 'Report closed.',
}, c);
return c.json(await renderAdminReport(event, { viewerPubkey: pubkey, action_taken: true }));
};
export { adminReportController, adminReportResolveController, adminReportsController, reportsController };

View File

@ -30,13 +30,14 @@ async function renderReport(reportEvent: DittoEvent, profile: DittoEvent) {
interface RenderAdminReportOpts { interface RenderAdminReportOpts {
viewerPubkey?: string; viewerPubkey?: string;
action_taken?: boolean;
} }
/** Admin-level information about a filed report. /** Admin-level information about a filed report.
* Expects an event of kind 1984 fully hydrated. * Expects an event of kind 1984 fully hydrated.
* https://docs.joinmastodon.org/entities/Admin_Report */ * https://docs.joinmastodon.org/entities/Admin_Report */
async function renderAdminReport(reportEvent: DittoEvent, opts: RenderAdminReportOpts) { async function renderAdminReport(reportEvent: DittoEvent, opts: RenderAdminReportOpts) {
const { viewerPubkey } = opts; const { viewerPubkey, action_taken = false } = opts;
// 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 // 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]; const category = reportEvent.tags.find(([name]) => name === 'p')?.[2];
@ -50,7 +51,7 @@ async function renderAdminReport(reportEvent: DittoEvent, opts: RenderAdminRepor
return { return {
id: reportEvent.id, id: reportEvent.id,
action_taken: false, action_taken,
action_taken_at: null, action_taken_at: null,
category, category,
comment: reportEvent.content, comment: reportEvent.content,