mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 03:19:46 +00:00
feat: promote users to admin
This commit is contained in:
parent
5fc874b768
commit
c79867d8ca
2 changed files with 100 additions and 2 deletions
|
|
@ -85,6 +85,7 @@ import {
|
||||||
pleromaAdminTagController,
|
pleromaAdminTagController,
|
||||||
pleromaAdminUnsuggestController,
|
pleromaAdminUnsuggestController,
|
||||||
pleromaAdminUntagController,
|
pleromaAdminUntagController,
|
||||||
|
pleromaPromoteAdminController,
|
||||||
updateConfigController,
|
updateConfigController,
|
||||||
} from '@/controllers/api/pleroma.ts';
|
} from '@/controllers/api/pleroma.ts';
|
||||||
import { preferencesController } from '@/controllers/api/preferences.ts';
|
import { preferencesController } from '@/controllers/api/preferences.ts';
|
||||||
|
|
@ -440,6 +441,11 @@ app.delete('/api/v1/pleroma/statuses/:id{[0-9a-f]{64}}/reactions/:emoji', userMi
|
||||||
app.get('/api/v1/pleroma/admin/config', userMiddleware({ role: 'admin' }), configController);
|
app.get('/api/v1/pleroma/admin/config', userMiddleware({ role: 'admin' }), configController);
|
||||||
app.post('/api/v1/pleroma/admin/config', userMiddleware({ role: 'admin' }), updateConfigController);
|
app.post('/api/v1/pleroma/admin/config', userMiddleware({ role: 'admin' }), updateConfigController);
|
||||||
app.delete('/api/v1/pleroma/admin/statuses/:id', userMiddleware({ role: 'admin' }), pleromaAdminDeleteStatusController);
|
app.delete('/api/v1/pleroma/admin/statuses/:id', userMiddleware({ role: 'admin' }), pleromaAdminDeleteStatusController);
|
||||||
|
app.post(
|
||||||
|
'/api/v1/pleroma/admin/users/permission_group/admin',
|
||||||
|
userMiddleware({ role: 'admin' }),
|
||||||
|
pleromaPromoteAdminController,
|
||||||
|
);
|
||||||
|
|
||||||
app.get('/api/v1/admin/ditto/relays', userMiddleware({ role: 'admin' }), adminRelaysController);
|
app.get('/api/v1/admin/ditto/relays', userMiddleware({ role: 'admin' }), adminRelaysController);
|
||||||
app.put('/api/v1/admin/ditto/relays', userMiddleware({ role: 'admin' }), adminSetRelaysController);
|
app.put('/api/v1/admin/ditto/relays', userMiddleware({ role: 'admin' }), adminSetRelaysController);
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,14 @@
|
||||||
|
import { nip19 } from 'nostr-tools';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { type AppController } from '@/app.ts';
|
import { type AppController } from '@/app.ts';
|
||||||
import { configSchema, elixirTupleSchema } from '@/schemas/pleroma-api.ts';
|
import { createAdminEvent, parseBody, updateAdminEvent, updateUser } from '@/utils/api.ts';
|
||||||
import { createAdminEvent, updateAdminEvent, updateUser } from '@/utils/api.ts';
|
import { nostrNow } from '@/utils.ts';
|
||||||
import { lookupPubkey } from '@/utils/lookup.ts';
|
import { lookupPubkey } from '@/utils/lookup.ts';
|
||||||
import { getPleromaConfigs } from '@/utils/pleroma.ts';
|
import { getPleromaConfigs } from '@/utils/pleroma.ts';
|
||||||
|
import { renderAccount } from '@/views/mastodon/accounts.ts';
|
||||||
|
import { configSchema, elixirTupleSchema } from '@/schemas/pleroma-api.ts';
|
||||||
|
import { hydrateEvents } from '@/storages/hydrate.ts';
|
||||||
|
|
||||||
const frontendConfigController: AppController = async (c) => {
|
const frontendConfigController: AppController = async (c) => {
|
||||||
const configDB = await getPleromaConfigs(c.var);
|
const configDB = await getPleromaConfigs(c.var);
|
||||||
|
|
@ -62,6 +66,93 @@ const pleromaAdminTagSchema = z.object({
|
||||||
tags: z.string().array(),
|
tags: z.string().array(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const pleromaPromoteAdminSchema = z.object({
|
||||||
|
nicknames: z.string().transform((value, ctx) => {
|
||||||
|
try {
|
||||||
|
const { type, data } = nip19.decode(value);
|
||||||
|
if (type === 'npub') {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.addIssue({
|
||||||
|
code: z.ZodIssueCode.custom,
|
||||||
|
message: 'Not a valid nip 19 npub',
|
||||||
|
});
|
||||||
|
|
||||||
|
return z.NEVER;
|
||||||
|
} catch {
|
||||||
|
ctx.addIssue({
|
||||||
|
code: z.ZodIssueCode.custom,
|
||||||
|
message: 'Not a valid nip 19 npub',
|
||||||
|
});
|
||||||
|
|
||||||
|
return z.NEVER;
|
||||||
|
}
|
||||||
|
}).array().min(1),
|
||||||
|
});
|
||||||
|
|
||||||
|
const pleromaPromoteAdminController: AppController = async (c) => {
|
||||||
|
const { conf, relay, signal } = c.var;
|
||||||
|
const body = await parseBody(c.req.raw);
|
||||||
|
const result = pleromaPromoteAdminSchema.safeParse(body);
|
||||||
|
|
||||||
|
if (!result.success) {
|
||||||
|
return c.json({ error: 'Bad request', schema: result.error }, 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data } = result;
|
||||||
|
const { nicknames: authors } = data;
|
||||||
|
|
||||||
|
const events = await relay.query([{ kinds: [0], authors }], { signal });
|
||||||
|
|
||||||
|
if (events.length !== authors.length) {
|
||||||
|
return c.json({ error: 'User profile is missing in the database' }, 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
events.forEach(async (event) => {
|
||||||
|
const [existing] = await relay.query([{
|
||||||
|
kinds: [30382],
|
||||||
|
authors: [await conf.signer.getPublicKey()],
|
||||||
|
'#d': [event.pubkey],
|
||||||
|
limit: 1,
|
||||||
|
}]);
|
||||||
|
|
||||||
|
const prevTags = (existing?.tags ?? []).filter(([name, value]) => {
|
||||||
|
if (name === 'd') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (name === 'n' && value === 'admin') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
const tags: string[][] = [
|
||||||
|
['d', event.pubkey],
|
||||||
|
['n', 'admin'],
|
||||||
|
];
|
||||||
|
|
||||||
|
tags.push(...prevTags);
|
||||||
|
|
||||||
|
const promotion = await conf.signer.signEvent({
|
||||||
|
kind: 30382,
|
||||||
|
tags,
|
||||||
|
content: '',
|
||||||
|
created_at: nostrNow(),
|
||||||
|
});
|
||||||
|
|
||||||
|
await relay.event(promotion);
|
||||||
|
});
|
||||||
|
|
||||||
|
await hydrateEvents({ ...c.var, events });
|
||||||
|
|
||||||
|
const accounts = events.map((event) => {
|
||||||
|
return renderAccount(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
return c.json(accounts, 200);
|
||||||
|
};
|
||||||
|
|
||||||
const pleromaAdminTagController: AppController = async (c) => {
|
const pleromaAdminTagController: AppController = async (c) => {
|
||||||
const { conf } = c.var;
|
const { conf } = c.var;
|
||||||
const params = pleromaAdminTagSchema.parse(await c.req.json());
|
const params = pleromaAdminTagSchema.parse(await c.req.json());
|
||||||
|
|
@ -154,5 +245,6 @@ export {
|
||||||
pleromaAdminTagController,
|
pleromaAdminTagController,
|
||||||
pleromaAdminUnsuggestController,
|
pleromaAdminUnsuggestController,
|
||||||
pleromaAdminUntagController,
|
pleromaAdminUntagController,
|
||||||
|
pleromaPromoteAdminController,
|
||||||
updateConfigController,
|
updateConfigController,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue