diff --git a/deno.lock b/deno.lock index 0a80d27..975a6ba 100644 --- a/deno.lock +++ b/deno.lock @@ -54,5 +54,58 @@ "https://deno.land/x/sqlite@v2.3.2/src/row_objects.ts": "cf7ad165bb14c0fd346c46a7f3ea08043ace747d1abae3787bbe4b36be11b09c", "https://deno.land/x/sqlite@v2.3.2/src/rows.ts": "1b05730096f8df626bfc9d1597a776cc5ac7d989910a20711fa28c7a8daebb0e", "https://deno.land/x/sqlite@v2.3.2/src/wasm.ts": "9747b8c4de5542f2359a35461317f08a244fe8a0933c7e279caad27a0190e6bf" + }, + "npm": { + "specifiers": { + "nostr-tools@^1.7.4": "nostr-tools@1.7.4" + }, + "packages": { + "@noble/hashes@1.0.0": { + "integrity": "sha512-DZVbtY62kc3kkBtMHqwCOfXrT/hnoORy5BJ4+HU1IR59X0KWAOqsfzQPcUl/lQLlG7qXbe/fZ3r/emxtAl+sqg==", + "dependencies": {} + }, + "@noble/hashes@1.2.0": { + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "dependencies": {} + }, + "@noble/secp256k1@1.7.1": { + "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", + "dependencies": {} + }, + "@scure/base@1.1.1": { + "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", + "dependencies": {} + }, + "@scure/bip32@1.1.5": { + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "dependencies": { + "@noble/hashes": "@noble/hashes@1.2.0", + "@noble/secp256k1": "@noble/secp256k1@1.7.1", + "@scure/base": "@scure/base@1.1.1" + } + }, + "@scure/bip39@1.1.1": { + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "dependencies": { + "@noble/hashes": "@noble/hashes@1.2.0", + "@scure/base": "@scure/base@1.1.1" + } + }, + "nostr-tools@1.7.4": { + "integrity": "sha512-YowDJ+S3UW9KCYPDZfZXXMITrJSMjiCmFOK5HohyKkg+w6EipFUTkFRBPRA2BTLXO/qw8gukKXfL0B7Dv3jtcQ==", + "dependencies": { + "@noble/hashes": "@noble/hashes@1.0.0", + "@noble/secp256k1": "@noble/secp256k1@1.7.1", + "@scure/base": "@scure/base@1.1.1", + "@scure/bip32": "@scure/bip32@1.1.5", + "@scure/bip39": "@scure/bip39@1.1.1", + "prettier": "prettier@2.8.4" + } + }, + "prettier@2.8.4": { + "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", + "dependencies": {} + } + } } } diff --git a/entrypoint.example.ts b/entrypoint.example.ts index 26f1a15..1d7f831 100755 --- a/entrypoint.example.ts +++ b/entrypoint.example.ts @@ -2,6 +2,7 @@ //bin/true; exec deno run -A "$0" "$@" import { antiDuplicationPolicy, + filterPolicy, hellthreadPolicy, keywordPolicy, noopPolicy, @@ -16,6 +17,7 @@ import { for await (const msg of readStdin()) { const result = await pipeline(msg, [ noopPolicy, + [filterPolicy, { kinds: [0, 1, 3, 5, 7, 1984, 9734, 9735, 10002] }], [keywordPolicy, ['https://t.me/']], [regexPolicy, /(🟠|🔥|😳)ChtaGPT/i], [pubkeyBanPolicy, ['e810fafa1e89cdf80cced8e013938e87e21b699b24c8570537be92aec4b12c18']], diff --git a/mod.ts b/mod.ts index cf5f336..8a8a930 100644 --- a/mod.ts +++ b/mod.ts @@ -1,4 +1,5 @@ export { default as antiDuplicationPolicy } from './src/policies/anti-duplication-policy.ts'; +export { default as filterPolicy } from './src/policies/filter-policy.ts'; export { default as hellthreadPolicy } from './src/policies/hellthread-policy.ts'; export { default as keywordPolicy } from './src/policies/keyword-policy.ts'; export { default as noopPolicy } from './src/policies/noop-policy.ts'; diff --git a/src/policies/filter-policy.test.ts b/src/policies/filter-policy.test.ts new file mode 100644 index 0000000..d317f2a --- /dev/null +++ b/src/policies/filter-policy.test.ts @@ -0,0 +1,13 @@ +import { assertEquals } from '../deps.ts'; +import { buildEvent, buildInputMessage } from '../test.ts'; + +import filterPolicy from './filter-policy.ts'; + +Deno.test('only allows events that match the filter', async () => { + const msg0 = buildInputMessage({ event: buildEvent({ kind: 0 }) }); + const msg1 = buildInputMessage({ event: buildEvent({ kind: 1 }) }); + + assertEquals((await filterPolicy(msg0, { kinds: [1] })).action, 'reject'); + assertEquals((await filterPolicy(msg1, { kinds: [1] })).action, 'accept'); + assertEquals((await filterPolicy(msg1, { kinds: [1], authors: [] })).action, 'reject'); +}); diff --git a/src/policies/filter-policy.ts b/src/policies/filter-policy.ts new file mode 100644 index 0000000..b5b8a2a --- /dev/null +++ b/src/policies/filter-policy.ts @@ -0,0 +1,24 @@ +import { Policy } from '../types.ts'; + +import { Filter, matchFilter } from 'npm:nostr-tools@^1.7.4'; + +/** Reject all events which don't match the filter. */ +const filterPolicy: Policy = ({ event }, filter = {}) => { + if (matchFilter(filter, event)) { + return { + id: event.id, + action: 'accept', + msg: '', + }; + } + + return { + id: event.id, + action: 'reject', + msg: 'blocked: the event doesn\'t match the allowed filters', + }; +}; + +export default filterPolicy; + +export type { Filter };