Eigene Zugangscode-Schranke statt Cloudflare Access — löst VanVans Login-Problem

Ersetzt die (fehlerhaft auf die GANZE Domain wirkende) Cloudflare-Zero-
Trust-Access-Sperre durch eine eigene, schlanke Lösung nach dem bewährten
Vorbild von "Dogfather Universe": eine Pages-Functions-Middleware
(functions/_middleware.js) prüft bei jeder Anfrage ein HMAC-signiertes
Session-Cookie; ohne gültiges Cookie geht's zu public/gate.html (im Van's-
Design), wo ein Zugangscode eingegeben wird. Zwei getrennte Codes für qciga
und VanVan, 90 Tage gültig, danach neu eingeben. /admin/* ist komplett
ausgenommen — läuft weiter über das echte GitHub-OAuth-Login, das für
VanVan schon funktioniert.

Bonus: die drei separaten Vorschau-Seiten (demo-normal/demo-konto/demo-abo)
sind jetzt überflüssig und entfernt. Stattdessen gibt's ein schwebendes
Umschalter-Widget (Layout.astro), das NUR sichtbar ist, wenn das Gate-Cookie
vorhanden ist (also nur für uns beide) — auf jeder beliebigen Seite kann
per Knopfdruck zwischen "Normaler Besucher", "Angemeldete Kundin" und
"Abonnentin" gewechselt werden, ohne die Seite verlassen zu müssen.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
qcigano
2026-08-03 18:55:44 +02:00
co-authored by Claude Sonnet 5
parent 6b1920dfb3
commit ad07584906
9 changed files with 502 additions and 161 deletions
+48
View File
@@ -2632,3 +2632,51 @@ a:focus-visible, button:focus-visible {
.abo-notif-body { display: flex; flex-direction: column; gap: 0.15rem; }
.abo-notif-date { color: var(--c-text-muted); }
@media (prefers-reduced-motion: reduce) { .abo-plan-card, .abo-plan-card.is-current-plan, .abo-reward-ready { animation: none; transition: none; } }
/* Vorschau-Umschalter (nur für qciga/vanvan sichtbar, siehe Layout.astro) — schwebt rechts unten
über jeder Seite, damit man ohne Seitenwechsel zwischen normalem Besucher/angemeldeter Kundin/
Abonnentin hin- und herschalten kann. */
#vandiy-preview-switcher { position: fixed; right: 1.2rem; bottom: 1.2rem; z-index: 200; }
#vandiy-preview-toggle {
width: 52px;
height: 52px;
border-radius: 50%;
border: 1.5px solid transparent;
background:
linear-gradient(155deg, var(--c-anthracite-light), var(--c-anthracite)) padding-box,
linear-gradient(120deg, #9b7fd6, var(--c-accent), #e3b23c) border-box;
font-size: 1.4rem;
cursor: pointer;
box-shadow: 0 10px 26px -10px rgba(0, 0, 0, 0.7);
transition: transform 0.2s var(--ease);
}
#vandiy-preview-toggle:hover { transform: scale(1.08); }
#vandiy-preview-panel {
display: none;
position: absolute;
right: 0;
bottom: calc(100% + 0.7rem);
min-width: 240px;
padding: 0.8rem;
border-radius: var(--radius-m);
background: var(--c-anthracite-light);
border: 1px solid rgba(244, 241, 247, 0.14);
box-shadow: var(--shadow-card);
flex-direction: column;
gap: 0.4rem;
}
#vandiy-preview-panel.open { display: flex; }
#vandiy-preview-current { margin: 0 0 0.3rem; color: var(--c-text-muted); }
#vandiy-preview-panel button[data-preview] {
text-align: left;
padding: 0.55em 0.7em;
border-radius: var(--radius-s);
border: 1px solid rgba(244, 241, 247, 0.12);
background: rgba(244, 241, 247, 0.04);
color: var(--c-text);
font-size: 0.88rem;
cursor: pointer;
transition: background 0.15s var(--ease);
}
#vandiy-preview-panel button[data-preview]:hover { background: color-mix(in srgb, var(--c-accent) 14%, transparent); }
@media (max-width: 500px) { #vandiy-preview-switcher { right: 0.7rem; bottom: 0.7rem; } }