From 994aabfb858287d06d757f4597bc0b1df8d40c54 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Wed, 7 Jan 2026 22:01:28 +0100 Subject: [PATCH] Enhance WebAuthn origin handling and debug logging for passkey registration Refine the WebAuthn configuration to ensure that HTTPS origins do not include ports, improving compliance with standards. Add additional debug logging in the passkey registration process to verify the webauthnOrigin and provide guidance for configuration issues, aiding in troubleshooting and enhancing the clarity of the registration flow. --- .../api/auth/register-passkey-options.post.js | 10 +++++- server/utils/webauthn-config.js | 35 +++++++++++++------ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/server/api/auth/register-passkey-options.post.js b/server/api/auth/register-passkey-options.post.js index c68cd89..117ecd1 100644 --- a/server/api/auth/register-passkey-options.post.js +++ b/server/api/auth/register-passkey-options.post.js @@ -53,8 +53,16 @@ export default defineEventHandler(async (event) => { rpId, rpName, webauthnOrigin, - requestOrigin + requestOrigin, + webauthnOriginEnv: process.env.WEBAUTHN_ORIGIN, + baseUrlEnv: process.env.NUXT_PUBLIC_BASE_URL }) + + // WICHTIG: Sicherstellen, dass die Origin KEINEN Port hat + if (webauthnOrigin.includes(':3100')) { + console.error('[DEBUG] ERROR: webauthnOrigin contains port 3100! This will cause verification to fail.') + console.error('[DEBUG] Fix: Set WEBAUTHN_ORIGIN=https://harheimertc.tsschulz.de (without port) in .env') + } const userId = crypto.randomUUID() const registrationId = crypto.randomBytes(16).toString('hex') diff --git a/server/utils/webauthn-config.js b/server/utils/webauthn-config.js index 93d9128..967278c 100644 --- a/server/utils/webauthn-config.js +++ b/server/utils/webauthn-config.js @@ -2,12 +2,20 @@ function deriveFromBaseUrl() { const base = process.env.NUXT_PUBLIC_BASE_URL || 'http://localhost:3100' try { const u = new URL(base) - // Für HTTPS (Port 443) den Port weglassen, da er standardmäßig ist - // Für andere Ports (z.B. Dev auf 3100) den Port beibehalten - const port = u.port && u.port !== '443' && u.port !== '80' ? `:${u.port}` : '' - const origin = u.protocol === 'https:' && !port - ? `${u.protocol}//${u.hostname}` - : `${u.protocol}//${u.hostname}${port}` + // Für HTTPS (Port 443) den Port IMMER weglassen, da er standardmäßig ist + // Für HTTP in Production sollte auch Port 80 weggelassen werden + // Nur für Development (localhost mit Port) den Port beibehalten + let origin + if (u.protocol === 'https:') { + // HTTPS: Port immer weglassen (443 ist Standard) + origin = `https://${u.hostname}` + } else if (u.protocol === 'http:' && u.hostname === 'localhost') { + // Development: Port beibehalten + origin = `${u.protocol}//${u.host}` + } else { + // HTTP Production: Port 80 weglassen + origin = u.port === '80' ? `http://${u.hostname}` : `${u.protocol}//${u.host}` + } return { origin, @@ -23,15 +31,19 @@ export function getWebAuthnConfig() { const rpId = process.env.WEBAUTHN_RP_ID || derived.rpId const rpName = process.env.WEBAUTHN_RP_NAME || 'Harheimer TC' + // WEBAUTHN_ORIGIN hat Priorität, sonst von BASE_URL ableiten - // WICHTIG: Origin sollte KEINEN Port enthalten für HTTPS (443 ist Standard) let origin = process.env.WEBAUTHN_ORIGIN || derived.origin - // Sicherstellen, dass HTTPS-Origins keinen Port haben (außer es ist explizit gesetzt) - if (origin.startsWith('https://') && !process.env.WEBAUTHN_ORIGIN) { + // Sicherstellen, dass HTTPS-Origins KEINEN Port haben (auch wenn in ENV gesetzt) + if (origin.startsWith('https://')) { try { const u = new URL(origin) - if (u.port === '443' || (!u.port && u.protocol === 'https:')) { + // Port 443 oder kein Port = Standard, also Port weglassen + if (u.port === '443' || !u.port) { + origin = `https://${u.hostname}` + } else { + // Auch andere Ports bei HTTPS entfernen (nicht Standard für WebAuthn) origin = `https://${u.hostname}` } } catch { @@ -47,7 +59,8 @@ export function getWebAuthnConfig() { origin, requireUV, webauthnOriginEnv: process.env.WEBAUTHN_ORIGIN, - baseUrlEnv: process.env.NUXT_PUBLIC_BASE_URL + baseUrlEnv: process.env.NUXT_PUBLIC_BASE_URL, + derivedOrigin: derived.origin }) return { rpId, rpName, origin, requireUV }