diff --git a/src/app.ts b/src/app.ts index 2657a28..f9ea03a 100644 --- a/src/app.ts +++ b/src/app.ts @@ -42,7 +42,9 @@ import { configController, frontendConfigController, pleromaAdminDeleteStatusController, + pleromaAdminSuggestController, pleromaAdminTagController, + pleromaAdminUnsuggestController, pleromaAdminUntagController, updateConfigController, } from '@/controllers/api/pleroma.ts'; @@ -257,6 +259,8 @@ app.post('/api/v1/admin/accounts/:id{[0-9a-f]{64}}/action', requireSigner, requi app.put('/api/v1/pleroma/admin/users/tag', requireRole('admin'), pleromaAdminTagController); app.delete('/api/v1/pleroma/admin/users/tag', requireRole('admin'), pleromaAdminUntagController); +app.patch('/api/v1/pleroma/admin/users/suggest', requireRole('admin'), pleromaAdminSuggestController); +app.patch('/api/v1/pleroma/admin/users/unsuggest', requireRole('admin'), pleromaAdminUnsuggestController); // Not (yet) implemented. app.get('/api/v1/custom_emojis', emptyArrayController); diff --git a/src/controllers/api/pleroma.ts b/src/controllers/api/pleroma.ts index 57b77cf..f428ce9 100644 --- a/src/controllers/api/pleroma.ts +++ b/src/controllers/api/pleroma.ts @@ -6,7 +6,7 @@ import { Conf } from '@/config.ts'; import { configSchema, elixirTupleSchema, type PleromaConfig } from '@/schemas/pleroma-api.ts'; import { AdminSigner } from '@/signers/AdminSigner.ts'; import { Storages } from '@/storages.ts'; -import { createAdminEvent, updateAdminEvent } from '@/utils/api.ts'; +import { createAdminEvent, updateAdminEvent, updateUser } from '@/utils/api.ts'; import { lookupPubkey } from '@/utils/lookup.ts'; const frontendConfigController: AppController = async (c) => { @@ -88,13 +88,13 @@ async function getConfigs(store: NStore, signal: AbortSignal): Promise { - const params = pleromaAdminTagsSchema.parse(await c.req.json()); + const params = pleromaAdminTagSchema.parse(await c.req.json()); for (const nickname of params.nicknames) { const pubkey = await lookupPubkey(nickname); @@ -126,7 +126,7 @@ const pleromaAdminTagController: AppController = async (c) => { }; const pleromaAdminUntagController: AppController = async (c) => { - const params = pleromaAdminTagsSchema.parse(await c.req.json()); + const params = pleromaAdminTagSchema.parse(await c.req.json()); for (const nickname of params.nicknames) { const pubkey = await lookupPubkey(nickname); @@ -147,11 +147,41 @@ const pleromaAdminUntagController: AppController = async (c) => { return new Response(null, { status: 204 }); }; +const pleromaAdminSuggestSchema = z.object({ + nicknames: z.string().array(), +}); + +const pleromaAdminSuggestController: AppController = async (c) => { + const { nicknames } = pleromaAdminSuggestSchema.parse(await c.req.json()); + + for (const nickname of nicknames) { + const pubkey = await lookupPubkey(nickname); + if (!pubkey) continue; + await updateUser(pubkey, { suggest: true }, c); + } + + return new Response(null, { status: 204 }); +}; + +const pleromaAdminUnsuggestController: AppController = async (c) => { + const { nicknames } = pleromaAdminSuggestSchema.parse(await c.req.json()); + + for (const nickname of nicknames) { + const pubkey = await lookupPubkey(nickname); + if (!pubkey) continue; + await updateUser(pubkey, { suggest: false }, c); + } + + return new Response(null, { status: 204 }); +}; + export { configController, frontendConfigController, pleromaAdminDeleteStatusController, + pleromaAdminSuggestController, pleromaAdminTagController, + pleromaAdminUnsuggestController, pleromaAdminUntagController, updateConfigController, }; diff --git a/src/views/mastodon/accounts.ts b/src/views/mastodon/accounts.ts index 3974c3c..9f2f052 100644 --- a/src/views/mastodon/accounts.ts +++ b/src/views/mastodon/accounts.ts @@ -34,7 +34,7 @@ async function renderAccount( const npub = nip19.npubEncode(pubkey); const parsed05 = await parseAndVerifyNip05(nip05, pubkey); - const roles = getTagSet(event.user?.tags ?? [], 'n'); + const names = getTagSet(event.user?.tags ?? [], 'n'); return { id: pubkey, @@ -77,8 +77,9 @@ async function renderAccount( accepts_zaps: Boolean(getLnurl({ lud06, lud16 })), }, pleroma: { - is_admin: roles.has('admin'), - is_moderator: roles.has('admin') || roles.has('moderator'), + is_admin: names.has('admin'), + is_moderator: names.has('admin') || names.has('moderator'), + is_suggested: names.has('suggest'), is_local: parsed05?.domain === Conf.url.host, settings_store: undefined as unknown, tags: [...getTagSet(event.user?.tags ?? [], 't')],