From 61729d4f12e21aa0d18a96ba5a9b7d8a4dbeaae5 Mon Sep 17 00:00:00 2001 From: Dogfather Date: Wed, 5 Aug 2026 20:00:15 +0200 Subject: [PATCH] Zugangs-Sperre: Code wird nach dem Schliessen des Browsers wieder gefragt Sitzungs-Cookie ohne maxAge/expires statt 90-Tage-Cookie; zusaetzlich Notbremse von 12 Stunden im signierten Token, falls ein Browser sehr lange offen bleibt. --- server/gate.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/server/gate.js b/server/gate.js index ea1e9b8..2d0386d 100644 --- a/server/gate.js +++ b/server/gate.js @@ -7,7 +7,13 @@ export const COOKIE_NAME = "dogi_session"; export const ROLE_COOKIE_NAME = "dogi_role"; -export const SESSION_TAGE = 90; + +/* Zugang gilt nur für die laufende Browser-Sitzung (Wunsch 05.08.2026: "jedes Mal wenn wir den + Browser zu machen, soll der Code wieder gefragt werden"). Umgesetzt über ein reines + Sitzungs-Cookie OHNE maxAge/expires — das löscht der Browser beim Schließen selbst. + SESSION_STUNDEN ist nur die zusätzliche Notbremse im signierten Token für den Fall, dass ein + Browser tage-/wochenlang offen bleibt (dann läuft der Zugang trotzdem ab). */ +export const SESSION_STUNDEN = 12; function b64urlEncode(bytes) { let bin = ""; @@ -25,7 +31,7 @@ async function hmacKey(secret) { } export async function signSession(role, secret) { - const payload = JSON.stringify({ role, exp: Date.now() + SESSION_TAGE * 24 * 60 * 60 * 1000 }); + const payload = JSON.stringify({ role, exp: Date.now() + SESSION_STUNDEN * 60 * 60 * 1000 }); const payloadB64 = b64urlEncode(new TextEncoder().encode(payload)); const key = await hmacKey(secret); const sig = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(payloadB64)); @@ -61,9 +67,9 @@ export async function gateAuthHandler(req, res) { } const session = await signSession(role, process.env.SITE_ACCESS_SECRET); - const maxAge = SESSION_TAGE * 24 * 60 * 60 * 1000; - res.cookie(COOKIE_NAME, session, { path: "/", maxAge, httpOnly: true, secure: true, sameSite: "lax" }); - res.cookie(ROLE_COOKIE_NAME, role, { path: "/", maxAge, secure: true, sameSite: "lax" }); + // Bewusst OHNE maxAge/expires → reines Sitzungs-Cookie, verfällt beim Schließen des Browsers. + res.cookie(COOKIE_NAME, session, { path: "/", httpOnly: true, secure: true, sameSite: "lax" }); + res.cookie(ROLE_COOKIE_NAME, role, { path: "/", secure: true, sameSite: "lax" }); return res.json({ ok: true, next }); }