fix: WebAuthn PRF salt length and server logbook key storage

This commit is contained in:
2026-05-29 08:46:50 +02:00
parent abfaf3e99c
commit 128dd17863
2 changed files with 21 additions and 11 deletions
+16 -9
View File
@@ -45,7 +45,7 @@ export function setActiveMasterKey(key: ArrayBuffer | null) {
} }
// Convert string salt to 32-byte Uint8Array // Convert string salt to 32-byte Uint8Array
const PRF_SALT = new TextEncoder().encode("KapteinsDaagboxPRFSaltForE2EKey") const PRF_SALT = new TextEncoder().encode("KapteinsDaagboxPRFSaltForE2EKey_")
export interface RegistrationResult { export interface RegistrationResult {
verified: boolean verified: boolean
@@ -88,7 +88,11 @@ export async function registerUser(username: string): Promise<RegistrationResult
let encryptedMasterKeyPrfIv = null let encryptedMasterKeyPrfIv = null
let encryptedMasterKeyPrfTag = null let encryptedMasterKeyPrfTag = null
const prfResults = (credentialResponse as any).clientExtensionResults?.prf console.log('Registration credential response:', credentialResponse)
const clientExtensionResults = credentialResponse.clientExtensionResults || {}
console.log('Registration client extension results:', clientExtensionResults)
const prfResults = (clientExtensionResults as any).prf
console.log('Registration PRF extension result:', prfResults)
if (prfResults?.enabled && prfResults.results?.first) { if (prfResults?.enabled && prfResults.results?.first) {
const prfKey = await deriveKeyFromPrf(prfResults.results.first) const prfKey = await deriveKeyFromPrf(prfResults.results.first)
@@ -152,13 +156,16 @@ export interface LoginResult {
} }
export async function loginUser(username?: string): Promise<LoginResult> { export async function loginUser(username?: string): Promise<LoginResult> {
// Log browser supported extensions to diagnose PRF availability // Log browser WebAuthn capabilities to diagnose PRF availability
console.log( if (window.PublicKeyCredential && (window.PublicKeyCredential as any).getClientCapabilities) {
'Browser supported WebAuthn extensions:', (window.PublicKeyCredential as any).getClientCapabilities().then((caps: any) => {
window.PublicKeyCredential && (window.PublicKeyCredential as any).getClientExtensionResults console.log('Browser WebAuthn client capabilities:', caps)
? (window.PublicKeyCredential as any).getClientExtensionResults() }).catch((err: any) => {
: 'none' console.warn('Error reading WebAuthn client capabilities:', err)
) })
} else {
console.log('window.PublicKeyCredential.getClientCapabilities is not supported.')
}
// 1. Get authentication options // 1. Get authentication options
const optionsRes = await fetch(`${API_BASE}/login-options`, { const optionsRes = await fetch(`${API_BASE}/login-options`, {
+5 -2
View File
@@ -46,7 +46,7 @@ router.get('/', async (req: any, res) => {
// 2. Create a new logbook // 2. Create a new logbook
router.post('/', async (req: any, res) => { router.post('/', async (req: any, res) => {
try { try {
const { id, encryptedTitle } = req.body const { id, encryptedTitle, encryptedKey, iv, tag } = req.body
if (!encryptedTitle) { if (!encryptedTitle) {
return res.status(400).json({ error: 'encryptedTitle is required' }) return res.status(400).json({ error: 'encryptedTitle is required' })
} }
@@ -55,7 +55,10 @@ router.post('/', async (req: any, res) => {
data: { data: {
id: id || undefined, id: id || undefined,
userId: req.userId, userId: req.userId,
encryptedTitle encryptedTitle,
encryptedKey,
iv,
tag
} }
}) })