diff --git a/src/app.ts b/src/app.ts index a3f6a43..344c52a 100644 --- a/src/app.ts +++ b/src/app.ts @@ -25,7 +25,7 @@ import { updateCredentialsController, verifyCredentialsController, } from '@/controllers/api/accounts.ts'; -import { adminAccountsController } from '@/controllers/api/admin.ts'; +import { adminAccountAction, adminAccountsController } from '@/controllers/api/admin.ts'; import { appCredentialsController, createAppController } from '@/controllers/api/apps.ts'; import { blocksController } from '@/controllers/api/blocks.ts'; import { bookmarksController } from '@/controllers/api/bookmarks.ts'; @@ -222,6 +222,8 @@ app.post( adminReportResolveController, ); +app.post('/api/v1/admin/accounts/:id{[0-9a-f]{64}}/action', requirePubkey, requireRole('admin'), adminAccountAction); + // Not (yet) implemented. app.get('/api/v1/custom_emojis', emptyArrayController); app.get('/api/v1/filters', emptyArrayController); diff --git a/src/controllers/api/admin.ts b/src/controllers/api/admin.ts index 1542056..97e28b4 100644 --- a/src/controllers/api/admin.ts +++ b/src/controllers/api/admin.ts @@ -5,7 +5,8 @@ import { Conf } from '@/config.ts'; import { booleanParamSchema } from '@/schema.ts'; import { Storages } from '@/storages.ts'; import { renderAdminAccount } from '@/views/mastodon/admin-accounts.ts'; -import { paginated, paginationSchema } from '@/utils/api.ts'; +import { paginated, paginationSchema, parseBody, updateListAdminEvent } from '@/utils/api.ts'; +import { addTag } from '@/tags.ts'; const adminAccountQuerySchema = z.object({ local: booleanParamSchema.optional(), @@ -57,4 +58,39 @@ const adminAccountsController: AppController = async (c) => { return paginated(c, events, accounts); }; -export { adminAccountsController }; +const adminAccountActionSchema = z.object({ + type: z.enum(['none', 'sensitive', 'disable', 'silence', 'suspend']), +}); + +const adminAccountAction: AppController = async (c) => { + const body = await parseBody(c.req.raw); + const result = adminAccountActionSchema.safeParse(body); + const authorId = c.req.param('id'); + const store = c.get('store'); + const { signal } = c.req.raw; + + if (!result.success) { + return c.json({ error: 'This action is not allowed' }, 403); + } + + const { data } = result; + + if (data.type !== 'disable') { + return c.json({ error: 'Record invalid' }, 422); + } + + const [event] = await store.query([{ kinds: [0], authors: [authorId], limit: 1 }], { signal }); + if (!event) { + return c.json({ error: 'Record not found' }, 404); + } + + await updateListAdminEvent( + { kinds: [10000], authors: [Conf.pubkey] }, + (tags) => addTag(tags, ['p', event.pubkey]), + c, + ); + + return c.json({}, 200); +}; + +export { adminAccountAction, adminAccountsController };