feat(security): "Lock vault when Windows locks or sleeps" toggle (default ON)

Explicit opt-out for users without Quick Unlock who don't want to retype the
master password after every sleep. Default ON = exact historical behavior
(lock on WTS lock/suspend, with the documented Quick Unlock exemption —
DPAPI already gates access via the Windows account). Synced setting,
Settings > Security.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
r-zakarya
2026-07-13 05:17:16 +01:00
parent 8555661823
commit a090c64081
2 changed files with 30 additions and 0 deletions
+17
View File
@@ -86,6 +86,9 @@ const Bridge = (() => {
// re-locking is redundant — we just stay unlocked and the user is
// back where they left off when they return.
onSystemLock() {
// Explicit user opt-out (Settings → Security). Default ON keeps
// the historical behavior below.
if (state.lockOnSystemLock === false) return;
if (state.quickUnlockEnabled) {
if (typeof toast === 'function')
toast('System lock — vault kept unlocked (quick unlock active)');
@@ -650,6 +653,7 @@ const state = {
autofillEnabled: localStorage.getItem('autofillEnabled') !== '0', // default ON
autofillClearField: localStorage.getItem('autofillClearField') !== '0', // default ON
clipboardClearSeconds: parseInt(localStorage.getItem('clipboardClearSeconds') ?? '30', 10), // 0 = never
lockOnSystemLock: localStorage.getItem('lockOnSystemLock') !== '0', // default ON
autofillFailBalloon: localStorage.getItem('autofillFailBalloon') !== '0', // default ON
// Hotkey combos. Each combo = { ctrl, shift, alt, win, key }.
// key is the uppercase character or VK label ('A'..'Z', '0'..'9',
@@ -6398,6 +6402,7 @@ function openSettings() {
$('#settingTrashPurge').value = String(state.trashAutoPurgeDays || 0);
$('#settingPasswordExpiry').value = String(state.passwordExpiryDays || 0);
$('#settingClipboardClear').value = String(state.clipboardClearSeconds ?? 30);
$('#settingLockOnSystemLock').checked = state.lockOnSystemLock !== false;
$('#settingEditorPosition').value = state.editorPosition || 'right';
$('#settingConfirmUnsaved').checked = state.confirmOnUnsaved !== false;
// PIN unlock — only meaningful when DPAPI is available.
@@ -6796,6 +6801,8 @@ const SYNCED_SETTING_KEYS = [
'autofillFailBalloon',
// Seconds before a copied secret is auto-cleared (0 = never). Default 30.
'clipboardClearSeconds',
// Lock the vault when Windows locks / sleeps (default ON).
'lockOnSystemLock',
];
// Sets `data-editor-position` on <body> so CSS can swap the slideover
@@ -6885,6 +6892,9 @@ async function loadServerSettings() {
case 'clipboardClearSeconds':
localStorage.setItem('clipboardClearSeconds', String(v));
break;
case 'lockOnSystemLock':
localStorage.setItem('lockOnSystemLock', v ? '1' : '0');
break;
}
});
// Apply visual settings immediately.
@@ -7586,6 +7596,13 @@ async function init() {
saveServerSettings();
toast(n === 0 ? 'Clipboard auto-clear disabled' : 'Copied secrets clear after ' + n + 's');
});
$('#settingLockOnSystemLock').addEventListener('change', e => {
state.lockOnSystemLock = e.target.checked;
localStorage.setItem('lockOnSystemLock', e.target.checked ? '1' : '0');
saveServerSettings();
toast(e.target.checked ? 'Vault will lock when Windows locks'
: 'Vault stays unlocked when Windows locks');
});
$('#settingPasswordExpiry').addEventListener('change', e => {
const n = parseInt(e.target.value, 10) || 0;
state.passwordExpiryDays = n;