Merge remote-tracking branch 'origin/main' into nip05-request

This commit is contained in:
Alex Gleason
2024-06-08 15:01:01 -05:00
18 changed files with 363 additions and 200 deletions

View File

@@ -5,8 +5,7 @@ import { type AppController } from '@/app.ts';
import { Conf } from '@/config.ts';
import { booleanParamSchema } from '@/schema.ts';
import { Storages } from '@/storages.ts';
import { paginated, paginationSchema, parseBody, updateListAdminEvent } from '@/utils/api.ts';
import { addTag } from '@/utils/tags.ts';
import { paginated, paginationSchema, parseBody, updateUser } from '@/utils/api.ts';
import { renderAdminAccount, renderAdminAccountFromPubkey } from '@/views/mastodon/admin-accounts.ts';
import { hydrateEvents } from '@/storages/hydrate.ts';
@@ -91,7 +90,7 @@ const adminAccountActionSchema = z.object({
type: z.enum(['none', 'sensitive', 'disable', 'silence', 'suspend']),
});
const adminAccountAction: AppController = async (c) => {
const adminActionController: AppController = async (c) => {
const body = await parseBody(c.req.raw);
const result = adminAccountActionSchema.safeParse(body);
const authorId = c.req.param('id');
@@ -102,17 +101,24 @@ const adminAccountAction: AppController = async (c) => {
const { data } = result;
if (data.type !== 'disable') {
return c.json({ error: 'Record invalid' }, 422);
const n: Record<string, boolean> = {};
if (data.type === 'sensitive') {
n.sensitive = true;
}
if (data.type === 'disable') {
n.disable = true;
}
if (data.type === 'silence') {
n.silence = true;
}
if (data.type === 'suspend') {
n.suspend = true;
}
await updateListAdminEvent(
{ kinds: [10000], authors: [Conf.pubkey], limit: 1 },
(tags) => addTag(tags, ['p', authorId]),
c,
);
await updateUser(authorId, n, c);
return c.json({}, 200);
};
export { adminAccountAction, adminAccountsController };
export { adminAccountsController, adminActionController };

View File

@@ -6,7 +6,8 @@ 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 } from '@/utils/api.ts';
import { createAdminEvent, updateAdminEvent, updateUser } from '@/utils/api.ts';
import { lookupPubkey } from '@/utils/lookup.ts';
const frontendConfigController: AppController = async (c) => {
const store = await Storages.db();
@@ -87,4 +88,100 @@ async function getConfigs(store: NStore, signal: AbortSignal): Promise<PleromaCo
}
}
export { configController, frontendConfigController, pleromaAdminDeleteStatusController, updateConfigController };
const pleromaAdminTagSchema = z.object({
nicknames: z.string().array(),
tags: z.string().array(),
});
const pleromaAdminTagController: AppController = async (c) => {
const params = pleromaAdminTagSchema.parse(await c.req.json());
for (const nickname of params.nicknames) {
const pubkey = await lookupPubkey(nickname);
if (!pubkey) continue;
await updateAdminEvent(
{ kinds: [30382], authors: [Conf.pubkey], '#d': [pubkey], limit: 1 },
(prev) => {
const tags = prev?.tags ?? [['d', pubkey]];
for (const tag of params.tags) {
const existing = prev?.tags.some(([name, value]) => name === 't' && value === tag);
if (!existing) {
tags.push(['t', tag]);
}
}
return {
kind: 30382,
content: prev?.content ?? '',
tags,
};
},
c,
);
}
return new Response(null, { status: 204 });
};
const pleromaAdminUntagController: AppController = async (c) => {
const params = pleromaAdminTagSchema.parse(await c.req.json());
for (const nickname of params.nicknames) {
const pubkey = await lookupPubkey(nickname);
if (!pubkey) continue;
await updateAdminEvent(
{ kinds: [30382], authors: [Conf.pubkey], '#d': [pubkey], limit: 1 },
(prev) => ({
kind: 30382,
content: prev?.content ?? '',
tags: (prev?.tags ?? [['d', pubkey]])
.filter(([name, value]) => !(name === 't' && params.tags.includes(value))),
}),
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,
};

View File

@@ -31,7 +31,7 @@ async function renderV2Suggestions(c: AppContext, params: PaginatedListParams, s
const pubkey = await signer?.getPublicKey();
const filters: NostrFilter[] = [
{ kinds: [3], authors: [Conf.pubkey], limit: 1 },
{ kinds: [30382], authors: [Conf.pubkey], '#n': ['suggest'], limit },
{ kinds: [1985], '#L': ['pub.ditto.trends'], '#l': [`#p`], authors: [Conf.pubkey], limit: 1 },
];
@@ -42,8 +42,8 @@ async function renderV2Suggestions(c: AppContext, params: PaginatedListParams, s
const events = await store.query(filters, { signal });
const [suggestedEvent, followsEvent, mutesEvent, trendingEvent] = [
events.find((event) => matchFilter({ kinds: [3], authors: [Conf.pubkey] }, event)),
const [userEvents, followsEvent, mutesEvent, trendingEvent] = [
events.filter((event) => matchFilter({ kinds: [30382], authors: [Conf.pubkey], '#n': ['suggest'] }, event)),
pubkey ? events.find((event) => matchFilter({ kinds: [3], authors: [pubkey] }, event)) : undefined,
pubkey ? events.find((event) => matchFilter({ kinds: [10000], authors: [pubkey] }, event)) : undefined,
events.find((event) =>
@@ -51,8 +51,13 @@ async function renderV2Suggestions(c: AppContext, params: PaginatedListParams, s
),
];
const [suggested, trending, follows, mutes] = [
getTagSet(suggestedEvent?.tags ?? [], 'p'),
const suggested = new Set(
userEvents
.map((event) => event.tags.find(([name]) => name === 'd')?.[1])
.filter((pubkey): pubkey is string => !!pubkey),
);
const [trending, follows, mutes] = [
getTagSet(trendingEvent?.tags ?? [], 'p'),
getTagSet(followsEvent?.tags ?? [], 'p'),
getTagSet(mutesEvent?.tags ?? [], 'p'),