Files
claude-projects/wuerth-plato/memory/project_pwa_sw_auth_bypass.md
T

2.9 KiB

name, description, metadata
name description metadata
project-pwa-sw-auth-bypass PWA-Service-Worker muss server-seitige Navigationsrouten (/auth, /oauth, /commands) explizit durchlassen, sonst Login-Loop.
node_type type originSessionId
memory project 73911b5f-10ba-449e-abaf-9db0e509132c

Der Service Worker (apps/plato-customer-fe/vite.config.ts, VitePWA/workbox) fängt per navigateFallback: '/index.html' + runtimeCaching mit request.mode === 'navigate' (StaleWhileRevalidate, cache pages) alle Navigationen ab. Server-seitige Routen, die NICHT zum FE gehören, müssen daher zweifach ausgenommen werden: in navigateFallbackDenylist UND als eigene NetworkOnly-Route (vor der navigate-Regel, erste passende gewinnt). Stand nach Fix ab6933c (2026-05-29): ausgenommen sind /commands, /auth, /oauth.

Why: Vor dem Fix war nur /commands ausgenommen. /auth/login (Navigation via window.location.href in FE main.js:28) wurde vom SW mit der gecachten index.html beantwortet statt zum IdP durchgelassen → Endlos-Loop: boot → /auth/me 401 → /auth/login → index.html → boot. Komplett client-seitig, der Server sah /auth/login nie. Symptom-Fingerabdruck: normales Profil loopt, Incognito beim Erststart sauber (SW kontrolliert erste Navigation noch nicht), nur "Seitendaten löschen" (= SW + Cache weg) heilt. registerType: 'autoUpdate' zieht den neuen SW bei Bestandsclients beim nächsten Laden nach.

Zweiter Loop (Fix 9dd1a29, 2026-06-02): Die navigate-Runtime-Regel hat matchOptions.ignoreSearch: true. Lokal kehrt der IdP NICHT auf /oauth/callback, sondern auf die Root zurück (http://localhost:3000/?code&state — IAM hat lokal nur die Root als redirect_uri registriert, siehe oidc.controller.ts computeRedirectUri). Mit ignoreSearch matcht der Callback den gecachten /-Eintrag → SW liefert die alte index.html → die Root-Middleware in main.ts (verarbeitet ?code&state) läuft nie → Endlos-Loop, auch nach Site-Data-Löschen. Die Denylist (/auth, /oauth) greift NICHT, weil der Pfad / ist. Fix: navigate-urlPattern um && !url.searchParams.has('code') ergänzt → Callback geht ans Netz/den Server. Server-seitig war alles gesund (/auth/login → 302 IdP, /auth/me → 401) — der Bruch saß rein im SW. Diagnose-Fingerabdruck identisch (Profil loopt, Server sieht den Callback nie).

How to apply: Jede NEUE server-seitige Route, die der Browser per Navigation (nicht fetch) erreicht, MUSS in navigateFallbackDenylist UND als NetworkOnly-Route rein — und Callbacks, die auf der Root mit Query landen, zusätzlich aus der navigate-Regel ausnehmen (code-Param), sonst kehrt der Loop zurück. Verifizieren am gebauten Artefakt: grep -o 'searchParams.has("code")' dist/apps/plato-customer-fe/sw.js. FE muss nach Änderung neu gebaut werden (npx nx build plato-customer-fe), Browser einmal SW entregistrieren. Siehe project-run-commands, OIDC-Flow: project-idp-witglobal.