Create AdminStore to filter out banned users
This commit is contained in:
parent
a30cdec79b
commit
e5fadafc7a
|
@ -1,14 +1,11 @@
|
|||
import { NKinds, NostrEvent, NSchema as n } from '@nostrify/nostrify';
|
||||
import { PipePolicy } from '@nostrify/nostrify/policies';
|
||||
import Debug from '@soapbox/stickynotes/debug';
|
||||
import { sql } from 'kysely';
|
||||
import { LRUCache } from 'lru-cache';
|
||||
|
||||
import { Conf } from '@/config.ts';
|
||||
import { DittoDB } from '@/db/DittoDB.ts';
|
||||
import { deleteAttachedMedia } from '@/db/unattached-media.ts';
|
||||
import { DittoEvent } from '@/interfaces/DittoEvent.ts';
|
||||
import { MuteListPolicy } from '@/policies/MuteListPolicy.ts';
|
||||
import { RelayError } from '@/RelayError.ts';
|
||||
import { hydrateEvents } from '@/storages/hydrate.ts';
|
||||
import { Storages } from '@/storages.ts';
|
||||
|
@ -44,6 +41,15 @@ async function handleEvent(event: DittoEvent, signal: AbortSignal): Promise<void
|
|||
|
||||
await hydrateEvent(event, signal);
|
||||
|
||||
const n = getTagSet(event.user?.tags ?? [], 'n');
|
||||
|
||||
if (n.has('disable')) {
|
||||
throw new RelayError('blocked', 'user is disabled');
|
||||
}
|
||||
if (n.has('suspend')) {
|
||||
throw new RelayError('blocked', 'user is suspended');
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
storeEvent(event, signal),
|
||||
parseMetadata(event, signal),
|
||||
|
@ -55,13 +61,8 @@ async function handleEvent(event: DittoEvent, signal: AbortSignal): Promise<void
|
|||
async function policyFilter(event: NostrEvent): Promise<void> {
|
||||
const debug = Debug('ditto:policy');
|
||||
|
||||
const policy = new PipePolicy([
|
||||
new MuteListPolicy(Conf.pubkey, await Storages.admin()),
|
||||
policyWorker,
|
||||
]);
|
||||
|
||||
try {
|
||||
const result = await policy.call(event);
|
||||
const result = await policyWorker.call(event);
|
||||
debug(JSON.stringify(result));
|
||||
RelayError.assert(result);
|
||||
} catch (e) {
|
||||
|
|
|
@ -3,15 +3,15 @@ import { RelayPoolWorker } from 'nostr-relaypool';
|
|||
|
||||
import { Conf } from '@/config.ts';
|
||||
import { DittoDB } from '@/db/DittoDB.ts';
|
||||
import { AdminStore } from '@/storages/AdminStore.ts';
|
||||
import { EventsDB } from '@/storages/EventsDB.ts';
|
||||
import { PoolStore } from '@/storages/pool-store.ts';
|
||||
import { SearchStore } from '@/storages/search-store.ts';
|
||||
import { InternalRelay } from '@/storages/InternalRelay.ts';
|
||||
import { UserStore } from '@/storages/UserStore.ts';
|
||||
|
||||
export class Storages {
|
||||
private static _db: Promise<EventsDB> | undefined;
|
||||
private static _admin: Promise<UserStore> | undefined;
|
||||
private static _admin: Promise<AdminStore> | undefined;
|
||||
private static _client: Promise<PoolStore> | undefined;
|
||||
private static _pubsub: Promise<InternalRelay> | undefined;
|
||||
private static _search: Promise<SearchStore> | undefined;
|
||||
|
@ -28,9 +28,9 @@ export class Storages {
|
|||
}
|
||||
|
||||
/** Admin user storage. */
|
||||
public static async admin(): Promise<UserStore> {
|
||||
public static async admin(): Promise<AdminStore> {
|
||||
if (!this._admin) {
|
||||
this._admin = Promise.resolve(new UserStore(Conf.pubkey, await this.db()));
|
||||
this._admin = Promise.resolve(new AdminStore(await this.db()));
|
||||
}
|
||||
return this._admin;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
import { NostrEvent, NostrFilter, NStore } from '@nostrify/nostrify';
|
||||
|
||||
import { Conf } from '@/config.ts';
|
||||
import { DittoEvent } from '@/interfaces/DittoEvent.ts';
|
||||
import { getTagSet } from '@/utils/tags.ts';
|
||||
|
||||
/** A store that prevents banned users from being displayed. */
|
||||
export class AdminStore implements NStore {
|
||||
constructor(private store: NStore) {}
|
||||
|
||||
async event(event: NostrEvent, opts?: { signal?: AbortSignal }): Promise<void> {
|
||||
return await this.store.event(event, opts);
|
||||
}
|
||||
|
||||
async query(filters: NostrFilter[], opts: { signal?: AbortSignal; limit?: number } = {}): Promise<DittoEvent[]> {
|
||||
const events = await this.store.query(filters, opts);
|
||||
|
||||
const users = await this.store.query([{
|
||||
kinds: [30382],
|
||||
authors: [Conf.pubkey],
|
||||
'#d': events.map((event) => event.pubkey),
|
||||
limit: 1,
|
||||
}]);
|
||||
|
||||
return events.filter((event) => {
|
||||
const user = users.find(
|
||||
({ kind, pubkey, tags }) =>
|
||||
kind === 30382 && pubkey === Conf.pubkey && tags.find(([name]) => name === 'd')?.[1] === event.pubkey,
|
||||
);
|
||||
|
||||
const n = getTagSet(user?.tags ?? [], 'n');
|
||||
|
||||
if (n.has('disable') || n.has('suspend')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue