import * as Effect from "effect/Effect"; import assert from "node:assert/strict"; import { test } from "node:test"; import { Secret } from "../configuration/secrets.ts"; import { customDomainOrigin } from "../shared/domain-origin.ts"; import { authorizeRuntimeRequest, createOwnerSession, verifyOwnerSession, } from "../worker/session.ts"; const management = "https://flarebot-0123456789abcdef0123456789abcdef.example.workers.dev"; const custom = "https://bot.example.com"; const installation = { schemaVersion: 1, installationId: "0123456789abcdef0123456789abcdef", ownerSubject: "owner", runtimeOrigin: custom, controlPlaneOrigin: "https://control.example.com", }; const secret = new Secret("a-session-secret-that-is-at-least-32-bytes"); test("custom domain origins are canonical HTTPS DNS origins", () => { assert.equal(customDomainOrigin(custom), custom); for (const origin of [ "http://bot.example.com", "https://bot.example.com/route", "https://bot.example.com:8443", "https://127.0.0.1", "https://bot.example.workers.dev", "https://*.example.com", "https://BOT.example.com", ]) assert.equal(customDomainOrigin(origin), null, origin); }); test("owner session and state-changing requests bind the exact custom origin", async () => { const setCookie = await Effect.runPromise( createOwnerSession(secret, installation), ); const cookie = setCookie.split(";")[0]; const request = (url, origin = custom, method = "GET") => new Request(url, { method, headers: { Cookie: cookie, Origin: origin } }); assert.ok( await Effect.runPromise( verifyOwnerSession(request(`${custom}/api`), secret, installation), ), ); assert.equal( await Effect.runPromise( verifyOwnerSession( request(`${management}/api`, management), secret, installation, ), ), null, ); assert.equal( await Effect.runPromise( authorizeRuntimeRequest( request(`${custom}/api`, management, "POST"), secret, installation, ), ).then((response) => response?.status), 403, ); assert.equal( await Effect.runPromise( authorizeRuntimeRequest( new Request(`${custom}/agents/personal`, { headers: { Cookie: cookie, Origin: management, Upgrade: "websocket" }, }), secret, installation, ), ).then((response) => response?.status), 403, ); });