Enhance logging for mobile requests in log-requests middleware
Some checks failed
Code Analysis (JS/Vue) / analyze (push) Failing after 44s

Add functionality to log all requests from mobile devices, improving debugging capabilities. Extend the existing passkey endpoint checks to include a new endpoint for cross-device registration. This update aims to provide clearer insights into mobile user interactions with the application.
This commit is contained in:
Torsten Schulz (local)
2026-01-08 23:42:16 +01:00
parent e0c41b76c3
commit e1c555e99f
2 changed files with 153 additions and 3 deletions

View File

@@ -0,0 +1,142 @@
<template>
<div class="min-h-screen bg-gray-900 text-white flex items-center justify-center p-4">
<div class="max-w-md w-full bg-gray-800 rounded-lg p-6 space-y-4">
<h1 class="text-2xl font-bold text-center">Passkey-Registrierung</h1>
<div v-if="status === 'loading'" class="text-center">
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-white mx-auto mb-4"></div>
<p>Lade Registrierungsoptionen...</p>
</div>
<div v-else-if="status === 'waiting'" class="text-center">
<div class="animate-pulse text-4xl mb-4">🔐</div>
<p class="text-lg mb-2">Warte auf Passkey-Authentifizierung...</p>
<p class="text-sm text-gray-400">Bitte bestätigen Sie die Registrierung auf diesem Gerät.</p>
</div>
<div v-else-if="status === 'error'" class="text-center text-red-400">
<p class="text-lg font-semibold mb-2">Fehler</p>
<p>{{ errorMessage }}</p>
<button
@click="retry"
class="mt-4 px-4 py-2 bg-primary-600 hover:bg-primary-700 rounded"
>
Erneut versuchen
</button>
</div>
<div v-else-if="status === 'success'" class="text-center text-green-400">
<p class="text-lg font-semibold mb-2"> Erfolgreich!</p>
<p>Die Credential-Response wurde an den Desktop-Browser gesendet.</p>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const status = ref('loading')
const errorMessage = ref('')
const registrationId = ref('')
// Hole registrationId aus URL-Parameter
onMounted(async () => {
const route = useRoute()
registrationId.value = route.query.registrationId || ''
if (!registrationId.value) {
status.value = 'error'
errorMessage.value = 'Keine registrationId in der URL gefunden.'
return
}
await startRegistration()
})
async function startRegistration() {
try {
status.value = 'loading'
// Hole Options vom Server
console.log('[DEBUG] Fetching options for registrationId:', registrationId.value)
const optionsResponse = await fetch(`/api/auth/register-passkey-options/${registrationId.value}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
})
if (!optionsResponse.ok) {
throw new Error(`Options request failed: ${optionsResponse.status}`)
}
const optionsData = await optionsResponse.json()
if (!optionsData.success || !optionsData.options) {
throw new Error('Invalid options response')
}
console.log('[DEBUG] Options received:', {
hasChallenge: !!optionsData.options.challenge,
rpId: optionsData.options.rp?.id,
timeout: optionsData.options.timeout
})
// Importiere @simplewebauthn/browser
const mod = await import('@simplewebauthn/browser')
if (!mod.startRegistration) {
throw new Error('startRegistration ist nicht verfügbar')
}
status.value = 'waiting'
console.log('[DEBUG] Calling startRegistration on smartphone...')
// Rufe startRegistration auf
const credential = await mod.startRegistration({ optionsJSON: optionsData.options })
console.log('[DEBUG] Credential received:', {
id: credential.id,
type: credential.type
})
// Sende Credential-Response an den Server
const verifyResponse = await fetch('/api/auth/register-passkey', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
registrationId: registrationId.value,
credential
})
})
if (!verifyResponse.ok) {
const errorData = await verifyResponse.json().catch(() => ({}))
throw new Error(errorData.message || `Verification failed: ${verifyResponse.status}`)
}
const verifyData = await verifyResponse.json()
if (verifyData.success) {
status.value = 'success'
console.log('[DEBUG] Registration successful!')
} else {
throw new Error(verifyData.message || 'Registrierung fehlgeschlagen')
}
} catch (error) {
console.error('[DEBUG] Registration error:', error)
status.value = 'error'
errorMessage.value = error.message || 'Unbekannter Fehler'
}
}
function retry() {
status.value = 'loading'
startRegistration()
}
</script>

View File

@@ -19,14 +19,16 @@ export default defineEventHandler((event) => {
'/api/auth/passkeys/register',
'/api/auth/passkeys/authentication-options',
'/api/auth/passkeys/login',
'/api/auth/passkeys/recovery'
'/api/auth/passkeys/recovery',
'/passkey-register-cross-device'
]
const isPasskeyEndpoint = passkeyEndpoints.some(ep => path.startsWith(ep))
// Logge auch alle Requests vom Smartphone (Mobile User-Agent)
const isMobile = /Mobile|Android|iPhone|iPad/i.test(userAgent || '')
const isPasskeyEndpoint = passkeyEndpoints.some(ep => path.startsWith(ep)) || (isMobile && path.startsWith('/'))
if (isPasskeyEndpoint) {
const timestamp = new Date().toISOString()
const isMobile = /Mobile|Android|iPhone|iPad/i.test(userAgent || '')
console.log('')
console.log('─'.repeat(80))
@@ -51,6 +53,12 @@ export default defineEventHandler((event) => {
console.log(`[REQUEST] ⚠️ Wenn dieser Request vom Smartphone kommt, sollte der User-Agent Mobile/Android/iPhone enthalten`)
}
// Logge alle Requests vom Smartphone (für Debugging)
if (isMobile && path.startsWith('/') && !path.startsWith('/_nuxt') && !path.startsWith('/api')) {
console.log(`[REQUEST] 📱 SMARTPHONE REQUEST - ${path}`)
console.log(`[REQUEST] ⚠️ Wenn das Smartphone die Website öffnet, sollten hier Requests erscheinen`)
}
console.log('─'.repeat(80))
console.log('')
}