From 125e2fd1966c1820e426d1d204f9f81ffd999f86 Mon Sep 17 00:00:00 2001 From: Eddy Date: Tue, 7 Jul 2026 15:41:37 +0200 Subject: [PATCH] PWA-Login: Fingerabdruck-/Passkey-Anmeldung (WebAuthn) [deploy] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Zweiter, gleichwertiger Login-Weg neben Passwort — nutzt die zentrale awlauth-WebAuthn-JS (/custom/awlauth/js/awlauth-webauthn.js), analog zum Stundenzettel-Pilot. - Script-Einbindung nach app.js in index.php (same-origin, /custom/awlauth). - Neuer Button "Mit Fingerabdruck anmelden" im Login-Template (app.js), type="button", versteckt bis awlauthWebAuthn.isSupported() true ist. - Klick-Handler: awlauthWebAuthn.login() -> bei Erfolg Profil aus dem Login-Result in idb('user') ablegen (wie api.login es tut, sonst zeigt Einstellungen nach reinem Passkey-Login "Unbekannt") -> showToast + router.go('#/orders') wie der Passwort-Login-Pfad. - Passkey ist domainweit (RP awl.data-it-solution.de): ein z.B. ueber Stundenzettel registrierter Passkey funktioniert hier direkt mit. Lokal verifiziert: php -l / node --check sauber, Playwright + Virtual- Authenticator (CDP) — Button korrekt sichtbar/gestylt (eigene Dark-Palette), Klick loest webauthn_login_options.php (200) aus, Fehlerpfad reaktiviert den Button, bleibt auf #/login, 0 Console-Errors. Adversarialer Code-Review fand 1 kosmetischen Befund (fehlendes idb-Profil) — bereits gefixt. Co-Authored-By: Claude Opus 4.8 (1M context) --- app.js | 27 +++++++++++++++++++++++++++ index.php | 3 +++ 2 files changed, 30 insertions(+) diff --git a/app.js b/app.js index f564f01..004be16 100644 --- a/app.js +++ b/app.js @@ -352,6 +352,10 @@ router.on('/login', async () => { + `; const _blPass = document.getElementById('bl-pass'); @@ -372,6 +376,29 @@ router.on('/login', async () => { showToast(err.message, 'error'); } }); + + // WebAuthn / Passkey (Fingerabdruck) — nur wenn der Browser es kann. + // Der Passkey gilt domainweit (RP awl.data-it-solution.de): ein auf dem + // Handy registrierter Passkey loggt hier ohne Benutzername/Passwort ein. + const _pk = document.getElementById('bl-passkey'); + if (_pk && window.awlauthWebAuthn && awlauthWebAuthn.isSupported()) { + _pk.style.display = 'flex'; + _pk.addEventListener('click', async () => { + _pk.disabled = true; + try { + const res = await awlauthWebAuthn.login(); + // Profil wie beim Passwort-Login ablegen (Einstellungen liest idb 'user'), + // sonst zeigt der Konto-Block nach reinem Passkey-Login 'Unbekannt'. + if (res && res.user) { await idb.set('user', res.user); } + // awl_sso ist gesetzt -> Orders-Route rendert und faehrt ensureAuth()/verify.php + showToast('Erfolgreich angemeldet'); + router.go('#/orders'); + } catch (err) { + _pk.disabled = false; + showToast(err && err.message ? err.message : 'Anmeldung fehlgeschlagen', 'error'); + } + }); + } }); router.on('/today', async () => { diff --git a/index.php b/index.php index 1607d5f..b457e9b 100644 --- a/index.php +++ b/index.php @@ -83,6 +83,9 @@ if (typeof pdfjs !== 'undefined') { + + +