fix: Passkey-Sign Challenge und Signatur-Moduswechsel

WebAuthn-Challenge wird als Bytes übergeben und unter options.challenge
gespeichert. Passkey/Klassisch-Toggle erlaubt Wechsel zwischen Freigabearten.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-29 16:40:01 +02:00
parent ce47fe5fdc
commit 878a18e9f7
5 changed files with 231 additions and 74 deletions
+13 -10
View File
@@ -150,12 +150,22 @@ router.post('/options', async (req: any, res) => {
const nonce = crypto.randomBytes(16).toString('hex')
const challengePayload = `${entryId}:${entryHash}:${role}:${nonce}`
const derivedChallenge = crypto
const challengeBytes = crypto
.createHash('sha256')
.update(challengePayload)
.digest('base64url')
.digest()
signingChallenges.set(derivedChallenge, {
const options = await generateAuthenticationOptions({
rpID,
challenge: challengeBytes,
allowCredentials,
userVerification: 'required'
})
// Must key by options.challenge — the base64url value returned to the client.
// Passing a string challenge would be UTF-8 re-encoded by simplewebauthn, so the
// client challenge would not match a map key derived from our pre-encoded string.
signingChallenges.set(options.challenge, {
userId: req.userId,
logbookId,
entryId,
@@ -164,13 +174,6 @@ router.post('/options', async (req: any, res) => {
expiresAt: Date.now() + CHALLENGE_TTL_MS
})
const options = await generateAuthenticationOptions({
rpID,
challenge: derivedChallenge,
allowCredentials,
userVerification: 'required'
})
return res.json(options)
} catch (error: any) {
console.error('Error generating sign options:', error)