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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user