a7728642a731
complete locked-vault Sync reset flow (v5.2.48)
- time
- 2026-09-11 17:21 UTC · 1 month ago
- machine
- koh2
- agent
- camel-stream/auto
- session
- fix secure reset completion
- parent
- 9aec7adfb69c
↓ peach-browser-a7728642.tar.gzatlas at this save
files changed6 files
manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/background/messages.test.ts+27 −0src/background/messages.ts+15 −3src/shared/release-notes.ts+3 −3manifest.firefox.json+1 −1
@@ -1,7 +1,7 @@11 {22 "manifest_version": 3,33 "name": "Peach Password Manager",4- "version": "5.2.47",4+ "version": "5.2.48",55 "description": "Zero-knowledge password manager",66 "browser_specific_settings": {77 "gecko": {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.47",5+ "version": "5.2.48",66 "description": "Zero-knowledge password manager",77 "action": {88 "default_popup": "src/popup/index.html",package.json+1 −1
@@ -1,6 +1,6 @@11 {22 "name": "peach",3- "version": "5.2.47",3+ "version": "5.2.48",44 "description": "Zero-knowledge password manager",55 "license": "GPL-3.0-only",66 "type": "module",src/background/messages.test.ts+27 −0
@@ -1831,6 +1831,33 @@18311831 expect(response).toMatchObject({ ok: true, data: { state: "V2_ANCHOR" } });18321832 expect(await identity.getOrCreateDeviceId()).not.toBe(previousDeviceId);18331833 });1834+ it("SECURE_RESET unlocks a locked real vault before rotating identity", async () => {1835+ const vault = await import("./vault");1836+ await vault.createVault("correct-pass-12345");1837+ const identity = await import("./device-identity");1838+ const previousDeviceId = await identity.getOrCreateDeviceId();1839+ const { upsertPairedDevice } = await import("./paired-devices");1840+ await upsertPairedDevice({1841+ deviceId: "phone-1",1842+ deviceName: "June's Phone",1843+ deviceType: "android",1844+ longTermPublicKeyHex: "a".repeat(64),1845+ signingPublicKeyHex: "b".repeat(64),1846+ pairedAt: 1_700_000_000_000,1847+ trustSource: "direct",1848+ });1849+ await vault.lock();1850+ expect(vault.isUnlocked()).toBe(false);1851+1852+ const response = await dispatch({1853+ type: "SECURE_RESET",1854+ payload: { password: "correct-pass-12345" },1855+ });1856+1857+ expect(response).toMatchObject({ ok: true, data: { state: "V2_ANCHOR" } });1858+ expect(vault.isUnlocked()).toBe(true);1859+ expect(await identity.getOrCreateDeviceId()).not.toBe(previousDeviceId);1860+ });18341861 18351862 // The old "fresh direct re-pair clears the old revocation" test dispatched18361863 // COMPLETE_PAIRING, a handler deleted on 2026-08-04 (no legitimate senders;src/background/messages.ts+15 −3
@@ -1808,11 +1808,23 @@18081808 if (typeof payload.password !== "string" || payload.password.length === 0) {18091809 return { ok: false, error: "Enter your master password" };18101810 }1811- if (!(await vault.verifyMainPassword(payload.password))) {1811+ const wasLocked = !vault.isUnlocked();1812+ const passwordValid = wasLocked1813+ ? await vault.unlock(payload.password)1814+ : await vault.verifyMainPassword(payload.password);1815+ if (!passwordValid) {18121816 return { ok: false, error: "Incorrect master password" };18131817 }1814- // Enter the blocking state first: a crash between these two calls then1815- // leaves the device refusing sync rather than mid-reset over live1818+ if (wasLocked) {1819+ await setupAutoLock();1820+ broadcastToContentScripts({ type: "VAULT_UNLOCKED" });1821+ onVaultUnlocked();1822+ }1823+ // Identity rotation needs the live vault root key. A password check is1824+ // deliberately verification-only, so establish the real session first1825+ // when Settings is opened after the vault session expired.1826+ // Enter the blocking state before the reset steps: a crash after this1827+ // point leaves the device refusing sync rather than mid-reset over live18161828 // trust. Both are idempotent, so a retry is safe.18171829 await enterResetRequired(browserGenerationIo);18181830 const result = await confirmSecureReset(browserGenerationIo, {src/shared/release-notes.ts+3 −3
@@ -21,11 +21,11 @@2121 2222 export const RELEASES: PeachRelease[] = [2323 {24- version: "5.2.47",24+ version: "5.2.48",2525 releasedAt: "2026-09-11",2626 notes: [{27- heading: "Repair Sync reset and peer removal",28- body: "Sync reset now creates the new device identity, and removing a peer still works when the old identity needs migration.",27+ heading: "Complete locked-vault Sync resets",28+ body: "Sync reset now unlocks the real vault before rotating its local identity when Settings is opened after the vault session expired.",2929 }],3030 },3131 {