fix(reauth): wrong master pw re-prompts inline instead of closing
Setting a PIN, enabling Quick Unlock, and generating a recovery key all closed the reauth modal and showed a toast on the first wrong master password — no retry. Export already looped inline; the others didn't. Extracted that loop into reauthLoop(message): re-prompts with an inline error + attempt count (5 tries), honours the 429 lockout, returns the verified password or null. All four sensitive-action flows now share it, so a mistyped master password keeps the modal up to try again. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -6022,6 +6022,45 @@ function closeReauth(ok) {
|
||||
}
|
||||
}
|
||||
|
||||
// Prompt for the master password and verify it via /reauth, RE-PROMPTING
|
||||
// inline on a wrong entry (the modal stays up with an error + attempt count)
|
||||
// instead of closing on the first miss. The single choke point for every
|
||||
// sensitive-action reauth (export, PIN set, Quick Unlock, recovery) so they
|
||||
// all behave the same. Returns the verified master password, or null when the
|
||||
// user cancels or the attempt cap / server lockout is hit (already toasted).
|
||||
async function reauthLoop(message) {
|
||||
const MAX = 5;
|
||||
let attempts = 0;
|
||||
let lastError = '';
|
||||
for (;;) {
|
||||
const pwd = await askReauth(message, { error: lastError });
|
||||
if (!pwd) return null; // cancelled
|
||||
try {
|
||||
const verifier = await computeVerifier(
|
||||
pwd, state.salt, state.kdfIterations || 100000,
|
||||
state.hashAlgo, state.argon2Params);
|
||||
await api('/reauth', {
|
||||
method: 'POST',
|
||||
headers: authHeaders({ 'Content-Type': 'application/json' }),
|
||||
body: JSON.stringify({ verifier }),
|
||||
});
|
||||
return pwd;
|
||||
} catch (err) {
|
||||
if (err.status === 429 && err.body && err.body.retry_after) {
|
||||
toast('Account locked. Try again in ' +
|
||||
Math.ceil(err.body.retry_after / 60) + ' min', 'warning');
|
||||
return null;
|
||||
}
|
||||
attempts++;
|
||||
if (attempts >= MAX) {
|
||||
toast('Too many wrong attempts — try again later', 'error');
|
||||
return null;
|
||||
}
|
||||
lastError = 'Wrong master password. Attempt ' + attempts + ' / ' + MAX + '.';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// QUICK UNLOCK + PIN + RECOVERY KEY — extracted to js/app.unlock.js (§3.1),
|
||||
// loaded AFTER this file (it assigns Bridge.onQuickUnlockResult / onPinResult
|
||||
|
||||
Reference in New Issue
Block a user