0a1c5debb187
fix: Keep new-entry creation inline when vault is unlocked (v5.2.3)
- time
- 2026-09-06 19:20 UTC · 1 month ago
- machine
- koh2
- parent
- 3e534fd912b8
↓ peach-browser-0a1c5deb.tar.gzatlas at this save
files changed5 files
manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/content/content.selector-ui.test.ts+28 −0src/content/inject.ts+0 −9manifest.firefox.json+1 −1
@@ -1,7 +1,7 @@11 {22 "manifest_version": 3,33 "name": "Peach Password Manager",4- "version": "5.2.2",4+ "version": "5.2.3",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.2",5+ "version": "5.2.3",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.2",3+ "version": "5.2.3",44 "description": "Zero-knowledge password manager",55 "license": "GPL-3.0-only",66 "type": "module",src/content/content.selector-ui.test.ts+28 −0
@@ -84,6 +84,34 @@8484 });8585 8686 describe("PB-26-201: content-safe privileged actions", () => {87+ it("opens new-entry creation inline without rechecking an already-unlocked selector", async () => {88+ const originalAttachShadow = Element.prototype.attachShadow;89+ const attachSpy = vi.spyOn(Element.prototype, "attachShadow").mockImplementation(function (this: Element) {90+ return originalAttachShadow.call(this, { mode: "open" });91+ });92+ const anchor = makeInput({ type: "password" });93+ setMessageResponder((message) =>94+ message.type === "GET_VAULT_STATUS"95+ ? { ok: true, unlocked: false }96+ : { ok: true, data: null },97+ );98+99+ try {100+ const dismiss = showAutofillSelector(anchor, [ENTRIES[0]!], vi.fn(), { domain: "example.com" });101+ const host = selectorHost();102+ host?.shadowRoot?.querySelector<HTMLButtonElement>(".domain-add-btn")?.click();103+104+ await vi.waitFor(() => {105+ expect(host?.shadowRoot?.querySelector(".create-form-wrap")).not.toBeNull();106+ });107+ expect(host?.shadowRoot?.querySelector(".locked-wrap")).toBeNull();108+ expect(sentMessages.some((message) => message.type === "GET_VAULT_STATUS")).toBe(false);109+ dismiss();110+ } finally {111+ attachSpy.mockRestore();112+ }113+ });114+87115 it("uses a command capability for exactly one login-with-TOTP secret fetch", async () => {88116 const originalAttachShadow = Element.prototype.attachShadow;89117 const attachSpy = vi.spyOn(Element.prototype, "attachShadow").mockImplementation(function (this: Element) {src/content/inject.ts+0 −9
@@ -2481,15 +2481,6 @@24812481 currentMode = "create";24822482 container.innerHTML = "";24832483 2484- // Guard: the service worker may lock the vault between when the selector2485- // opens and when the user clicks "New entry". Show the inline unlock form2486- // instead of silently failing on save.2487- const statusRes = await chrome.runtime.sendMessage({ type: "GET_VAULT_STATUS" }).catch(() => null) as { unlocked?: boolean } | null;2488- if (!statusRes?.unlocked) {2489- renderLocked();2490- return;2491- }2492-24932484 // Detect page password policy once for this form — reused on every24942485 // regenerate click so the user always gets a compliant password.24952486 const sitePolicy = detectPasswordPolicy();