diff --git a/entrypoint.example.ts b/entrypoint.example.ts index d933176..61fe279 100644 --- a/entrypoint.example.ts +++ b/entrypoint.example.ts @@ -3,6 +3,7 @@ import { antiDuplicationPolicy, hellthreadPolicy, + keywordPolicy, noopPolicy, pipeline, pubkeyBanPolicy, @@ -18,6 +19,7 @@ for await (const msg of readStdin()) { [antiDuplicationPolicy, { ttl: 60000, minLength: 50 }], [rateLimitPolicy, { whitelist: ['127.0.0.1'] }], [pubkeyBanPolicy, ['e810fafa1e89cdf80cced8e013938e87e21b699b24c8570537be92aec4b12c18']], + [keywordPolicy, ['https://t.me/']], ]); writeStdout(result); diff --git a/mod.ts b/mod.ts index bef8ed9..b5f080f 100644 --- a/mod.ts +++ b/mod.ts @@ -1,9 +1,11 @@ export { default as antiDuplicationPolicy } from './src/policies/anti-duplication-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'; export { default as pubkeyBanPolicy } from './src/policies/pubkey-ban-policy.ts'; export { default as rateLimitPolicy } from './src/policies/rate-limit-policy.ts'; export { default as readOnlyPolicy } from './src/policies/read-only-policy.ts'; +export { default as whitelistPolicy } from './src/policies/whitelist-policy.ts'; export { readStdin, writeStdout } from './src/io.ts'; export { default as pipeline } from './src/pipeline.ts'; diff --git a/src/policies/keyword-policy.test.ts b/src/policies/keyword-policy.test.ts new file mode 100644 index 0000000..f33f7df --- /dev/null +++ b/src/policies/keyword-policy.test.ts @@ -0,0 +1,15 @@ +import { assert } from '../deps.ts'; +import { buildEvent, buildInputMessage } from '../test.ts'; + +import keywordPolicy from './keyword-policy.ts'; + +Deno.test('blocks banned pubkeys', async () => { + const words = ['https://t.me/spam']; + + const msg0 = buildInputMessage(); + const msg1 = buildInputMessage({ event: buildEvent({ content: '🔥🔥🔥 https://t.me/spam 我想死' }) }); + + assert((await keywordPolicy(msg0, words)).action === 'accept'); + assert((await keywordPolicy(msg1, words)).action === 'reject'); + assert((await keywordPolicy(msg1, [])).action === 'accept'); +}); diff --git a/src/policies/keyword-policy.ts b/src/policies/keyword-policy.ts new file mode 100644 index 0000000..7487dd3 --- /dev/null +++ b/src/policies/keyword-policy.ts @@ -0,0 +1,29 @@ +import { Policy } from '../types.ts'; + +/** Reject events containing any of the strings in its content. */ +const keywordPolicy: Policy> = ({ event: { id, content } }, words = []) => { + let isMatch = false; + + for (const word of words) { + if (content.toLocaleLowerCase().includes(word.toLowerCase())) { + isMatch = true; + break; + } + } + + if (isMatch) { + return { + id, + action: 'reject', + msg: 'Event contains a banned word or phrase.', + }; + } + + return { + id, + action: 'accept', + msg: '', + }; +}; + +export default keywordPolicy;