import type { IterablePubkeys, Policy } from 'https://gitlab.com/soapbox-pub/strfry-policies/-/raw/develop/mod.ts'; import { Client } from 'npm:ldapts'; import { nip57 } from '@nostr/tools'; interface LdapConfig { url: string; bindDN: string; password: string; searchDN: string; whitelistPubkeys?: IterablePubkeys; } const ldapPolicy: Policy = async (msg, opts) => { const client = new Client({ url: opts.url }); const { kind, tags } = msg.event; let { pubkey } = msg.event; let out = { id: msg.event.id } if (opts.whitelistPubkeys.includes(pubkey)) { out['action'] = 'accept'; out['msg'] = ''; return out; } // Zap receipt if (kind === 9735) { const descriptionTag = tags.find(([t, v]) => t === 'description' && v); const invalidZapRequestMsg = 'Zap receipts must contain a valid zap request from a relay member'; if (typeof descriptionTag === 'undefined') { out['action'] = 'reject'; out['msg'] = invalidZapRequestMsg; return out; } const zapRequestJSON = descriptionTag[1]; const validationResult = nip57.validateZapRequest(zapRequestJSON); // TODO // The zap receipt event's pubkey MUST be the same as the recipient's lnurl provider's nostrPubkey (retrieved in step 1 of the protocol flow). // The invoiceAmount contained in the bolt11 tag of the zap receipt MUST equal the amount tag of the zap request (if present). if (validationResult === null) { pubkey = JSON.parse(zapRequestJSON).pubkey; } else { out['action'] = 'reject'; out['msg'] = invalidZapRequestMsg; return out; } } try { await client.bind(opts.bindDN, opts.password); const { searchEntries } = await client.search(opts.searchDN, { filter: `(nostrKey=${pubkey})`, attributes: ['nostrKey'] }); const memberKey = searchEntries[0]?.nostrKey; if (memberKey === pubkey) { out['action'] = 'accept'; out['msg'] = ''; } else { out['action'] = 'reject'; out['msg'] = 'Only members can publish notes on this relay'; } } catch (ex) { out['action'] = 'reject'; out['msg'] = 'Auth service temporarily unavailable'; } finally { await client.unbind(); return out; } }; export default ldapPolicy;