Zero-dependency Discord connector under packages/discord: binding
validation, REST and gateway clients, pi engine adapter, journal with
append-only inbox, outbox, admissions and notices, and a run.lock
ownership record {pid, start, boot} whose identity is checked three ways
and whose cleanup is gated by STOP. CLI check|run|stop|unlock via
scripts/discord.sh; offline suite scripts/test-discord.sh (28 checks,
87 node tests).
Reviewed by rev-code-02 on #1509 over nine rounds; approved exact tree
4e0feb6758c0a7e4a71483912a8e0d3e3ec95aef at comment 26170. Corrections
(1) to (12) recorded in BUILD-LOG. No listener started, no token read,
no Discord write; the live pilot follows this commit per the brief.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
68 lines
4.8 KiB
JavaScript
68 lines
4.8 KiB
JavaScript
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { authorize, DROP } from "../src/authorize.mjs";
|
|
import { binding, message, IDS } from "./helpers.mjs";
|
|
|
|
const b = binding();
|
|
const threads = new Map([
|
|
[IDS.threadOfAdmin, { type: 11, parentId: IDS.admin, name: "admin-thread", guildId: IDS.guild }],
|
|
[IDS.threadOfOther, { type: 11, parentId: IDS.other, name: "other-thread", guildId: IDS.guild }],
|
|
["100000000000000030", { type: 12, parentId: IDS.general, name: "private-general-thread", guildId: IDS.guild }],
|
|
["100000000000000031", { type: 0, parentId: null, name: "text-not-thread", guildId: IDS.guild }],
|
|
]);
|
|
const info = (id) => threads.get(id);
|
|
const botMention = [{ id: IDS.bot, username: "bot" }];
|
|
|
|
const table = [
|
|
["open channel, listed user", message(), { ok: true, channel: IDS.admin, thread: null }],
|
|
["wrong guild", message({ guild_id: "100000000000000099" }), { ok: false, reason: DROP.GUILD }],
|
|
["no guild (DM)", message({ guild_id: undefined }), { ok: false, reason: DROP.GUILD }],
|
|
["unlisted channel", message({ channel_id: IDS.other }), { ok: false, reason: DROP.CHANNEL }],
|
|
["unknown channel, no info", message({ channel_id: "100000000000000098" }), { ok: false, reason: DROP.CHANNEL }],
|
|
["thread of listed parent", message({ channel_id: IDS.threadOfAdmin }), { ok: true, channel: IDS.admin, thread: IDS.threadOfAdmin }],
|
|
["thread of unlisted parent", message({ channel_id: IDS.threadOfOther }), { ok: false, reason: DROP.THREAD_PARENT }],
|
|
["text channel that is not a thread and not listed", message({ channel_id: "100000000000000031" }), { ok: false, reason: DROP.CHANNEL }],
|
|
["unlisted user", message({ author: { id: IDS.stranger } }), { ok: false, reason: DROP.USER }],
|
|
["no author", message({ author: undefined }), { ok: false, reason: DROP.USER }],
|
|
["bot author (listed id, bot flag)", message({ author: { id: IDS.owner, bot: true } }), { ok: false, reason: DROP.BOT }],
|
|
["system author", message({ author: { id: IDS.owner, system: true } }), { ok: false, reason: DROP.BOT }],
|
|
["the bot itself", message({ author: { id: IDS.bot } }), { ok: false, reason: DROP.SELF }],
|
|
["webhook", message({ webhook_id: "100000000000000050" }), { ok: false, reason: DROP.WEBHOOK }],
|
|
["mention channel without mention", message({ channel_id: IDS.general }), { ok: false, reason: DROP.MENTION }],
|
|
["mention channel with bot mention", message({ channel_id: IDS.general, mentions: botMention }), { ok: true, channel: IDS.general, thread: null }],
|
|
["mention channel with @everyone only", message({ channel_id: IDS.general, mention_everyone: true, content: "@everyone hi" }), { ok: false, reason: DROP.MENTION }],
|
|
["mention channel mentioning someone else", message({ channel_id: IDS.general, mentions: [{ id: IDS.stranger }] }), { ok: false, reason: DROP.MENTION }],
|
|
["mention channel, content says @bot but mentions empty", message({ channel_id: IDS.general, content: `<@${IDS.bot}> hi` }), { ok: false, reason: DROP.MENTION }],
|
|
["private thread under mention channel, mentioned", message({ channel_id: "100000000000000030", mentions: botMention }), { ok: true, channel: IDS.general, thread: "100000000000000030" }],
|
|
["private thread under mention channel, not mentioned", message({ channel_id: "100000000000000030" }), { ok: false, reason: DROP.MENTION }],
|
|
["thread in another guild per channel info", message({ channel_id: IDS.threadOfAdmin, guild_id: IDS.guild }), { ok: true, channel: IDS.admin, thread: IDS.threadOfAdmin }],
|
|
["not an object", null, { ok: false, reason: DROP.NOT_OBJECT }],
|
|
["no id", message({ id: "" }), { ok: false, reason: DROP.NO_ID }],
|
|
["oversize content is accepted and flagged", message({ content: "x".repeat(4001) }), { ok: true, channel: IDS.admin, thread: null, oversize: true }],
|
|
["exactly the limit is not oversize", message({ content: "x".repeat(4000) }), { ok: true, channel: IDS.admin, thread: null, oversize: false }],
|
|
];
|
|
|
|
for (const [name, msg, expected] of table) {
|
|
test(`authorize: ${name}`, () => {
|
|
const r = authorize(b, msg, info);
|
|
assert.equal(r.ok, expected.ok, JSON.stringify(r));
|
|
if (!expected.ok) assert.equal(r.reason, expected.reason);
|
|
else {
|
|
assert.equal(r.channel.id, expected.channel);
|
|
assert.equal(r.thread ? r.thread.id : null, expected.thread);
|
|
if (expected.oversize !== undefined) assert.equal(r.oversize, expected.oversize);
|
|
}
|
|
});
|
|
}
|
|
|
|
test("authorize: order puts wrong guild before user, and user before channel (no channel lookup for strangers)", () => {
|
|
let looked = 0;
|
|
const spy = (id) => {
|
|
looked += 1;
|
|
return info(id);
|
|
};
|
|
assert.equal(authorize(b, message({ guild_id: "100000000000000099", author: { id: IDS.stranger } }), spy).reason, DROP.GUILD);
|
|
assert.equal(authorize(b, message({ channel_id: IDS.threadOfAdmin, author: { id: IDS.stranger } }), spy).reason, DROP.USER);
|
|
assert.equal(looked, 0);
|
|
});
|