// Tests for the signup-first join page's pure decision helpers (prejoin.js). import test from "node:test"; import assert from "node:assert/strict"; import { PREJOIN_STASH_KEY, offerPrejoin, prejoinStash, readPrejoinReturn, homeSigninURL, } from "../web/static/prejoin.js"; const HOME = "https://home.example.com"; const base = { kind: "join", homeOrigin: HOME, embed: false, native: false, signedUp: false }; test("offerPrejoin: fresh join/setup kinds with a home server", () => { assert.equal(offerPrejoin(base), true); assert.equal(offerPrejoin({ ...base, kind: "setup" }), true); }); test("offerPrejoin: never for established or unsupported contexts", () => { for (const kind of ["device", "adopt", "adopt-admin"]) { assert.equal(offerPrejoin({ ...base, kind }), false); } assert.equal(offerPrejoin({ ...base, homeOrigin: "" }), false); assert.equal(offerPrejoin({ ...base, homeOrigin: "__HOME_ORIGIN__" }), false); assert.equal(offerPrejoin({ ...base, embed: true }), false); assert.equal(offerPrejoin({ ...base, native: true }), false); assert.equal(offerPrejoin({ ...base, signedUp: true }), false); }); test("round trip: stash then read back on a genuine return", () => { const now = 1_000_000; const stored = prejoinStash({ frag: "e1.SECRET~Ann~bkey", nonce: "n0nce", now }); const r = readPrejoinReturn({ search: "?su=n0nce", storedJSON: stored, now: now + 5000 }); assert.deepEqual(r, { signedUp: true, frag: "e1.SECRET~Ann~bkey" }); }); test("readPrejoinReturn: no marker, forged nonce, stale stash, clock skew", () => { const now = 1_000_000; const stored = prejoinStash({ frag: "f", nonce: "good", now }); assert.deepEqual(readPrejoinReturn({ search: "", storedJSON: stored, now }), { signedUp: false, frag: "" }); assert.deepEqual(readPrejoinReturn({ search: "?su=evil", storedJSON: stored, now }), { signedUp: false, frag: "" }); assert.deepEqual(readPrejoinReturn({ search: "?su=good", storedJSON: stored, now: now + 61 * 60 * 1000 }), { signedUp: false, frag: "" }); assert.deepEqual(readPrejoinReturn({ search: "?su=good", storedJSON: stored, now: now - 1000 }), { signedUp: false, frag: "" }); assert.deepEqual(readPrejoinReturn({ search: "?su=good", storedJSON: "not json", now }), { signedUp: false, frag: "" }); assert.deepEqual(readPrejoinReturn({ search: "?su=good", storedJSON: "", now }), { signedUp: false, frag: "" }); }); test("homeSigninURL: return URL rides the fragment, encoded, no invite secret", () => { const url = homeSigninURL(HOME, "https://chat.example.com", "/join/abc", "n+once"); assert.equal(url, HOME + "/#joinret=" + encodeURIComponent("https://chat.example.com/join/abc?su=" + encodeURIComponent("n+once"))); assert.equal(homeSigninURL(HOME + "/", "https://c.example.com", "/join/x", "n"), HOME + "/#joinret=" + encodeURIComponent("https://c.example.com/join/x?su=n")); }); test("stash key is stable", () => assert.equal(PREJOIN_STASH_KEY, "lchat_prejoin"));