cf02cd217e1f

fix: TOTP picker shows empty-state toast when no TOTP entries for domain; drop 'mobile apps' from Onboarding Pro list (v3.6.80)

time
2026-05-21 15:43 UTC · 5 months ago
machine
koh2
parent
e073840d9292
6 files manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/content/content.adversarial.test.ts+16 −0src/content/index.ts+6 −1src/popup/views/Onboarding.tsx+1 −1
manifest.firefox.json+1 −1
@@ -2,7 +2,7 @@22   "_comment_audio_capture": "Firefox does not honor the Chrome 'audioCapture' optional_permission — getUserMedia in WebExtensions is gated solely by the runtime permission prompt. Microphone access for chirp pairing works from the popup under the existing '<all_urls>' host permission; no manifest entry is required or accepted here.",33   "manifest_version": 3,44   "name": "Peach",5-  "version": "3.6.79",5+  "version": "3.6.80",66   "description": "Zero-knowledge password manager",77   "browser_specific_settings": {88     "gecko": {

view file

manifest.json+1 −1
@@ -1,7 +1,7 @@11 {22   "manifest_version": 3,33   "name": "Peach",4-  "version": "3.6.79",4+  "version": "3.6.80",55   "description": "Zero-knowledge password manager",66   "action": {77     "default_popup": "src/popup/index.html",

view file

package.json+1 −1
@@ -1,6 +1,6 @@11 {22   "name": "peach",3-  "version": "3.6.79",3+  "version": "3.6.80",44   "description": "Zero-knowledge password manager",55   "type": "module",66   "scripts": {

view file

src/content/content.adversarial.test.ts+16 −0
@@ -606,4 +606,20 @@606606       expect(isVisible(el)).toBe(false);607607     });608608   });609+610+  describe("TOTP picker empty-state message (SEV-2-A)", () => {611+    it("openTOTPSelector renders an empty-state toast when no TOTP entries exist for the domain", async () => {612+      const { readFileSync } = await import("node:fs");613+      const path = await import("node:path");614+      const source = readFileSync(615+        path.resolve(process.cwd(), "src/content/index.ts"),616+        "utf8"617+      );618+      const totpFn = source.slice(source.indexOf("async function openTOTPSelector"));619+      const body = totpFn.slice(0, totpFn.indexOf("\n}"));620+      expect(body).toMatch(/result\.entries\.length === 0/);621+      expect(body).toMatch(/No 2FA entries for this site/);622+      expect(body).not.toMatch(/result\.entries\.length === 0\)\s*return;/);623+    });624+  });609625 });

view file

src/content/index.ts+6 −1
@@ -519,7 +519,12 @@519519     return;520520   }521521 522-  if (result.entries.length === 0) return;522+  if (result.entries.length === 0) {523+    lastDismissedField = anchorField;524+    startDismissLock();525+    showToast("No 2FA entries for this site — add a code in Peach first");526+    return;527+  }523528 524529   currentDismiss?.();525530   currentAnchorField = anchorField;

view file

src/popup/views/Onboarding.tsx+1 −1
@@ -29,7 +29,7 @@2929     headline: "Everything\nyou need.",3030     body: [3131       "Free includes passwords, cards, secure notes, two-factor codes, autofill, strong passwords, and breach checks.",32-      "Pro adds encrypted sync, Peach Codex paper restore, passkeys, mobile apps, advanced vault health, canary entries, and duress tools.",32+      "Pro adds encrypted sync, Peach Codex paper restore, passkeys, advanced vault health, canary entries, and duress tools.",3333     ],3434     warning: null,3535   },

view file