d12779c5867c

fix passkey entry editability — isPasskeyOnly excludes TOTP/email, + 2FA always visible on login entries

time
2026-05-31 01:22 UTC · 4 months ago
machine
koh2
agent
claude-sonnet-4-6
session
passkey Google origin and TOTP merge
parent
ab5496be14e8
6 files manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/background/messages.ts+0 −3src/popup/views/Entry.tsx+1 −1src/shared/types.ts+6 −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 Password Manager",5-  "version": "3.6.143",5+  "version": "3.6.144",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 Password Manager",4-  "version": "3.6.143",4+  "version": "3.6.144",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.143",3+  "version": "3.6.144",44   "description": "Zero-knowledge password manager",55   "type": "module",66   "scripts": {

view file

src/background/messages.ts+0 −3
@@ -365,9 +365,6 @@365365           return { ok: false, error: "invalid_payload" };366366         }367367         const entry = await vault.addEntry(payload as Parameters<typeof vault.addEntry>[0]);368-        // Merge any same-domain passkey entry with this new entry right away369-        // (e.g. user adds a TOTP for a site that already has a passkey entry).370-        void vault.consolidatePasskeyEntries();371368         return { ok: true, data: entry };372369       }373370       case "BATCH_ADD_ENTRIES": {

view file

src/popup/views/Entry.tsx+1 −1
@@ -1245,7 +1245,7 @@12451245               </Show>12461246 12471247               {/* ── TOTP ─────────────────────────────────────────── */}1248-              <Show when={entry().type === "login" && !isPasskeyOnly(entry())}>1248+              <Show when={entry().type === "login"}>12491249                 <Show12501250                   when={totpState() || editingField() === "totp"}12511251                   fallback={

view file

src/shared/types.ts+6 −1
@@ -142,7 +142,12 @@142142  * domain-index/search keep working) and is not part of this discriminator.143143  */144144 export function isPasskeyOnly(entry: VaultEntry): boolean {145-  return hasPasskey(entry) && !entry.password;145+  // An entry is "passkey only" when it holds SOLELY a passkey credential —146+  // no password, no TOTP, and no dedicated email. Username is intentionally147+  // excluded (the migration copies passkey.userName onto username for search).148+  // Entries with passkey + TOTP or passkey + email are NOT passkey-only: they149+  // carry fillable credentials and must show the full login-fields UI.150+  return hasPasskey(entry) && !entry.password && !entry.totp && !entry.email;146151 }147152 148153 export interface LegacyVaultEntry {

view file