From 5f5d0bc324af830475b69c331bf8870a99f431a1 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Thu, 27 Feb 2025 16:35:06 -0600 Subject: [PATCH 1/3] Remove `@/config.ts` import from utils/stats.ts --- packages/ditto/app.ts | 2 +- packages/ditto/storages/DittoPgStore.ts | 19 ++++--- packages/ditto/test.ts | 2 +- packages/ditto/utils/stats.test.ts | 23 ++++---- packages/ditto/utils/stats.ts | 53 +++++++++++++------ packages/ditto/workers/policy.worker.ts | 13 ++++- .../translators/LibreTranslateTranslator.ts | 2 - scripts/admin-event.ts | 2 +- scripts/admin-role.ts | 2 +- scripts/db-export.ts | 2 +- scripts/db-import.ts | 2 +- scripts/db-policy.ts | 2 +- scripts/db-populate-nip05.ts | 2 +- scripts/db-populate-search.ts | 2 +- scripts/nostr-pull.ts | 2 +- scripts/setup-kind0.ts | 2 +- scripts/stats-recompute.ts | 2 +- scripts/trends.ts | 2 +- 18 files changed, 86 insertions(+), 50 deletions(-) diff --git a/packages/ditto/app.ts b/packages/ditto/app.ts index 8e818552..5f3a12e4 100644 --- a/packages/ditto/app.ts +++ b/packages/ditto/app.ts @@ -194,7 +194,7 @@ await db.migrate(); const pgstore = new DittoPgStore({ db, - pubkey: await conf.signer.getPublicKey(), + conf, timeout: conf.db.timeouts.default, notify: conf.notifyEnabled, }); diff --git a/packages/ditto/storages/DittoPgStore.ts b/packages/ditto/storages/DittoPgStore.ts index ea3e864c..34625fbc 100644 --- a/packages/ditto/storages/DittoPgStore.ts +++ b/packages/ditto/storages/DittoPgStore.ts @@ -1,5 +1,6 @@ // deno-lint-ignore-file require-await +import { type DittoConf } from '@ditto/conf'; import { type DittoDB, type DittoTables } from '@ditto/db'; import { detectLanguage } from '@ditto/lang'; import { NPostgres, NPostgresSchema } from '@nostrify/db'; @@ -52,8 +53,8 @@ interface TagConditionOpts { interface DittoPgStoreOpts { /** Kysely instance to use. */ db: DittoDB; - /** Pubkey of the admin account. */ - pubkey: string; + /** Ditto configuration. */ + conf: DittoConf; /** Timeout in milliseconds for database queries. */ timeout?: number; /** Whether the event returned should be a Nostr event or a Ditto event. Defaults to false. */ @@ -171,7 +172,7 @@ export class DittoPgStore extends NPostgres { ): Promise { try { await super.transaction(async (relay, kysely) => { - await updateStats({ event, relay, kysely: kysely as unknown as Kysely }); + await updateStats({ conf: this.opts.conf, relay, kysely: kysely as unknown as Kysely, event }); await relay.event(event, opts); }); } catch (e) { @@ -229,8 +230,11 @@ export class DittoPgStore extends NPostgres { /** Check if an event has been deleted by the admin. */ private async isDeletedAdmin(event: NostrEvent): Promise { + const { conf } = this.opts; + const adminPubkey = await conf.signer.getPublicKey(); + const filters: NostrFilter[] = [ - { kinds: [5], authors: [this.opts.pubkey], '#e': [event.id], limit: 1 }, + { kinds: [5], authors: [adminPubkey], '#e': [event.id], limit: 1 }, ]; if (NKinds.replaceable(event.kind) || NKinds.parameterizedReplaceable(event.kind)) { @@ -238,7 +242,7 @@ export class DittoPgStore extends NPostgres { filters.push({ kinds: [5], - authors: [this.opts.pubkey], + authors: [adminPubkey], '#a': [`${event.kind}:${event.pubkey}:${d}`], since: event.created_at, limit: 1, @@ -251,7 +255,10 @@ export class DittoPgStore extends NPostgres { /** The DITTO_NSEC can delete any event from the database. NDatabase already handles user deletions. */ private async deleteEventsAdmin(event: NostrEvent): Promise { - if (event.kind === 5 && event.pubkey === this.opts.pubkey) { + const { conf } = this.opts; + const adminPubkey = await conf.signer.getPublicKey(); + + if (event.kind === 5 && event.pubkey === adminPubkey) { const ids = new Set(event.tags.filter(([name]) => name === 'e').map(([_name, value]) => value)); const addrs = new Set(event.tags.filter(([name]) => name === 'a').map(([_name, value]) => value)); diff --git a/packages/ditto/test.ts b/packages/ditto/test.ts index d2ea5ec7..31b31e37 100644 --- a/packages/ditto/test.ts +++ b/packages/ditto/test.ts @@ -19,8 +19,8 @@ export async function createTestDB(opts?: { pure?: boolean }) { const store = new DittoPgStore({ db, + conf, timeout: conf.db.timeouts.default, - pubkey: await conf.signer.getPublicKey(), pure: opts?.pure ?? false, notify: true, }); diff --git a/packages/ditto/utils/stats.test.ts b/packages/ditto/utils/stats.test.ts index 043e6f13..2ebcab94 100644 --- a/packages/ditto/utils/stats.test.ts +++ b/packages/ditto/utils/stats.test.ts @@ -23,7 +23,7 @@ Deno.test('updateStats with kind 1 increments notes count', async () => { Deno.test('updateStats with kind 1 increments replies count', async () => { await using test = await setupTest(); - const { relay, kysely } = test; + const { kysely, relay } = test; const sk = generateSecretKey(); @@ -42,7 +42,7 @@ Deno.test('updateStats with kind 1 increments replies count', async () => { Deno.test('updateStats with kind 5 decrements notes count', async () => { await using test = await setupTest(); - const { relay, kysely } = test; + const { kysely, relay } = test; const sk = generateSecretKey(); const pubkey = getPublicKey(sk); @@ -74,7 +74,7 @@ Deno.test('updateStats with kind 3 increments followers count', async () => { Deno.test('updateStats with kind 3 decrements followers count', async () => { await using test = await setupTest(); - const { relay, kysely } = test; + const { kysely, relay } = test; const sk = generateSecretKey(); const follow = genEvent({ kind: 3, tags: [['p', 'alex']], created_at: 0 }, sk); @@ -101,7 +101,7 @@ Deno.test('getFollowDiff returns added and removed followers', () => { Deno.test('updateStats with kind 6 increments reposts count', async () => { await using test = await setupTest(); - const { relay, kysely } = test; + const { kysely, relay } = test; const note = genEvent({ kind: 1 }); await updateStats({ ...test, event: note }); @@ -118,7 +118,7 @@ Deno.test('updateStats with kind 6 increments reposts count', async () => { Deno.test('updateStats with kind 5 decrements reposts count', async () => { await using test = await setupTest(); - const { relay, kysely } = test; + const { kysely, relay } = test; const note = genEvent({ kind: 1 }); await updateStats({ ...test, event: note }); @@ -138,7 +138,7 @@ Deno.test('updateStats with kind 5 decrements reposts count', async () => { Deno.test('updateStats with kind 7 increments reactions count', async () => { await using test = await setupTest(); - const { relay, kysely } = test; + const { kysely, relay } = test; const note = genEvent({ kind: 1 }); await updateStats({ ...test, event: note }); @@ -155,7 +155,7 @@ Deno.test('updateStats with kind 7 increments reactions count', async () => { Deno.test('updateStats with kind 5 decrements reactions count', async () => { await using test = await setupTest(); - const { relay, kysely } = test; + const { kysely, relay } = test; const note = genEvent({ kind: 1 }); await updateStats({ ...test, event: note }); @@ -175,7 +175,7 @@ Deno.test('updateStats with kind 5 decrements reactions count', async () => { Deno.test('countAuthorStats counts author stats from the database', async () => { await using test = await setupTest(); - const { relay } = test; + const { kysely, relay } = test; const sk = generateSecretKey(); const pubkey = getPublicKey(sk); @@ -184,7 +184,7 @@ Deno.test('countAuthorStats counts author stats from the database', async () => await relay.event(genEvent({ kind: 1, content: 'yolo' }, sk)); await relay.event(genEvent({ kind: 3, tags: [['p', pubkey]] })); - await test.kysely.insertInto('author_stats').values({ + await kysely.insertInto('author_stats').values({ pubkey, search: 'Yolo Lolo', notes_count: 0, @@ -193,7 +193,7 @@ Deno.test('countAuthorStats counts author stats from the database', async () => }).onConflict((oc) => oc.column('pubkey').doUpdateSet({ 'search': 'baka' })) .execute(); - const stats = await countAuthorStats({ ...test, pubkey }); + const stats = await countAuthorStats({ ...test, kysely, pubkey }); assertEquals(stats!.notes_count, 2); assertEquals(stats!.followers_count, 1); @@ -206,9 +206,10 @@ async function setupTest() { await db.migrate(); const { kysely } = db; - const relay = new NPostgres(kysely); + const relay = new NPostgres(db.kysely); return { + conf, relay, kysely, [Symbol.asyncDispose]: async () => { diff --git a/packages/ditto/utils/stats.ts b/packages/ditto/utils/stats.ts index 448ba241..922d5dca 100644 --- a/packages/ditto/utils/stats.ts +++ b/packages/ditto/utils/stats.ts @@ -4,40 +4,46 @@ import { Insertable, Kysely, UpdateObject } from 'kysely'; import { SetRequired } from 'type-fest'; import { z } from 'zod'; -import { Conf } from '@/config.ts'; import { findQuoteTag, findReplyTag, getTagSet } from '@/utils/tags.ts'; +import type { DittoConf } from '@ditto/conf'; + interface UpdateStatsOpts { - kysely: Kysely; + conf: DittoConf; relay: NStore; + kysely: Kysely; event: NostrEvent; x?: 1 | -1; } /** Handle one event at a time and update relevant stats for it. */ // deno-lint-ignore require-await -export async function updateStats({ event, kysely, relay, x = 1 }: UpdateStatsOpts): Promise { +export async function updateStats(opts: UpdateStatsOpts): Promise { + const { event } = opts; + switch (event.kind) { case 1: case 20: case 1111: case 30023: - return handleEvent1(kysely, event, x); + return handleEvent1(opts); case 3: - return handleEvent3(kysely, event, x, relay); + return handleEvent3(opts); case 5: - return handleEvent5(kysely, event, -1, relay); + return handleEvent5(opts); case 6: - return handleEvent6(kysely, event, x); + return handleEvent6(opts); case 7: - return handleEvent7(kysely, event, x); + return handleEvent7(opts); case 9735: - return handleEvent9735(kysely, event); + return handleEvent9735(opts); } } /** Update stats for kind 1 event. */ -async function handleEvent1(kysely: Kysely, event: NostrEvent, x: number): Promise { +async function handleEvent1(opts: UpdateStatsOpts): Promise { + const { conf, kysely, event, x = 1 } = opts; + await updateAuthorStats(kysely, event.pubkey, (prev) => { const now = event.created_at; @@ -47,7 +53,7 @@ async function handleEvent1(kysely: Kysely, event: NostrEvent, x: n if (start && end) { // Streak exists. if (now <= end) { // Streak cannot go backwards in time. Skip it. - } else if (now - end > Conf.streakWindow) { + } else if (now - end > conf.streakWindow) { // Streak is broken. Start a new streak. start = now; end = now; @@ -88,7 +94,9 @@ async function handleEvent1(kysely: Kysely, event: NostrEvent, x: n } /** Update stats for kind 3 event. */ -async function handleEvent3(kysely: Kysely, event: NostrEvent, x: number, relay: NStore): Promise { +async function handleEvent3(opts: UpdateStatsOpts): Promise { + const { relay, kysely, event, x = 1 } = opts; + const following = getTagSet(event.tags, 'p'); await updateAuthorStats(kysely, event.pubkey, () => ({ following_count: following.size })); @@ -117,26 +125,34 @@ async function handleEvent3(kysely: Kysely, event: NostrEvent, x: n } /** Update stats for kind 5 event. */ -async function handleEvent5(kysely: Kysely, event: NostrEvent, x: -1, relay: NStore): Promise { +async function handleEvent5(opts: UpdateStatsOpts): Promise { + const { relay, event, x = -1 } = opts; + const id = event.tags.find(([name]) => name === 'e')?.[1]; + if (id) { const [target] = await relay.query([{ ids: [id], authors: [event.pubkey], limit: 1 }]); if (target) { - await updateStats({ event: target, kysely, relay, x }); + await updateStats({ ...opts, event: target, x }); } } } /** Update stats for kind 6 event. */ -async function handleEvent6(kysely: Kysely, event: NostrEvent, x: number): Promise { +async function handleEvent6(opts: UpdateStatsOpts): Promise { + const { kysely, event, x = 1 } = opts; + const id = event.tags.find(([name]) => name === 'e')?.[1]; + if (id) { await updateEventStats(kysely, id, ({ reposts_count }) => ({ reposts_count: Math.max(0, reposts_count + x) })); } } /** Update stats for kind 7 event. */ -async function handleEvent7(kysely: Kysely, event: NostrEvent, x: number): Promise { +async function handleEvent7(opts: UpdateStatsOpts): Promise { + const { kysely, event, x = 1 } = opts; + const id = event.tags.findLast(([name]) => name === 'e')?.[1]; const emoji = event.content; @@ -166,12 +182,15 @@ async function handleEvent7(kysely: Kysely, event: NostrEvent, x: n } /** Update stats for kind 9735 event. */ -async function handleEvent9735(kysely: Kysely, event: NostrEvent): Promise { +async function handleEvent9735(opts: UpdateStatsOpts): Promise { + const { kysely, event } = opts; + // https://github.com/nostr-protocol/nips/blob/master/57.md#appendix-f-validating-zap-receipts const id = event.tags.find(([name]) => name === 'e')?.[1]; if (!id) return; const amountSchema = z.coerce.number().int().nonnegative().catch(0); + let amount = 0; try { const zapRequest = n.json().pipe(n.event()).parse(event.tags.find(([name]) => name === 'description')?.[1]); diff --git a/packages/ditto/workers/policy.worker.ts b/packages/ditto/workers/policy.worker.ts index b2ca3720..6ea39f1a 100644 --- a/packages/ditto/workers/policy.worker.ts +++ b/packages/ditto/workers/policy.worker.ts @@ -1,11 +1,13 @@ import './deno-env.ts'; // HACK should be removed when `@/config.ts` is removed. +import { DittoConf } from '@ditto/conf'; import { DittoPolyPg } from '@ditto/db'; import '@soapbox/safe-fetch/load'; import { NostrEvent, NostrRelayOK, NPolicy } from '@nostrify/nostrify'; import { ReadOnlyPolicy } from '@nostrify/policies'; import * as Comlink from 'comlink'; +import { ReadOnlySigner } from '@/signers/ReadOnlySigner.ts'; import { DittoPgStore } from '@/storages/DittoPgStore.ts'; /** Serializable object the worker can use to set up the state. */ @@ -31,9 +33,18 @@ export class CustomPolicy implements NPolicy { const db = new DittoPolyPg(databaseUrl, { poolSize: 1 }); + const conf = new Proxy(new DittoConf(new Map()), { + get(target, prop) { + if (prop === 'signer') { + return new ReadOnlySigner(pubkey); + } + return Reflect.get(target, prop); + }, + }); + const store = new DittoPgStore({ db, - pubkey, + conf, timeout: 5_000, }); diff --git a/packages/translators/LibreTranslateTranslator.ts b/packages/translators/LibreTranslateTranslator.ts index cc978e90..62c39e1c 100644 --- a/packages/translators/LibreTranslateTranslator.ts +++ b/packages/translators/LibreTranslateTranslator.ts @@ -72,8 +72,6 @@ export class LibreTranslateTranslator implements DittoTranslator { const response = await this.fetch(request); const json = await response.json(); - console.log(json); - if (!response.ok) { const result = LibreTranslateTranslator.errorSchema().safeParse(json); diff --git a/scripts/admin-event.ts b/scripts/admin-event.ts index bec49460..750057ec 100644 --- a/scripts/admin-event.ts +++ b/scripts/admin-event.ts @@ -9,7 +9,7 @@ import { nostrNow } from '../packages/ditto/utils.ts'; const conf = new DittoConf(Deno.env); const db = new DittoPolyPg(conf.databaseUrl); -const relay = new DittoPgStore({ db, pubkey: await conf.signer.getPublicKey() }); +const relay = new DittoPgStore({ db, conf }); const { signer } = conf; diff --git a/scripts/admin-role.ts b/scripts/admin-role.ts index 59b95878..ba2059f6 100644 --- a/scripts/admin-role.ts +++ b/scripts/admin-role.ts @@ -8,7 +8,7 @@ import { nostrNow } from '../packages/ditto/utils.ts'; const conf = new DittoConf(Deno.env); const db = new DittoPolyPg(conf.databaseUrl); -const relay = new DittoPgStore({ db, pubkey: await conf.signer.getPublicKey() }); +const relay = new DittoPgStore({ db, conf }); const [pubkeyOrNpub, role] = Deno.args; const pubkey = pubkeyOrNpub.startsWith('npub1') ? nip19.decode(pubkeyOrNpub as `npub1${string}`).data : pubkeyOrNpub; diff --git a/scripts/db-export.ts b/scripts/db-export.ts index d9295420..215e9d6f 100644 --- a/scripts/db-export.ts +++ b/scripts/db-export.ts @@ -7,7 +7,7 @@ import { DittoPgStore } from '../packages/ditto/storages/DittoPgStore.ts'; const conf = new DittoConf(Deno.env); const db = new DittoPolyPg(conf.databaseUrl); -const relay = new DittoPgStore({ db, pubkey: await conf.signer.getPublicKey() }); +const relay = new DittoPgStore({ db, conf }); interface ExportFilter { authors?: string[]; diff --git a/scripts/db-import.ts b/scripts/db-import.ts index 4d27e54a..3a51ddb0 100644 --- a/scripts/db-import.ts +++ b/scripts/db-import.ts @@ -9,7 +9,7 @@ import { DittoPgStore } from '../packages/ditto/storages/DittoPgStore.ts'; const conf = new DittoConf(Deno.env); const db = new DittoPolyPg(conf.databaseUrl); -const relay = new DittoPgStore({ db, pubkey: await conf.signer.getPublicKey() }); +const relay = new DittoPgStore({ db, conf }); const sem = new Semaphore(conf.pg.poolSize); console.warn('Importing events...'); diff --git a/scripts/db-policy.ts b/scripts/db-policy.ts index b7ceee96..9dcf8986 100644 --- a/scripts/db-policy.ts +++ b/scripts/db-policy.ts @@ -6,7 +6,7 @@ import { PolicyWorker } from '../packages/ditto/workers/policy.ts'; const conf = new DittoConf(Deno.env); const db = new DittoPolyPg(conf.databaseUrl); -const relay = new DittoPgStore({ db, pubkey: await conf.signer.getPublicKey() }); +const relay = new DittoPgStore({ db, conf }); const policyWorker = new PolicyWorker(conf); let count = 0; diff --git a/scripts/db-populate-nip05.ts b/scripts/db-populate-nip05.ts index c1015f9f..49866579 100644 --- a/scripts/db-populate-nip05.ts +++ b/scripts/db-populate-nip05.ts @@ -10,7 +10,7 @@ import { DittoRelayStore } from '../packages/ditto/storages/DittoRelayStore.ts'; const conf = new DittoConf(Deno.env); const db = new DittoPolyPg(conf.databaseUrl); -const pgstore = new DittoPgStore({ db, pubkey: await conf.signer.getPublicKey() }); +const pgstore = new DittoPgStore({ db, conf }); const relaystore = new DittoRelayStore({ conf, db, relay: pgstore }); const sem = new Semaphore(5); diff --git a/scripts/db-populate-search.ts b/scripts/db-populate-search.ts index 7189b30c..54b28737 100644 --- a/scripts/db-populate-search.ts +++ b/scripts/db-populate-search.ts @@ -6,7 +6,7 @@ import { DittoPgStore } from '../packages/ditto/storages/DittoPgStore.ts'; const conf = new DittoConf(Deno.env); const db = new DittoPolyPg(conf.databaseUrl); -const relay = new DittoPgStore({ db, pubkey: await conf.signer.getPublicKey() }); +const relay = new DittoPgStore({ db, conf }); for await (const msg of relay.req([{ kinds: [0] }])) { if (msg[0] === 'EVENT') { diff --git a/scripts/nostr-pull.ts b/scripts/nostr-pull.ts index d8a4513a..b8204f94 100644 --- a/scripts/nostr-pull.ts +++ b/scripts/nostr-pull.ts @@ -12,7 +12,7 @@ import { DittoPgStore } from '../packages/ditto/storages/DittoPgStore.ts'; const conf = new DittoConf(Deno.env); const db = new DittoPolyPg(conf.databaseUrl); -const relay = new DittoPgStore({ db, pubkey: await conf.signer.getPublicKey() }); +const relay = new DittoPgStore({ db, conf }); interface ImportEventsOpts { profilesOnly: boolean; diff --git a/scripts/setup-kind0.ts b/scripts/setup-kind0.ts index b3dd0682..5428fdcd 100644 --- a/scripts/setup-kind0.ts +++ b/scripts/setup-kind0.ts @@ -7,7 +7,7 @@ import { DittoPgStore } from '../packages/ditto/storages/DittoPgStore.ts'; const conf = new DittoConf(Deno.env); const db = new DittoPolyPg(conf.databaseUrl); -const relay = new DittoPgStore({ db, pubkey: await conf.signer.getPublicKey() }); +const relay = new DittoPgStore({ db, conf }); function die(code: number, ...args: unknown[]) { console.error(...args); diff --git a/scripts/stats-recompute.ts b/scripts/stats-recompute.ts index 16614e45..432e6f92 100644 --- a/scripts/stats-recompute.ts +++ b/scripts/stats-recompute.ts @@ -7,7 +7,7 @@ import { refreshAuthorStats } from '../packages/ditto/utils/stats.ts'; const conf = new DittoConf(Deno.env); const db = new DittoPolyPg(conf.databaseUrl); -const relay = new DittoPgStore({ db, pubkey: await conf.signer.getPublicKey() }); +const relay = new DittoPgStore({ db, conf }); const { kysely } = db; diff --git a/scripts/trends.ts b/scripts/trends.ts index 2a878a12..067643d9 100644 --- a/scripts/trends.ts +++ b/scripts/trends.ts @@ -13,7 +13,7 @@ import { const conf = new DittoConf(Deno.env); const db = new DittoPolyPg(conf.databaseUrl); -const relay = new DittoPgStore({ db, pubkey: await conf.signer.getPublicKey() }); +const relay = new DittoPgStore({ db, conf }); const ctx = { conf, db, relay }; const trendSchema = z.enum(['pubkeys', 'zapped_events', 'events', 'hashtags', 'links']); From 7e00b9f9a2c473d442da802351d57101bc730919 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Thu, 27 Feb 2025 16:52:09 -0600 Subject: [PATCH 2/3] Add PolicyWorker test --- packages/ditto/workers/deno-env.ts | 2 -- packages/ditto/workers/policy.test.ts | 14 ++++++++++++++ packages/ditto/workers/policy.ts | 11 +++++++++++ packages/ditto/workers/policy.worker.ts | 5 +++-- 4 files changed, 28 insertions(+), 4 deletions(-) delete mode 100644 packages/ditto/workers/deno-env.ts create mode 100644 packages/ditto/workers/policy.test.ts diff --git a/packages/ditto/workers/deno-env.ts b/packages/ditto/workers/deno-env.ts deleted file mode 100644 index 1500eb57..00000000 --- a/packages/ditto/workers/deno-env.ts +++ /dev/null @@ -1,2 +0,0 @@ -// @ts-ignore Don't try to access the env from this worker. -Deno.env = new Map(); diff --git a/packages/ditto/workers/policy.test.ts b/packages/ditto/workers/policy.test.ts new file mode 100644 index 00000000..623e7c98 --- /dev/null +++ b/packages/ditto/workers/policy.test.ts @@ -0,0 +1,14 @@ +import { DittoConf } from '@ditto/conf'; +import { generateSecretKey, nip19 } from 'nostr-tools'; + +import { PolicyWorker } from './policy.ts'; + +Deno.test('PolicyWorker', () => { + const conf = new DittoConf( + new Map([ + ['DITTO_NSEC', nip19.nsecEncode(generateSecretKey())], + ]), + ); + + new PolicyWorker(conf); +}); diff --git a/packages/ditto/workers/policy.ts b/packages/ditto/workers/policy.ts index e2617f72..6cddd0a0 100644 --- a/packages/ditto/workers/policy.ts +++ b/packages/ditto/workers/policy.ts @@ -3,6 +3,8 @@ import { NostrEvent, NostrRelayOK, NPolicy } from '@nostrify/nostrify'; import { logi } from '@soapbox/logi'; import * as Comlink from 'comlink'; +import { errorJson } from '@/utils/log.ts'; + import type { CustomPolicy } from '@/workers/policy.worker.ts'; export class PolicyWorker implements NPolicy { @@ -85,6 +87,15 @@ export class PolicyWorker implements NPolicy { return; } + logi({ + level: 'error', + ns: 'ditto.system.policy', + msg: 'Failed to load custom policy', + path: conf.policy, + error: errorJson(e), + enabled: false, + }); + throw new Error(`DITTO_POLICY (error importing policy): ${conf.policy}`); } } diff --git a/packages/ditto/workers/policy.worker.ts b/packages/ditto/workers/policy.worker.ts index 6ea39f1a..80966c2e 100644 --- a/packages/ditto/workers/policy.worker.ts +++ b/packages/ditto/workers/policy.worker.ts @@ -1,5 +1,3 @@ -import './deno-env.ts'; // HACK should be removed when `@/config.ts` is removed. - import { DittoConf } from '@ditto/conf'; import { DittoPolyPg } from '@ditto/db'; import '@soapbox/safe-fetch/load'; @@ -10,6 +8,9 @@ import * as Comlink from 'comlink'; import { ReadOnlySigner } from '@/signers/ReadOnlySigner.ts'; import { DittoPgStore } from '@/storages/DittoPgStore.ts'; +// @ts-ignore Don't try to access the env from this worker. +Deno.env = new Map(); + /** Serializable object the worker can use to set up the state. */ interface PolicyInit { /** Path to the policy module (https, jsr, file, etc) */ From 70d8c2ed594eb5e9871881ce927c80fd5bbf0bf3 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Thu, 27 Feb 2025 16:54:12 -0600 Subject: [PATCH 3/3] DittoPgStore: destructure conf --- packages/ditto/storages/DittoPgStore.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/ditto/storages/DittoPgStore.ts b/packages/ditto/storages/DittoPgStore.ts index 34625fbc..f73d1703 100644 --- a/packages/ditto/storages/DittoPgStore.ts +++ b/packages/ditto/storages/DittoPgStore.ts @@ -170,9 +170,10 @@ export class DittoPgStore extends NPostgres { event: NostrEvent, opts: { signal?: AbortSignal; timeout?: number } = {}, ): Promise { + const { conf } = this.opts; try { await super.transaction(async (relay, kysely) => { - await updateStats({ conf: this.opts.conf, relay, kysely: kysely as unknown as Kysely, event }); + await updateStats({ conf, relay, kysely: kysely as unknown as Kysely, event }); await relay.event(event, opts); }); } catch (e) {