From c890636f03ded1aca53f5d02de90d6e5e376dab8 Mon Sep 17 00:00:00 2001 From: Andrew Zambazos Date: Mon, 16 Feb 2026 11:50:07 +1300 Subject: [PATCH] Fix passkey length and add reset action Introduce a single PASSKEY_LENGTH constant (6) and enforce it across passkey config/load/save/update, removing the previous user-adjustable length/clamping. Add resetSequence() to clear stored hash/salt, reset length/attempts/lockout and persist the cleared state. Update settings UI: relabel "Change Passkey" to "Reset Passkey", show "6 digits" and "Fixed for testing", remove length adjustment controls/handlers, and call state.passkey.resetSequence() when resetting so setup will run on next lock. --- src/core/passkey.js | 19 +++++++++++++++---- src/views/settings/settings.js | 23 +++++------------------ 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/core/passkey.js b/src/core/passkey.js index 8bebaee..5ea3c34 100644 --- a/src/core/passkey.js +++ b/src/core/passkey.js @@ -1,11 +1,12 @@ const PASSKEY_STORAGE_KEY = "nebula.passkey.v1"; const PASSKEY_VERSION = 1; +const PASSKEY_LENGTH = 6; const clamp = (value, min, max) => Math.max(min, Math.min(max, value)); const FALLBACK_CONFIG = { enabled: true, - length: 6, + length: PASSKEY_LENGTH, requireConfirm: false, keyboardSupport: true, maxAttempts: 5, @@ -49,7 +50,7 @@ export const loadPasskeyConfig = () => { return { ...FALLBACK_CONFIG, ...parsed, - length: clamp(Number(parsed.length ?? FALLBACK_CONFIG.length), 4, 8), + length: PASSKEY_LENGTH, maxAttempts: clamp(Number(parsed.maxAttempts ?? FALLBACK_CONFIG.maxAttempts), 1, 10), cooldownSeconds: clamp(Number(parsed.cooldownSeconds ?? FALLBACK_CONFIG.cooldownSeconds), 5, 120), requireConfirm: Boolean(parsed.requireConfirm ?? FALLBACK_CONFIG.requireConfirm), @@ -76,7 +77,7 @@ export const savePasskeyConfig = (config) => { ...FALLBACK_CONFIG, ...config, version: PASSKEY_VERSION, - length: clamp(Number(config.length ?? FALLBACK_CONFIG.length), 4, 8), + length: PASSKEY_LENGTH, maxAttempts: clamp(Number(config.maxAttempts ?? FALLBACK_CONFIG.maxAttempts), 1, 10), cooldownSeconds: clamp(Number(config.cooldownSeconds ?? FALLBACK_CONFIG.cooldownSeconds), 5, 120), }; @@ -150,13 +151,22 @@ export const createPasskeyController = () => { const updateConfig = (partial) => { Object.assign(config, partial); - config.length = clamp(Number(config.length), 4, 8); + config.length = PASSKEY_LENGTH; config.maxAttempts = clamp(Number(config.maxAttempts), 1, 10); config.cooldownSeconds = clamp(Number(config.cooldownSeconds), 5, 120); persist(); return { ...config }; }; + const resetSequence = () => { + config.hash = ""; + config.salt = ""; + config.length = PASSKEY_LENGTH; + failedAttempts = 0; + lockoutUntil = 0; + persist(); + }; + const getConfig = () => ({ ...config }); return { @@ -164,6 +174,7 @@ export const createPasskeyController = () => { updateConfig, verifySequence, setSequence, + resetSequence, inLockout, getLockoutRemainingMs, hasPasskey: () => Boolean(config.hash && config.salt), diff --git a/src/views/settings/settings.js b/src/views/settings/settings.js index 25e4094..1be1101 100644 --- a/src/views/settings/settings.js +++ b/src/views/settings/settings.js @@ -36,13 +36,13 @@ const SETTINGS_TEMPLATE = `

Enabled