diag(lock): chaque verrouillage retient sa raison, et l'autofill la dit

Apres un demarrage en tray, une connexion reussie puis un remplissage
repondait "Vault is locked" sans rien dire de plus. Chaque lockVault() porte
desormais sa cause (inactivite, session Windows verrouillee ou en veille, menu
du tray, PIN faux, geste manuel) avec l'heure ; sans verrouillage connu, le
message donne l'heure de chargement de la page - ce qui trahit une page
rechargee entre la connexion et le remplissage.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
r-zakarya
2026-10-02 21:47:17 +01:00
parent 247771bfec
commit bcbbcebe16
3 changed files with 22 additions and 7 deletions
+8 -1
View File
@@ -268,7 +268,14 @@ async function autofillHandleRequest(windowTitle, kind) {
else pwd.focus();
}
}, 80);
toast('Vault is locked — unlock to autofill', 'warning');
// LA RAISON AVEC LE MESSAGE. Sans dernier verrouillage connu, c'est que
// cette page n'a jamais ete deverrouillee - rechargee entre-temps, ou
// jamais ouverte : l'heure de chargement le tranche.
toast('Vault is locked — unlock to autofill ('
+ (state.lastLockReason
? 'locked by: ' + state.lastLockReason
: 'never unlocked since the page loaded at ' + state.pageLoadedAt)
+ ')', 'warning');
return;
}
+12 -4
View File
@@ -95,7 +95,8 @@ const Bridge = (() => {
toast('System lock — vault kept unlocked (quick unlock active)');
return;
}
if (typeof lockVault === 'function') lockVault();
if (typeof lockVault === 'function')
lockVault('Windows session locked or computer asleep');
},
// Called by Delphi (ExecuteJavaScript) when the user restores the
@@ -732,6 +733,12 @@ const state = {
selectedId: null,
theme: localStorage.getItem('theme') || 'dark',
locked: false, // true after user clicks Lock (token still valid server-side)
// POURQUOI LE COFFRE S'EST FERME, et depuis quand la page vit. Un
// verrouillage automatique etait muet ; quand le remplissage repondait
// "Vault is locked", rien ne disait si c'etait l'inactivite, une veille de
// Windows, ou une page rechargee qui avait tout perdu.
lastLockReason: '',
pageLoadedAt: new Date().toLocaleTimeString(),
autoLock: parseInt(localStorage.getItem('autoLockMin') || '5'),
askBeforeDelete: localStorage.getItem('askBeforeDelete') !== '0', // default true
maskUsernames: localStorage.getItem('maskUsernames') === '1', // default false
@@ -1424,7 +1431,8 @@ async function confirmDiscardForSessionExit(action) {
});
}
function lockVault() {
function lockVault(reason) {
state.lastLockReason = (reason || 'manual lock') + ' at ' + new Date().toLocaleTimeString();
sessionStorage.removeItem('cryptoKey');
state.cryptoKey = null;
state.entries = [];
@@ -7010,7 +7018,7 @@ function resetAutoLock() {
autoLockTimer = setTimeout(() => {
hideIdleWarning();
toast('Auto-locked due to inactivity', 'warning');
lockVault();
lockVault('inactivity (' + state.autoLock + ' min)');
}, totalMs);
}
@@ -7185,7 +7193,7 @@ async function enterApp() {
if (!ok) {
const fresh = await bridgePinStatus();
state.pinConfigured = fresh;
lockVault();
lockVault('wrong PIN after the master password');
$('#authHint').textContent = fresh
? 'Wrong PIN. Try again.'
: 'Too many wrong PIN attempts — PIN has been removed. Re-set it from Settings after unlocking.';