/** * 单元测试:origin configuration 校验(C-HTTPS-INBOUND / C-LB-SINGLE-REG-URL)。 * 运行:cd cloudflare-worker && node --test */ import test from "node:test"; import assert from "node:assert/strict"; import { parseBackendOrigin, parseBackendOrigins, SAFE_ROUTES, LB_ROUTES } from "../src/backends.js"; test("http origin is rejected (https-only, fail-closed)", () => { assert.throws(() => parseBackendOrigin("http://bot.example"), /https/); }); test("non-https / invalid origins are rejected", () => { for (const bad of ["", " ", "not a url", "://x", "ws://bot.example", "wss://bot.example", "http://x"]) { assert.throws(() => parseBackendOrigin(bad), Error, `must reject: ${deep(bad)}`); } }); test("embedded credentials / query / fragment / path are rejected", () => { assert.throws(() => parseBackendOrigin("https://user:pass@bot.example"), /credentials/); assert.throws(() => parseBackendOrigin("https://bot.example?x=1"), /query|fragment/); assert.throws(() => parseBackendOrigin("https://bot.example#frag"), /query|fragment/); assert.throws(() => parseBackendOrigin("https://bot.example/api"), /bare origin/); }); test("valid https origins normalize to origin form", () => { const a = parseBackendOrigin("https://bot.example/"); assert.equal(a.url, "https://bot.example"); assert.equal(a.host, "bot.example"); assert.equal(a.port, 443); const b = parseBackendOrigin("https://bot.example:8443"); assert.equal(b.url, "https://bot.example:8443"); assert.equal(b.port, 8443); }); test("BACKEND_ORIGINS_JSON parses, dedups, validates all entries", () => { const raw = JSON.stringify(["https://a.example", "https://b.example", "https://a.example"]); const list = parseBackendOrigins(raw); assert.deepEqual(list.map((o) => o.url), ["https://a.example", "https://b.example"]); assert.throws(() => parseBackendOrigins(JSON.stringify(["https://a.example", "http://c.example"])), /https/); assert.throws(() => parseBackendOrigins("nope"), /valid JSON/); assert.throws(() => parseBackendOrigins("[]"), /non-empty/); }); test("route safelist forwards /healthz and blocks unknown paths (C-LB-SINGLE-REG-URL)", () => { for (const r of [ "/", "/assets/config.js", "/assets/styles.css", "/api/status", "/ready", "/webhook/tg", "/push/jmap", "/reconcile", "/api/push/register", "/api/push/disable", "/api/config", "/api/business-config", "/api/admin/session", "/api/admin/session/revoke", "/api/enabled", "/healthz", ]) { assert.ok(LB_ROUTES.includes(r), `forwarded: ${r}`); } for (const r of ["/healthz-worker", "/admin", "/debug", "/jmap/session", "/ready/extra"]) { assert.ok(!LB_ROUTES.includes(r), `must be blocked: ${r}`); assert.ok(!SAFE_ROUTES.includes(r), `must not be a safe route: ${r}`); } }); /** 让断言失败信息可读,且不泄漏敏感值。 */ function deep(v) { return typeof v === "string" && v.length > 48 ? `${v.slice(0, 12)}…(${v.length})` : String(v); }