load custom policy from policy spec in worker

This commit is contained in:
Siddharth Singh 2025-03-30 14:28:39 +05:30
parent 70dba0c66b
commit 282748ec80
No known key found for this signature in database

View file

@ -2,25 +2,36 @@ import { DittoConf } from '@ditto/conf';
import { DittoPolyPg } from '@ditto/db'; import { DittoPolyPg } from '@ditto/db';
import '@soapbox/safe-fetch/load'; import '@soapbox/safe-fetch/load';
import { NostrEvent, NostrRelayOK, NPolicy } from '@nostrify/nostrify'; import { NostrEvent, NostrRelayOK, NPolicy } from '@nostrify/nostrify';
import { ReadOnlyPolicy } from '@nostrify/policies'; import { ReadOnlyPolicy, PolicyRegistry, PipePolicy } from '@nostrify/policies';
import * as Comlink from 'comlink'; import * as Comlink from 'comlink';
import { ReadOnlySigner } from '@/signers/ReadOnlySigner.ts'; import { ReadOnlySigner } from '@/signers/ReadOnlySigner.ts';
import { DittoPgStore } from '@/storages/DittoPgStore.ts'; import { DittoPgStore } from '@/storages/DittoPgStore.ts';
import { DEFAULT_POLICY_SPEC, PolicySpec } from '@/utils/policies.ts';
// @ts-ignore Don't try to access the env from this worker. // @ts-ignore Don't try to access the env from this worker.
Deno.env = new Map<string, string>(); Deno.env = new Map<string, string>();
/** Serializable object the worker can use to set up the state. */ interface PolicyInitCommon {
interface PolicyInit {
/** Path to the policy module (https, jsr, file, etc) */
path: string;
/** Database URL to connect to. */ /** Database URL to connect to. */
databaseUrl: string; databaseUrl: string;
/** Admin pubkey to use for DittoPgStore checks. */ /** Admin pubkey to use for DittoPgStore checks. */
pubkey: string; pubkey: string;
mode: "script" | "event";
} }
interface ScriptPolicyInit {
/** Path to the policy module (https, jsr, file, etc) */
path: string;
mode: "script";
}
interface EventPolicyInit {
mode: "event";
}
type PolicyInit = PolicyInitCommon & (ScriptPolicyInit | EventPolicyInit);
export class CustomPolicy implements NPolicy { export class CustomPolicy implements NPolicy {
private policy: NPolicy = new ReadOnlyPolicy(); private policy: NPolicy = new ReadOnlyPolicy();
@ -29,8 +40,8 @@ export class CustomPolicy implements NPolicy {
return this.policy.call(event, signal); return this.policy.call(event, signal);
} }
async init({ path, databaseUrl, pubkey }: PolicyInit): Promise<void> { async init(opts: PolicyInit): Promise<void> {
const Policy = (await import(path)).default; const { databaseUrl, pubkey } = opts;
const db = new DittoPolyPg(databaseUrl, { poolSize: 1 }); const db = new DittoPolyPg(databaseUrl, { poolSize: 1 });
@ -49,7 +60,27 @@ export class CustomPolicy implements NPolicy {
timeout: 5_000, timeout: 5_000,
}); });
this.policy = new Policy({ db, store, pubkey }); if (opts.mode === "script") {
const Policy = (await import(opts.path)).default;
this.policy = new Policy({ db, store, pubkey });
}
else {
const registry = new PolicyRegistry({ store, antiDuplicationPolicyStore: await Deno.openKv() });
const policies: NPolicy[] = [];
const event = await store
.query([{ kinds: [11984], authors: [await conf.signer.getPublicKey()] }])
.then(results => results[0]);
const spec: PolicySpec = event ? JSON.parse(event.content) : DEFAULT_POLICY_SPEC;
for (const item of spec.policies) {
const policy = registry.available[item.name];
if (!policy) continue;
policies.push(policy.instantiate(item.params || {}));
}
this.policy = new PipePolicy(policies);
}
} }
} }