Enhance debug logging and validation for Passkey Registration
Some checks failed
Code Analysis (JS/Vue) / analyze (push) Failing after 51s

Add comprehensive debug statements in the registrieren.vue component to validate the options structure and ensure the challenge format is correct before initiating registration. Update the register-passkey API to log additional request details, including client IP and user-agent analysis, to improve troubleshooting and provide better insights during the registration process.
This commit is contained in:
Torsten Schulz (local)
2026-01-08 12:12:15 +01:00
parent 750c05eac1
commit a763c959ef
2 changed files with 32 additions and 2 deletions

View File

@@ -537,7 +537,27 @@ const handleRegisterWithPasskey = async () => {
console.log('[DEBUG] 4. Smartphone sendet Credential-Response an:', window.location.origin + '/api/auth/register-passkey') console.log('[DEBUG] 4. Smartphone sendet Credential-Response an:', window.location.origin + '/api/auth/register-passkey')
console.log('[DEBUG] 5. Server verifiziert die Response') console.log('[DEBUG] 5. Server verifiziert die Response')
// Prüfe Options-Struktur vor dem Aufruf
console.log('[DEBUG] Options validation before startRegistration:', {
hasChallenge: !!pre.options.challenge,
challengeType: typeof pre.options.challenge,
hasRp: !!pre.options.rp,
hasRpId: !!pre.options.rp?.id,
hasUser: !!pre.options.user,
hasUserID: !!pre.options.user?.id,
timeout: pre.options.timeout,
timeoutType: typeof pre.options.timeout,
allKeys: Object.keys(pre.options)
})
// Stelle sicher, dass challenge ein String ist (nicht Base64URL-encoded)
if (typeof pre.options.challenge !== 'string') {
console.error('[DEBUG] ERROR: Challenge is not a string!', pre.options.challenge)
throw new Error('Invalid challenge format')
}
// Direkt die Options übergeben (wie in profil.vue und passkey-wiederherstellen.vue) // Direkt die Options übergeben (wie in profil.vue und passkey-wiederherstellen.vue)
// @simplewebauthn/browser v13+ erwartet die Options direkt
credential = await mod.startRegistration(pre.options) credential = await mod.startRegistration(pre.options)
clearTimeout(timeoutWarning) clearTimeout(timeoutWarning)

View File

@@ -7,6 +7,7 @@ import { consumePreRegistration } from '../../utils/webauthn-challenges.js'
import { toBase64Url } from '../../utils/webauthn-encoding.js' import { toBase64Url } from '../../utils/webauthn-encoding.js'
import { writeAuditLog } from '../../utils/audit-log.js' import { writeAuditLog } from '../../utils/audit-log.js'
import { assertPasswordNotPwned } from '../../utils/hibp.js' import { assertPasswordNotPwned } from '../../utils/hibp.js'
import { getClientIp } from '../../utils/rate-limit.js'
export default defineEventHandler(async (event) => { export default defineEventHandler(async (event) => {
const requestStart = Date.now() const requestStart = Date.now()
@@ -14,14 +15,23 @@ export default defineEventHandler(async (event) => {
const userAgent = getHeader(event, 'user-agent') const userAgent = getHeader(event, 'user-agent')
const { origin: webauthnOrigin } = getWebAuthnConfig() const { origin: webauthnOrigin } = getWebAuthnConfig()
console.log('[DEBUG] register-passkey request received', { console.log('[DEBUG] ===== register-passkey request received =====')
console.log('[DEBUG] Request Details:', {
origin: requestOrigin, origin: requestOrigin,
webauthnOrigin, webauthnOrigin,
userAgent: userAgent?.substring(0, 100), userAgent: userAgent?.substring(0, 150),
timestamp: new Date().toISOString(), timestamp: new Date().toISOString(),
method: getMethod(event), method: getMethod(event),
ip: getClientIp(event),
note: 'Dieser Request sollte vom Smartphone kommen, wenn der QR-Code gescannt wurde' note: 'Dieser Request sollte vom Smartphone kommen, wenn der QR-Code gescannt wurde'
}) })
console.log('[DEBUG] User-Agent Analysis:', {
isMobile: /Mobile|Android|iPhone|iPad/i.test(userAgent || ''),
isChrome: /Chrome/i.test(userAgent || ''),
isSafari: /Safari/i.test(userAgent || '') && !/Chrome/i.test(userAgent || ''),
isFirefox: /Firefox/i.test(userAgent || ''),
fullUserAgent: userAgent
})
// CORS-Header für Cross-Device Authentication // CORS-Header für Cross-Device Authentication
// OPTIONS-Requests werden von .options.js behandelt // OPTIONS-Requests werden von .options.js behandelt