69320fbe5c70

preserve pending recovery confirmation across ordinary lock (v5.2.57)

time
2026-09-14 19:06 UTC · 1 month ago
machine
koh2
agent
camel-stream/auto
session
restore release assurance
parent
71c03512622e
6 files manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/background/recovery-pending.test.ts+5 −3src/background/vault.session-escrow.test.ts+2 −2src/background/vault.ts+1 −5
manifest.firefox.json+1 −1
@@ -1,7 +1,7 @@11 {22   "manifest_version": 3,33   "name": "Peach Password Manager",4-  "version": "5.2.56",4+  "version": "5.2.57",55   "description": "Zero-knowledge password manager",66   "browser_specific_settings": {77     "gecko": {

view file

manifest.json+1 −1
@@ -2,7 +2,7 @@22   "manifest_version": 3,33   "minimum_chrome_version": "116",44   "name": "Peach Password Manager",5-  "version": "5.2.56",5+  "version": "5.2.57",66   "description": "Zero-knowledge password manager",77   "action": {88     "default_popup": "src/popup/index.html",

view file

package.json+1 −1
@@ -1,6 +1,6 @@11 {22   "name": "peach",3-  "version": "5.2.56",3+  "version": "5.2.57",44   "description": "Zero-knowledge password manager",55   "license": "GPL-3.0-only",66   "type": "module",

view file

src/background/recovery-pending.test.ts+5 −3
@@ -71,12 +71,14 @@7171     }7272   });7373 74-  it("clears the recovery exemption when the vault locks", async () => {74+  it("preserves the recovery obligation when the vault locks", async () => {7575     const pending = await import("./recovery-pending");7676     const vault = await import("./vault");7777     await pending.setRecoveryConfirmPending();7878 79-    vault.lock();80-    await vi.waitFor(() => expect(sessionValues.peach_recovery_pending).toBeUndefined());79+    await vault.lock();80+81+    expect(await pending.isRecoveryConfirmPending()).toBe(true);82+    expect(sessionValues.peach_recovery_pending).toBeDefined();8183   });8284 });

view file

src/background/vault.session-escrow.test.ts+2 −2
@@ -353,7 +353,7 @@353353     }354354   });355355 356-  it("does not resolve lock until session escrow and recovery confirmation are absent", async () => {356+  it("does not resolve lock until session escrow is absent", async () => {357357     const vault = await import("./vault");358358     const pending = await import("./recovery-pending");359359     await vault.createVault("strong-pass-abc123");@@ -389,7 +389,7 @@389389     }390390 391391     expect(session.peach_session_dk).toBeUndefined();392-    expect(session.peach_recovery_pending).toBeUndefined();392+    expect(session.peach_recovery_pending).toBeDefined();393393   });394394 395395   it("disabled escrow clears the stored key and blocks save and restore", async () => {

view file

src/background/vault.ts+1 −5
@@ -35,11 +35,8 @@3535 } from "../shared/types";3636 import { decrypt, encrypt, zeroKey } from "./aes";3737 import { clearAutoLock, touchAutoLock } from "./alarms";38+import { setRecoveryConfirmPending } from "./recovery-pending";3839 import {39-  clearRecoveryConfirmPending,40-  setRecoveryConfirmPending,41-} from "./recovery-pending";42-import {4340   clearPairSecrets,4441   dropSessionCache,4542   reconcilePairSecrets,@@ -1932,7 +1929,6 @@19321929   // The decrypted identity is session state as well, so a locked vault must not19331930   // leave one behind; clear it after the in-memory state is gone.19341931   await notifyIdentitySessionEnded();1935-  await clearRecoveryConfirmPending();19361932 }19371933 19381934 export function isUnlocked(): boolean {

view file