Part of #151
Question
Audit finding 4 (findings doc, from #159): the auth-boundary logic is untested and partly unhardened. One pass, four items:
- Extract + test the pure gates —
resolveUserId (worker/index.ts:118, the DO tenant-isolation key: a regression here cross-wires two users' outlines), isAdminSession (:441), isPlausibleEmail (:436), and the invite-code predicate (worker/auth.ts:60-78) have zero test references and e2e can't reach them (the mock intercepts /api/auth). Extract to a pure module (the outline-ops.ts pattern, e.g. worker/identity.ts) and add a .test.ts: routing key equals user.id never email; empty/whitespace INVITE_CODES denies all; unknown/empty code denied; admin allowlist case-insensitive and fail-closed when unset.
- Assert
BETTER_AUTH_SECRET — it is optional-typed and passed unguarded (worker/auth.ts:24,38); the "Better Auth fails closed in prod" comment is unverified library behavior. Add an explicit non-empty assertion at createAuth.
- Pin admin identity to
user.id instead of an (unverified) email — closes the register-the-admin-email-first path permanently, even though the precondition is already false in prod.
- SSRF nit —
isPrivateIpv4 (worker/unfurl-core.ts:29) misses IPv4-mapped IPv6 ([::ffff:127.0.0.1]). Integer/hex forms are NOT a gap (WHATWG URL canonicalizes them); Cloudflare's platform block covers this anyway. One-line belt-and-suspenders while in the area.
Part of #151
Question
Audit finding 4 (findings doc, from #159): the auth-boundary logic is untested and partly unhardened. One pass, four items:
resolveUserId(worker/index.ts:118, the DO tenant-isolation key: a regression here cross-wires two users' outlines),isAdminSession(:441),isPlausibleEmail(:436), and the invite-code predicate (worker/auth.ts:60-78) have zero test references and e2e can't reach them (the mock intercepts/api/auth). Extract to a pure module (theoutline-ops.tspattern, e.g.worker/identity.ts) and add a.test.ts: routing key equalsuser.idnever email; empty/whitespaceINVITE_CODESdenies all; unknown/empty code denied; admin allowlist case-insensitive and fail-closed when unset.BETTER_AUTH_SECRET— it is optional-typed and passed unguarded (worker/auth.ts:24,38); the "Better Auth fails closed in prod" comment is unverified library behavior. Add an explicit non-empty assertion atcreateAuth.user.idinstead of an (unverified) email — closes the register-the-admin-email-first path permanently, even though the precondition is already false in prod.isPrivateIpv4(worker/unfurl-core.ts:29) misses IPv4-mapped IPv6 ([::ffff:127.0.0.1]). Integer/hex forms are NOT a gap (WHATWG URL canonicalizes them); Cloudflare's platform block covers this anyway. One-line belt-and-suspenders while in the area.