feat: rotation progress spinner + quick-unlock re-wrap on master-pw change
- doChangeMasterPassword shows the busy overlay while it re-encrypts the vault: "Re-encrypting vault…" → "Re-encrypting entries… N/total" → "Re-encrypting attachments… N/total", cleared in finally. A rotation on a big vault took tens of seconds with no feedback before. - Quick-unlock now SURVIVES a master-pw change instead of being wiped. The blob stores the raw key (DPAPI-wrapped, no user secret), so it's re-wrapped in place with the new key/salt/iters/algo (state already holds the new values at that point). Cold-start then re-logs in with a verifier derived from the new key. Falls back to clearing if the re-wrap throws, so a stale old-key blob is never left behind. - PIN blob still cleared (wrapped by PBKDF2(pin) — can't re-wrap without the PIN). A setTimeout(0) separates the quickunlock/store and pin/clear navigations so the back-to-back window.location.href assignments don't coalesce and drop the re-wrap. - Fixed a `failed` counter declaration accidentally dropped from the attachment re-encryption loop while adding progress (ReferenceError at runtime; node --check wouldn't catch it). - CLAUDE.md updated for the re-wrap vs clear distinction. Rebuild: BuildAssets + F9 (JS only this commit; F9 to re-embed). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -581,9 +581,15 @@ bypasses the PIN check (the device is already trusted).
|
||||
Sensitive actions (`askReauth` paths: export, change master pw,
|
||||
recovery code, etc.) ALWAYS require master pw — PIN never substitutes.
|
||||
|
||||
Master pw rotation clears the PIN blob (same reason as Quick Unlock :
|
||||
stored wrapped key + server verifier drift). User re-sets PIN from
|
||||
Settings after rotation.
|
||||
Master pw rotation **clears the PIN blob** (stored wrapped key + server
|
||||
verifier drift). Unlike Quick Unlock — which stores the raw key directly
|
||||
(DPAPI-wrapped, no user secret) and is therefore **re-wrapped in place**
|
||||
with the new key/salt/iters/algo during rotation so it survives — the PIN
|
||||
blob is wrapped by `PBKDF2(pin)` and can't be re-wrapped without the PIN,
|
||||
so it's wiped and the user re-sets it from Settings. `doChangeMasterPassword`
|
||||
does the two via `window.location.href` (quickunlock/store then pin/clear)
|
||||
with a `setTimeout(0)` between them so the back-to-back navigations don't
|
||||
coalesce and drop the re-wrap.
|
||||
|
||||
## Quick Unlock
|
||||
|
||||
|
||||
Reference in New Issue
Block a user