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
5 files manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/content/content.selector-ui.test.ts+28 −0src/content/inject.ts+0 −9
manifest.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": {

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.2",5+  "version": "5.2.3",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.2",3+  "version": "5.2.3",44   "description": "Zero-knowledge password manager",55   "license": "GPL-3.0-only",66   "type": "module",

view file

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) {

view file

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();

view file