52a1b1bfa47f
enable passkey interception by default with saved opt-out (v5.3.8)
- time
- 2026-10-08 17:32 UTC · 2 weeks ago
- machine
- Junes-MacBook-Pro.local
- agent
- gpt-6
- session
- reliable firefox passkey sign-in
- parent
- 2627a8b30c10
↓ peach-browser-52a1b1bf.tar.gzatlas at this save
files changed6 files
manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/background/passkey-firefox-proxy.test.ts+20 −0src/background/passkey.ts+5 −5src/popup/views/Settings.tsx+1 −1manifest.firefox.json+1 −1
@@ -1,7 +1,7 @@11 {22 "manifest_version": 3,33 "name": "Peach Password Manager",4- "version": "5.3.7",4+ "version": "5.3.8",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.3.7",5+ "version": "5.3.8",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.3.7",3+ "version": "5.3.8",44 "description": "Zero-knowledge password manager",55 "license": "GPL-3.0-only",66 "type": "module",src/background/passkey-firefox-proxy.test.ts+20 −0
@@ -141,6 +141,26 @@141141 void wait();142142 }143143 144+ it.each([[undefined, true], [true, true], [false, false]] as const)("defaults passkey interception on while preserving %s", async (preference, enabled) => {145+ storage.peach_settings = { breachMonitoring: false, ...(preference === undefined ? {} : { passkeyProviderEnabled: preference }) };146+ vi.stubGlobal("navigator", { userAgent: "Mozilla/5.0 Firefox/157.0" });147+ const passkey = await import("./passkey");148+ await passkey.setupPasskeyProxy();149+ const state = await passkey.getPasskeyProviderState();150+ expect(state).toMatchObject({ supported: true, enabled, attached: enabled });151+ });152+153+ it.each(["PASSKEY_HAS_CREDENTIALS", "PASSKEY_GET", "PASSKEY_CREATE"] as const)("honors explicit disabled interception for %s", async (type) => {154+ const vault = await import("./vault");155+ await vault.createVault("correct-pass-12345");156+ await vault.updateSettings({ passkeyProviderEnabled: false });157+ await expect(dispatch({158+ type,159+ payload: { rpId: "github.com", userName: "june", userId: "AQID", challenge: "x", origin: "https://github.com", clientDataJSON: Array.from(new TextEncoder().encode("{}")), allowCredentials: [] },160+ })).resolves.toMatchObject({ ok: false, error: "not_applicable" });161+ expect(chrome.action.openPopup).not.toHaveBeenCalled();162+ });163+144164 it("PASSKEY_HAS_CREDENTIALS returns false when vault has no passkey for rpId", async () => {145165 const vault = await import("./vault");146166 await vault.createVault("correct-pass-12345");src/background/passkey.ts+5 −5
@@ -295,7 +295,7 @@295295 export async function getPasskeyProviderState(): Promise<PasskeyProviderState> {296296 const settings = await vault.ensureSettingsLoaded();297297 const supported = isPasskeySupported();298- const enabled = settings.passkeyProviderEnabled === true;298+ const enabled = settings.passkeyProviderEnabled !== false;299299 return {300300 supported,301301 enabled,@@ -377,7 +377,7 @@377377 378378 async function refreshPasskeyProxy(): Promise<void> {379379 const settings = await vault.ensureSettingsLoaded();380- if (settings.passkeyProviderEnabled === true) {380+ if (settings.passkeyProviderEnabled !== false) {381381 await attachPasskeyProxy();382382 return;383383 }@@ -1106,7 +1106,7 @@11061106 payload: FirefoxPasskeyHasCredentialsPayload,11071107 callerOrigin?: string,11081108 ): Promise<{ ok: true; hasCredentials: boolean } | { ok: false; error: string }> {1109- if (!FIREFOX_USE_CONTENT_SCRIPT_PROXY) {1109+ if (!FIREFOX_USE_CONTENT_SCRIPT_PROXY || (await vault.ensureSettingsLoaded()).passkeyProviderEnabled === false) {11101110 return { ok: false, error: "not_applicable" };11111111 }11121112 // Scope the existence check to the caller's own origin so an arbitrary page@@ -1171,7 +1171,7 @@11711171 payload: FirefoxPasskeyCreatePayload,11721172 callerOrigin?: string,11731173 ): Promise<FirefoxPasskeyResult<FirefoxCreateCredentialResponse>> {1174- if (!FIREFOX_USE_CONTENT_SCRIPT_PROXY) {1174+ if (!FIREFOX_USE_CONTENT_SCRIPT_PROXY || (await vault.ensureSettingsLoaded()).passkeyProviderEnabled === false) {11751175 return { ok: false, error: "not_applicable" };11761176 }11771177 // WebAuthn §7.1 step 6 — the requested rpId must be owned by the page's@@ -1271,7 +1271,7 @@12711271 payload: FirefoxPasskeyGetPayload,12721272 callerOrigin?: string,12731273 ): Promise<FirefoxPasskeyResult<FirefoxGetCredentialResponse>> {1274- if (!FIREFOX_USE_CONTENT_SCRIPT_PROXY) {1274+ if (!FIREFOX_USE_CONTENT_SCRIPT_PROXY || (await vault.ensureSettingsLoaded()).passkeyProviderEnabled === false) {12751275 return { ok: false, error: "not_applicable" };12761276 }12771277 // WebAuthn §7.2 step 8 — the rpId must be owned by the page's browser-attestedsrc/popup/views/Settings.tsx+1 −1
@@ -1449,7 +1449,7 @@14491449 <div class="peach-settings-row-main">14501450 <span>Intercept passkey requests</span>14511451 <span class="peach-settings-value" style="font-size:11px;line-height:1.5;color:var(--t2)">1452- Peach can handle passkey sign-in and creation on supported Chromium browsers.1452+ Use Peach for passkey sign-in and creation in Chrome and Firefox.14531453 </span>14541454 </div>14551455 <button