Verwaltung: eigens gestalteter Abmelde-Button rechts über der Hero-Kiste
Neuer Endpunkt POST /gate-logout (functions/_middleware.js) löscht alle drei Zugangs-Cookies auf einmal (normale 90-Tage-Sitzung, Rollen-Anzeige, tägliche Verwaltungs-Sitzung) — "abmelden" bedeutet also wirklich abmelden von allem, nicht nur einen Teil der Schranke offen lassen. Button im selben "besonderen" Look wie die Hero-Kiste darunter (wandernder Verlaufsrand in den drei Markenfarben + Funkeln) statt eines schlichten Standard-Buttons. Per curl (Cookie-Löschung + anschließende 302-Sperre auf /verwaltung/ und /) und per echtem Browser-Klicktest (Playwright) end-to-end verifiziert.
This commit is contained in:
@@ -44,6 +44,8 @@
|
||||
- API-Routen (/api/*) bekommen bei fehlender Sitzung eine 401-JSON-Antwort statt der
|
||||
302-Weiterleitung zur Zugangscode-Seite — ein fetch() im Checkout/Verwaltung-Skript soll
|
||||
einen klaren Fehler sehen, nicht versehentlich HTML als Antwort bekommen.
|
||||
- POST /gate-logout (04.08.2026, Abmelde-Button auf /verwaltung/) löscht alle drei
|
||||
Zugangs-Cookies auf einmal (normale Sitzung + Rollen-Anzeige + tägliche Verwaltungs-Sitzung).
|
||||
|
||||
Die Signatur (HMAC-SHA256 über Web Crypto, in jeder Workers/Pages-Runtime
|
||||
eingebaut) verhindert, dass jemand sich einfach selbst ein
|
||||
@@ -161,6 +163,21 @@ async function handleVerwaltungAuth(request, env) {
|
||||
return new Response(JSON.stringify({ ok: true, next }), { status: 200, headers });
|
||||
}
|
||||
|
||||
/* Gegenstück zu handleAuth()/handleVerwaltungAuth() oben: löscht ALLE drei Zugangs-Cookies auf
|
||||
einmal (normale 90-Tage-Sitzung, die Rollen-Anzeige dafür, UND die tägliche Verwaltungs-Sitzung)
|
||||
— auf ausdrücklichen Wunsch (04.08.2026) als eigener Abmelde-Button auf /verwaltung/. Löscht
|
||||
bewusst auch die Verwaltungs-Sitzung mit, nicht nur die normale, damit "abmelden" wirklich
|
||||
"abmelden von allem" bedeutet und nicht nur einen Teil der Schranke offen lässt. */
|
||||
function handleLogout() {
|
||||
const headers = new Headers({ "Content-Type": "application/json" });
|
||||
const loeschen = (name, httpOnly) =>
|
||||
`${name}=; Path=/; Max-Age=0; ${httpOnly ? "HttpOnly; " : ""}Secure; SameSite=Lax`;
|
||||
headers.append("Set-Cookie", loeschen(COOKIE_NAME, true));
|
||||
headers.append("Set-Cookie", loeschen(ROLE_COOKIE_NAME, false));
|
||||
headers.append("Set-Cookie", loeschen(VERWALTUNG_COOKIE_NAME, true));
|
||||
return new Response(JSON.stringify({ ok: true }), { status: 200, headers });
|
||||
}
|
||||
|
||||
export async function onRequest(context) {
|
||||
const { request, next, env } = context;
|
||||
const url = new URL(request.url);
|
||||
@@ -170,6 +187,13 @@ export async function onRequest(context) {
|
||||
return next();
|
||||
}
|
||||
|
||||
// Abmelden muss IMMER funktionieren — unabhängig von SITE_PUBLIC, Hostname oder ob die
|
||||
// Sitzung technisch schon abgelaufen/ungültig ist. Deshalb ganz oben geprüft, vor jeder
|
||||
// sonstigen Weiche unten.
|
||||
if (url.pathname === "/gate-logout" && request.method === "POST") {
|
||||
return handleLogout();
|
||||
}
|
||||
|
||||
// Rechtstexte (Impressum, Datenschutz, AGB, Widerruf) bleiben IMMER ohne Zugangscode
|
||||
// erreichbar. Grund: PayPal prüft vor der Freischaltung von "Log in with PayPal" die
|
||||
// angegebene Datenschutz- und AGB-Adresse tatsächlich nach — hinter der Zugangsschranke
|
||||
|
||||
Reference in New Issue
Block a user