fix(unlock): persist unlockMode in DPAPI so a cold start still asks for the PIN

unlockMode lived only in localStorage, wiped on every launch since the ephemeral port changes the origin, and in settings_json, which needs a session to read. The auth screen therefore always fell back to the master password on a cold start even though the PIN blob was there. Mirror it to a DPAPI pref and read it back in showAuth, like rememberedUsername.
This commit is contained in:
r-zakarya
2026-07-28 22:50:28 +01:00
parent 52af21f917
commit 67107fba37
2 changed files with 26 additions and 0 deletions
+19
View File
@@ -6584,6 +6584,18 @@ async function showAuth() {
// user may have set/removed it from another instance, and we want
// the correct fields to show up without forcing a full reload.
state.pinConfigured = await bridgePinStatus();
// unlockMode lives in settings_json (needs a session) and in localStorage
// (wiped every launch — the port changes, so the origin does too). Neither
// is readable here, on a cold start before any login, so the DPAPI copy is
// the only one that survives: without it a PIN-only vault always came back
// asking for the master password.
if (Bridge.active) {
const savedMode = await Bridge.getPref('unlockMode');
if (savedMode === 'pw' || savedMode === 'pin' || savedMode === 'both') {
state.unlockMode = savedMode;
localStorage.setItem('unlockMode', savedMode);
}
}
applyAuthScreenMode();
// Clear residual PIN input from a previous attempt.
const pinInput = document.getElementById('loginPin');
@@ -6845,6 +6857,9 @@ async function loadServerSettings() {
break;
case 'unlockMode':
localStorage.setItem('unlockMode', String(v || 'pw'));
// Mirror to DPAPI so the next cold start's auth screen knows
// which method to offer, before any login can read settings.
if (Bridge.active) Bridge.setPref('unlockMode', String(v || 'pw'));
break;
case 'autofillClearField':
localStorage.setItem('autofillClearField', v ? '1' : '0');
@@ -7596,6 +7611,10 @@ async function init() {
}
state.unlockMode = next;
localStorage.setItem('unlockMode', next);
// Also DPAPI: the auth screen needs this BEFORE any login, and
// localStorage is wiped on every launch (ephemeral port = new origin),
// while settings_json requires being signed in to read.
if (Bridge.active) Bridge.setPref('unlockMode', next);
saveServerSettings();
toast('Unlock method updated');
});