From bb985ddc8fd0017425b2c628b097180e8132e9b3 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Wed, 7 Jan 2026 21:30:13 +0100 Subject: [PATCH] Improve passkey registration error handling and options serialization Enhance the registration process by adding error handling for the WebAuthn startRegistration method and ensuring the presence of required options. Include debug logging for received options and serialize the options correctly before returning them in the API response, improving robustness and clarity in the registration flow. --- pages/registrieren.vue | 19 ++++++++++++++++--- .../api/auth/register-passkey-options.post.js | 18 ++++++++++++++++-- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/pages/registrieren.vue b/pages/registrieren.vue index 70e2bf2..489ceb1 100644 --- a/pages/registrieren.vue +++ b/pages/registrieren.vue @@ -339,15 +339,28 @@ const handleRegisterWithPasskey = async () => { } // Debug: Prüfe Options-Struktur - if (!pre.options.challenge) { + console.log('Received options:', { + hasChallenge: !!pre.options?.challenge, + hasRp: !!pre.options?.rp, + hasUser: !!pre.options?.user, + timeout: pre.options?.timeout + }) + + if (!pre.options || !pre.options.challenge) { console.error('Options fehlen challenge:', pre.options) throw new Error('Ungültige WebAuthn-Options vom Server') } const mod = await import('@simplewebauthn/browser') - // startRegistration erwartet die Options direkt, nicht verschachtelt + // startRegistration erwartet die Options direkt // @simplewebauthn/browser v13+ erwartet die Options direkt - const credential = await mod.startRegistration(pre.options) + let credential + try { + credential = await mod.startRegistration(pre.options) + } catch (webauthnError) { + console.error('WebAuthn startRegistration error:', webauthnError) + throw new Error('Passkey-Registrierung fehlgeschlagen: ' + (webauthnError?.message || 'Unbekannter Fehler')) + } const response = await $fetch('/api/auth/register-passkey', { method: 'POST', diff --git a/server/api/auth/register-passkey-options.post.js b/server/api/auth/register-passkey-options.post.js index f464f92..efe653f 100644 --- a/server/api/auth/register-passkey-options.post.js +++ b/server/api/auth/register-passkey-options.post.js @@ -75,9 +75,23 @@ export default defineEventHandler(async (event) => { hasChallenge: !!options.challenge, rpId: options.rp?.id, userId: options.user?.id ? 'present' : 'missing', - timeout: options.timeout + timeout: options.timeout, + challengeType: typeof options.challenge }) - return { success: true, registrationId, options } + // Stelle sicher, dass die Options korrekt serialisiert werden + // @simplewebauthn/server gibt ein Objekt zurück, das direkt JSON-serialisierbar ist + // Aber wir müssen sicherstellen, dass alle Properties vorhanden sind + const serializedOptions = { + ...options, + challenge: options.challenge, + rp: options.rp, + user: options.user, + pubKeyCredParams: options.pubKeyCredParams, + authenticatorSelection: options.authenticatorSelection, + timeout: options.timeout || 300000 + } + + return { success: true, registrationId, options: serializedOptions } })