Files
rootnode-academy/platform/api/src/cookies.js
T
ced4568 52c17c1907 feat(identity): add persistent Postgres-backed session store
Replaces the in-memory studentSessions/adminSessions Maps (Phase 2B — gone on every
restart) with a sessions table. Browser holds an opaque CSPRNG bearer token; only its
SHA-256 hash is ever stored server-side, same principle as password hashing. Each session
has an absolute expiry (fixed at creation) and a sliding idle expiry (pushed forward on
every authenticated request, capped at the absolute one) — one atomic UPDATE...RETURNING
per resolve, no read-then-write race. Student and instructor sessions stay fully separate
token namespaces, matching Phase 2B's cookie-name separation.

cookies.js centralizes Set-Cookie construction so the Secure attribute (COOKIE_SECURE=1,
for real HTTPS deployments) is applied consistently instead of hand-built per call site.
2026-08-18 13:35:54 -05:00

22 lines
878 B
JavaScript

// Cookie construction, centralized so the Secure attribute is set consistently everywhere
// instead of hand-built per call site. Secure is opt-in via COOKIE_SECURE=1 — off by default
// because local dev and the current single-VM pilot deployment run over plain HTTP; anything
// served over real HTTPS should set COOKIE_SECURE=1 (see docs/PHASE3A... "production HTTPS
// expectations").
const SECURE = process.env.COOKIE_SECURE === '1';
function buildCookie(name, value, { maxAgeSec, httpOnly = true } = {}) {
const parts = [`${name}=${value}`, 'Path=/', 'SameSite=Lax'];
if (httpOnly) parts.push('HttpOnly');
if (SECURE) parts.push('Secure');
parts.push(`Max-Age=${maxAgeSec != null ? maxAgeSec : 0}`);
return parts.join('; ');
}
function clearCookie(name) {
return buildCookie(name, '', { maxAgeSec: 0 });
}
module.exports = { buildCookie, clearCookie };