Skip to content

fix(desktop): make right-click work in the in-app browser, and stop passkey requests hanging for 3 minutes - #3459

Merged
benjaminshafii merged 6 commits into
devfrom
fix/browser-passkeys-context-menu
Aug 3, 2026
Merged

fix(desktop): make right-click work in the in-app browser, and stop passkey requests hanging for 3 minutes#3459
benjaminshafii merged 6 commits into
devfrom
fix/browser-passkeys-context-menu

Conversation

@benjaminshafii

Copy link
Copy Markdown
Member

Two bugs reported in the built-in browser: right-click did nothing, and passkeys were unusable.

Right-click did nothing

No context-menu listener was ever registered on the browser tab's WebContentsView. The overlay menu machinery already existed and already declared a "page" source — the main process only ever emitted "tab", so page right-clicks fell on the floor.

Now builds a params-driven menu:

Target Items
Text input Cut / Copy / Paste / Select All
Selected text Copy
Link Open Link in New Tab / Copy Link Address / Open Link in Browser
Image Copy Image
Page Back / Forward / Reload / Copy Page URL / Open Page in Browser

Two traps handled: a secondary-button pointerdown used to dismiss the very menu it opened, and context-menu coordinates are local to the tab view so they need offsetting against the overlay's window-relative bounds.

Passkeys hung for 180 seconds

Electron 35 has no working WebAuthn authenticator at all — isUserVerifyingPlatformAuthenticatorAvailable() is false and requests hang for exactly 180s before a generic NotAllowedError. That silent 3-minute stall is what "I can't use it" actually felt like.

Requests now settle in ~0.6ms with a real DOMException/NotAllowedError so the site runs its own password/magic-link fallback immediately, and the user is offered to open the page in their real browser. Gated on a live capability probe, not a version check, so it goes quiet automatically once Electron can service passkeys (see the follow-up PR).

Real passkey support needs Electron ≥ 41.5.0 and is stacked in a follow-up.

Overlay sizing defect (found by validation)

Visual proof measured a ~13px transparent strip below the menu: the overlay was sized from a guessed 36px row height while rows render at 34.56px. That strip belongs to the overlay compositor surface, so it silently swallowed clicks meant for the page. The overlay now measures its rendered content and applies exact bounds (200px view vs 199.81px content), and dismisses on backdrop click.

Tests

evals/specs/builtin-browser-context-menu-passkey.slow.test.ts — new, drives the real app with real CDP right-clicks.

Because a WebContentsView embedded in another window is a separate compositor surface (invisible to CDP Page.captureScreenshot from both its own and the parent target), the menu is proven with OS-level X11 capture.

OPENWORK_EVAL_APP_SPECS=1 OPENWORK_EVAL_DAYTONA=1 ... --project stack \
  specs/builtin-browser-context-menu-passkey.slow.test.ts

Test Files  1 passed (1)
Tests       1 passed (1)
Duration    112.52s

26/26 frames, 34/34 expectations. Screenshots confirm menus land on the click markers, edge-clamp near the window bottom/right, and are unclipped. Also covered: item actions (clipboard, new tab), backdrop/Escape dismissal, the tab-strip 4-item regression guard, and passkey timing + error name.

Also green: pnpm typecheck, pnpm --filter @openwork/desktop typecheck:electron, pnpm --filter @openwork/desktop test (174 passed / 1 skipped).

Pre-existing and unrelated: pnpm evals:typecheck fails on den-trim-page-headers.flow.ts (FlowContext.page).

Right-clicking a browsed page did nothing: no context-menu listener was
ever registered on the browser tab's WebContentsView. The overlay menu
machinery already existed and already declared a "page" source, but the
main process only ever emitted "tab".

- build a params-driven menu (editable, selection, link, image, page)
- size the overlay from item count instead of a fixed 4-item height
- stop secondary-button pointerdown from dismissing the menu it opens
…passkey

Electron 35 has no working WebAuthn authenticator, so passkey requests
hung for 180s before a generic NotAllowedError, with no explanation.

Detect publicKey credential requests in the page's main world, settle
them immediately with a real NotAllowedError so the site can fall back
to password/magic-link, and offer to open the page in the user's own
browser. Gated on a live platform-authenticator probe, so this goes
quiet once Electron can actually service passkeys.
Visual validation measured a ~13px transparent strip below the menu: the
overlay view was sized from a guessed 36px row height while rows render
at 34.56px. That strip belongs to the overlay compositor surface, so it
silently swallowed clicks meant for the page.

Measure the rendered menu and apply exact bounds, and dismiss on
backdrop pointer-down so any residual area behaves correctly.

Adds evals/specs/builtin-browser-context-menu-passkey.slow.test.ts.
The sizing assertion hardcoded 212px from the old guessed-height
implementation. Assert the invariant instead: the overlay view must match
its rendered content within 1px, so it can neither clip the menu nor
leave a transparent strip that swallows clicks.
@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openwork-app Ready Ready Preview Aug 3, 2026 2:02pm
openwork-den Ready Ready Preview Aug 3, 2026 2:02pm
openwork-den-worker-proxy Ready Ready Preview Aug 3, 2026 2:02pm
openwork-diagnostics Ready Ready Preview Aug 3, 2026 2:02pm
openwork-landing Ready Ready Preview, v0 Aug 3, 2026 2:02pm

@benjaminshafii

Copy link
Copy Markdown
Member Author

Photo roll — built-in-browser-page-menus-and-passkeys-work-in-electron-with-os-level-visual-e — 9/9 frames passed · 17 facts

9/9 frames passed · 17 facts · 34 expectations passed · 0 failed

⚠ evidence from 0fed766, PR head is 658f842

ℹ️ FACT — 1. The real app under test is Electron 35

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) OpenWork-Dev/0.0 Chrome/134.0.6998.205 Electron/35.7.5 Safari/537.36

  • PASS The real app under test is Electron 35 — Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) OpenWork-Dev/0.0 Chrome/134.0.6998.205 Electron/35.7.5 Safari/537.36

ℹ️ FACT — 2. page context menu overlay height matches its rendered content without clipping or a large dead gap

{"overlayHeight":200,"contentHeight":199.8125,"metrics":{"ariaLabel":"page context menu","labels":["Back","Forward","Reload","Copy Page URL","Open Page in Browser"],"innerWidth":196,"innerHeight":200,"itemHeights":[34.5625,34.5625,34.5625,34.5625,34.5625],"separatorFootprints":[13],"menuRect":{"x":1,"y":1,"width":194,"height":197.8125,"top":1,"right":195,"bottom":198.8125,"left":1},"contentHeight":199.8125,"lastItemBottom":192.8125,"scrollHeight":200},"visibleTrailingGap":6,"transparentBottomSpace":1.1875}

  • PASS page context menu overlay height matches its rendered content without clipping or a large dead gap — {"overlayHeight":200,"contentHeight":199.8125,"metrics":{"ariaLabel":"page context menu","labels":["Back","Forward","Reload","Copy Page URL","Open Page in Browser"],"innerWidth":196,"innerHeight":200,"itemHeights":[34.5625,34.5625,34.5625,34.5625,34.5625],"separatorFootprints":[13],"menuRect":{"x":1,"y":1,"width":194,"height":197.8125,"top":1,"right":195,"bottom":198.8125,"left":1},"contentHeight":199.8125,"lastItemBottom":192.8125,"scrollHeight":200},"visibleTrailingGap":6,"transparentBottomSpace":1.1875}

ℹ️ FACT — 3. A real CDP right-click on plain page area opens Back / Forward / Reload / Copy Page URL / Open Page in Browser and is not instantly dismissed

["Back","Forward","Reload","Copy Page URL","Open Page in Browser"]

  • PASS A real CDP right-click on plain page area opens Back / Forward / Reload / Copy Page URL / Open Page in Browser and is not instantly dismissed — ["Back","Forward","Reload","Copy Page URL","Open Page in Browser"]

✅ PASS — 4. The in-app browser visibly shows a five-item page context menu with Back, Forward, Reload, Copy Page URL, and Open Page in Browser

  • PASS The in-app browser visibly shows a five-item page context menu with Back, Forward, Reload, Copy Page URL, and Open Page in Browser — The visible context menu lists exactly Back, Forward, Reload, Copy Page URL, and Open Page in Browser.
  • PASS The page context menu begins at the magenta click marker, is fully visible, and tightly fits its five rows without clipping or a large empty gap — The menu’s upper-left edge aligns with the magenta click marker; the entire rounded menu is visible and its five rows fit compactly without clipping or excessive empty space.

The in-app browser visibly shows a five-item page context menu with Back, Forward, Reload, Copy Page URL, and Open Page in Browser

ℹ️ FACT — 5. Choosing Copy Page URL writes the browsed page URL to the OS clipboard

http://localhost:43127/index.html

✅ PASS — 6. After a left-click on the browsed page, no page or tab context menu is visible anywhere in the OpenWork window

  • PASS After a left-click on the browsed page, no page or tab context menu is visible anywhere in the OpenWork window — The OpenWork window shows the browser page and tab normally, with no context menu visible anywhere.

After a left-click on the browsed page, no page or tab context menu is visible anywhere in the OpenWork window

✅ PASS — 7. After pressing Escape, no page or tab context menu is visible anywhere in the OpenWork window

  • PASS After pressing Escape, no page or tab context menu is visible anywhere in the OpenWork window — No context-menu popup is visible in either the browser page, tab bar, or elsewhere in the OpenWork window.

After pressing Escape, no page or tab context menu is visible anywhere in the OpenWork window

ℹ️ FACT — 8. page context menu overlay height matches its rendered content without clipping or a large dead gap

{"overlayHeight":118,"contentHeight":117.6875,"metrics":{"ariaLabel":"page context menu","labels":["Open Link in New Tab","Copy Link Address","Open Link in Browser"],"innerWidth":196,"innerHeight":118,"itemHeights":[34.5625,34.5625,34.5625],"separatorFootprints":[],"menuRect":{"x":1,"y":1,"width":194,"height":115.6875,"top":1,"right":195,"bottom":116.6875,"left":1},"contentHeight":117.6875,"lastItemBottom":110.6875,"scrollHeight":118},"visibleTrailingGap":6,"transparentBottomSpace":1.3125}

  • PASS page context menu overlay height matches its rendered content without clipping or a large dead gap — {"overlayHeight":118,"contentHeight":117.6875,"metrics":{"ariaLabel":"page context menu","labels":["Open Link in New Tab","Copy Link Address","Open Link in Browser"],"innerWidth":196,"innerHeight":118,"itemHeights":[34.5625,34.5625,34.5625],"separatorFootprints":[],"menuRect":{"x":1,"y":1,"width":194,"height":115.6875,"top":1,"right":195,"bottom":116.6875,"left":1},"contentHeight":117.6875,"lastItemBottom":110.6875,"scrollHeight":118},"visibleTrailingGap":6,"transparentBottomSpace":1.3125}

ℹ️ FACT — 9. Right-clicking a link exposes the three link actions

["Open Link in New Tab","Copy Link Address","Open Link in Browser"]

  • PASS Right-clicking a link exposes the three link actions — ["Open Link in New Tab","Copy Link Address","Open Link in Browser"]

✅ PASS — 10. The in-app browser visibly shows Open Link in New Tab, Copy Link Address, and Open Link in Browser for the fixture link

  • PASS The in-app browser visibly shows Open Link in New Tab, Copy Link Address, and Open Link in Browser for the fixture link — The open context menu visibly contains all three specified options.
  • PASS The link menu is positioned at the magenta click marker and all three rows are fully visible without excess empty space — The compact three-row menu begins at the magenta marker over the link, and every row is fully visible.

The in-app browser visibly shows Open Link in New Tab, Copy Link Address, and Open Link in Browser for the fixture link

ℹ️ FACT — 11. Choosing Open Link in New Tab opens the link in one new in-panel tab

{"before":{"activeTabId":"tab_msd6lhrg_1","tabs":[{"id":"tab_msd6lhrg_1","url":"http://localhost:43127/index.html"}]},"after":{"activeTabId":"tab_msd6mgp7_2","tabs":[{"id":"tab_msd6lhrg_1","url":"http://localhost:43127/index.html"},{"id":"tab_msd6mgp7_2","url":"http://localhost:43127/linked.html"}]}}

  • PASS Choosing Open Link in New Tab opens the link in one new in-panel tab — {"before":{"activeTabId":"tab_msd6lhrg_1","tabs":[{"id":"tab_msd6lhrg_1","url":"http://localhost:43127/index.html"}]},"after":{"activeTabId":"tab_msd6mgp7_2","tabs":[{"id":"tab_msd6lhrg_1","url":"http://localhost:43127/index.html"},{"id":"tab_msd6mgp7_2","url":"http://localhost:43127/linked.html"}]}}

ℹ️ FACT — 12. page context menu overlay height matches its rendered content without clipping or a large dead gap

{"overlayHeight":166,"contentHeight":165.25,"metrics":{"ariaLabel":"page context menu","labels":["Cut","Copy","Paste","Select All"],"innerWidth":196,"innerHeight":166,"itemHeights":[34.5625,34.5625,34.5625,34.5625],"separatorFootprints":[13],"menuRect":{"x":1,"y":1,"width":194,"height":163.25,"top":1,"right":195,"bottom":164.25,"left":1},"contentHeight":165.25,"lastItemBottom":158.25,"scrollHeight":166},"visibleTrailingGap":6,"transparentBottomSpace":1.75}

  • PASS page context menu overlay height matches its rendered content without clipping or a large dead gap — {"overlayHeight":166,"contentHeight":165.25,"metrics":{"ariaLabel":"page context menu","labels":["Cut","Copy","Paste","Select All"],"innerWidth":196,"innerHeight":166,"itemHeights":[34.5625,34.5625,34.5625,34.5625],"separatorFootprints":[13],"menuRect":{"x":1,"y":1,"width":194,"height":163.25,"top":1,"right":195,"bottom":164.25,"left":1},"contentHeight":165.25,"lastItemBottom":158.25,"scrollHeight":166},"visibleTrailingGap":6,"transparentBottomSpace":1.75}

ℹ️ FACT — 13. Right-clicking an editable text input exposes Cut / Copy / Paste / Select All

["Cut","Copy","Paste","Select All"]

  • PASS Right-clicking an editable text input exposes Cut / Copy / Paste / Select All — ["Cut","Copy","Paste","Select All"]

✅ PASS — 14. The in-app browser visibly shows Cut, Copy, Paste, and Select All for the text input

  • PASS The in-app browser visibly shows Cut, Copy, Paste, and Select All for the text input — The open context menu beside the editable text field visibly lists “Cut,” “Copy,” “Paste,” and “Select All.”
  • PASS The four-row input menu is fully visible at the magenta click marker and tightly sized without clipping — A compact four-row menu opens at the magenta marker; its full rounded boundary and all four labels are visible without clipping.

The in-app browser visibly shows Cut, Copy, Paste, and Select All for the text input

ℹ️ FACT — 15. page context menu overlay height matches its rendered content without clipping or a large dead gap

{"overlayHeight":49,"contentHeight":48.5625,"metrics":{"ariaLabel":"page context menu","labels":["Copy"],"innerWidth":196,"innerHeight":49,"itemHeights":[34.5625],"separatorFootprints":[],"menuRect":{"x":1,"y":1,"width":194,"height":46.5625,"top":1,"right":195,"bottom":47.5625,"left":1},"contentHeight":48.5625,"lastItemBottom":41.5625,"scrollHeight":49},"visibleTrailingGap":6,"transparentBottomSpace":1.4375}

  • PASS page context menu overlay height matches its rendered content without clipping or a large dead gap — {"overlayHeight":49,"contentHeight":48.5625,"metrics":{"ariaLabel":"page context menu","labels":["Copy"],"innerWidth":196,"innerHeight":49,"itemHeights":[34.5625],"separatorFootprints":[],"menuRect":{"x":1,"y":1,"width":194,"height":46.5625,"top":1,"right":195,"bottom":47.5625,"left":1},"contentHeight":48.5625,"lastItemBottom":41.5625,"scrollHeight":49},"visibleTrailingGap":6,"transparentBottomSpace":1.4375}

ℹ️ FACT — 16. Right-clicking selected non-editable text exposes Copy

["Copy"]

  • PASS Right-clicking selected non-editable text exposes Copy — ["Copy"]

✅ PASS — 17. The selected sentence is visibly highlighted and its context menu contains the single Copy action

  • PASS The selected sentence is visibly highlighted and its context menu contains the single Copy action — The sentence is visibly blue-highlighted, and the open context menu shows only “Copy”.
  • PASS The one-row Copy menu is fully visible at the magenta click marker with no extra blank height below the Copy row — A compact, fully visible one-row “Copy” popup appears beside the magenta marker without an additional blank section below it.

The selected sentence is visibly highlighted and its context menu contains the single Copy action

ℹ️ FACT — 18. page context menu overlay height matches its rendered content without clipping or a large dead gap

{"overlayHeight":200,"contentHeight":199.8125,"metrics":{"ariaLabel":"page context menu","labels":["Back","Forward","Reload","Copy Page URL","Open Page in Browser"],"innerWidth":196,"innerHeight":200,"itemHeights":[34.5625,34.5625,34.5625,34.5625,34.5625],"separatorFootprints":[13],"menuRect":{"x":1,"y":1,"width":194,"height":197.8125,"top":1,"right":195,"bottom":198.8125,"left":1},"contentHeight":199.8125,"lastItemBottom":192.8125,"scrollHeight":200},"visibleTrailingGap":6,"transparentBottomSpace":1.1875}

  • PASS page context menu overlay height matches its rendered content without clipping or a large dead gap — {"overlayHeight":200,"contentHeight":199.8125,"metrics":{"ariaLabel":"page context menu","labels":["Back","Forward","Reload","Copy Page URL","Open Page in Browser"],"innerWidth":196,"innerHeight":200,"itemHeights":[34.5625,34.5625,34.5625,34.5625,34.5625],"separatorFootprints":[13],"menuRect":{"x":1,"y":1,"width":194,"height":197.8125,"top":1,"right":195,"bottom":198.8125,"left":1},"contentHeight":199.8125,"lastItemBottom":192.8125,"scrollHeight":200},"visibleTrailingGap":6,"transparentBottomSpace":1.1875}

ℹ️ FACT — 19. A bottom-right page right-click keeps the complete five-item menu at its calculated item-count height

{"point":{"x":300,"y":711},"edgeMenu":{"ariaLabel":"page context menu","labels":["Back","Forward","Reload","Copy Page URL","Open Page in Browser"],"innerWidth":196,"innerHeight":200,"itemHeights":[34.5625,34.5625,34.5625,34.5625,34.5625],"separatorFootprints":[13],"menuRect":{"x":1,"y":1,"width":194,"height":197.8125,"top":1,"right":195,"bottom":198.8125,"left":1},"contentHeight":199.8125,"lastItemBottom":192.8125,"scrollHeight":200}}

  • PASS A bottom-right page right-click keeps the complete five-item menu at its calculated item-count height — {"point":{"x":300,"y":711},"edgeMenu":{"ariaLabel":"page context menu","labels":["Back","Forward","Reload","Copy Page URL","Open Page in Browser"],"innerWidth":196,"innerHeight":200,"itemHeights":[34.5625,34.5625,34.5625,34.5625,34.5625],"separatorFootprints":[13],"menuRect":{"x":1,"y":1,"width":194,"height":197.8125,"top":1,"right":195,"bottom":198.8125,"left":1},"contentHeight":199.8125,"lastItemBottom":192.8125,"scrollHeight":200}}

✅ PASS — 20. Near the bottom-right browser edge, the complete five-item page context menu is shifted left and up so it remains fully on-screen and unclipped

  • PASS Near the bottom-right browser edge, the complete five-item page context menu is shifted left and up so it remains fully on-screen and unclipped — The full menu is visible inside the browser panel, including Back, Forward, Reload, Copy Page URL, and Open Page in Browser.
  • PASS The magenta click marker is near the menu's bottom-right corner, showing the edge-clamped menu is aligned to the requested click rather than offset — A magenta click marker appears immediately beside the menu’s lower-right corner.
  • PASS The edge menu tightly fits its five rows without a large empty area below Open Page in Browser — The menu ends just below the Open Page in Browser row, with only normal padding and no large empty region.

Near the bottom-right browser edge, the complete five-item page context menu is shifted left and up so it remains fully on-screen and unclipped

ℹ️ FACT — 21. tab context menu overlay height matches its rendered content without clipping or a large dead gap

{"overlayHeight":166,"contentHeight":165.25,"metrics":{"ariaLabel":"tab context menu","labels":["Copy URL","Open in Browser","Close Tab","Close All Tabs"],"innerWidth":196,"innerHeight":166,"itemHeights":[34.5625,34.5625,34.5625,34.5625],"separatorFootprints":[13],"menuRect":{"x":1,"y":1,"width":194,"height":163.25,"top":1,"right":195,"bottom":164.25,"left":1},"contentHeight":165.25,"lastItemBottom":158.25,"scrollHeight":166},"visibleTrailingGap":6,"transparentBottomSpace":1.75}

  • PASS tab context menu overlay height matches its rendered content without clipping or a large dead gap — {"overlayHeight":166,"contentHeight":165.25,"metrics":{"ariaLabel":"tab context menu","labels":["Copy URL","Open in Browser","Close Tab","Close All Tabs"],"innerWidth":196,"innerHeight":166,"itemHeights":[34.5625,34.5625,34.5625,34.5625],"separatorFootprints":[13],"menuRect":{"x":1,"y":1,"width":194,"height":163.25,"top":1,"right":195,"bottom":164.25,"left":1},"contentHeight":165.25,"lastItemBottom":158.25,"scrollHeight":166},"visibleTrailingGap":6,"transparentBottomSpace":1.75}

ℹ️ FACT — 22. Right-clicking the browser tab strip preserves the original four-item tab menu

["Copy URL","Open in Browser","Close Tab","Close All Tabs"]

  • PASS Right-clicking the browser tab strip preserves the original four-item tab menu — ["Copy URL","Open in Browser","Close Tab","Close All Tabs"]

✅ PASS — 23. The browser tab strip visibly shows its original four-item menu: Copy URL, Open in Browser, Close Tab, and Close All Tabs

  • PASS The browser tab strip visibly shows its original four-item menu: Copy URL, Open in Browser, Close Tab, and Close All Tabs — The open tab menu visibly lists “Copy URL,” “Open in Browser,” “Close Tab,” and “Close All Tabs.”
  • PASS The tab context menu is fully visible beside the right-clicked tab and tightly fits its four rows — The complete compact menu is visible directly beneath/beside the browser tab, with all four rows contained in its bounds.

The browser tab strip visibly shows its original four-item menu: Copy URL, Open in Browser, Close Tab, and Close All Tabs

ℹ️ FACT — 24. navigator.credentials.get({ publicKey }) settles under 2s with a real NotAllowedError DOMException

{"settled":true,"elapsedMs":0.5999999999767169,"resolved":false,"name":"NotAllowedError","isDomException":true,"constructorName":"DOMException"}

  • PASS navigator.credentials.get({ publicKey }) settles under 2s with a real NotAllowedError DOMException — {"settled":true,"elapsedMs":0.5999999999767169,"resolved":false,"name":"NotAllowedError","isDomException":true,"constructorName":"DOMException"}

ℹ️ FACT — 25. The passkey fast-fail offers Open in your browser

["Open in your browser"]

  • PASS The passkey fast-fail offers Open in your browser — ["Open in your browser"]

✅ PASS — 26. The in-app browser visibly offers Open in your browser after the fixture requests a passkey

  • PASS The in-app browser visibly offers Open in your browser after the fixture requests a passkey — Visible passkey popup says “Open this page to use a passkey” and offers “Open in your browser.”
  • PASS The passkey fallback explains that the built-in browser cannot use passkeys yet, and the overlay is fully visible and unclipped — The fully visible overlay states: “This site asked for a passkey, but OpenWork’s built-in browser can’t use passkeys yet.”

The in-app browser visibly offers Open in your browser after the fixture requests a passkey


Roll created 2026-08-03T12:04:13.288Z · Source: evals/results/rolls/2026-08-03T12-04-13-288Z-built-in-browser-page-menus-and-passkeys-work-in-electron-with-os-level-visual-e/roll.json · Repro: pnpm fraimz:publish -- --pr 3459 --roll 2026-08-03T12-04-13-288Z-built-in-browser-page-menus-and-passkeys-work-in-electron-with-os-level-visual-e

Comment thread evals/specs/builtin-browser-context-menu-passkey.slow.test.ts
Electron only gained a working WebAuthn platform authenticator in 41.5.0
via app.configureWebAuthn; 35.x had no authenticator at all.

- Electron 35.7.5 -> 41.10.3 (Chromium 146, Node 24, native ABI 141->145)
- force native rebuilds so better-sqlite3 and node-pty match the new ABI
- add the keychain-access-groups entitlement, kept in sync with the
  signing Team ID from a single source of truth
- call configureWebAuthn first inside whenReady(); calling it earlier
  trips a native SIGTRAP

Touch ID credentials are device-bound and macOS-only: iCloud, 1Password,
phone and USB-key passkeys are still not usable, so the fast-fail
fallback stays in place for them.
Chromium 146 enforces that clipboard writes come from a focused
document, which exposed that hiding the overlay never handed focus back
to the page. Copy actions from the page context menu silently failed on
Electron 41.

@diff-warden diff-warden Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warden security clearance: clear. No new security issues found in this diff (f6b7db2f0031b3eabe82e0dc2e96d15cf0a724b2). Automated clearance satisfies the required-review gate only — a human still reviews and merges. Analysis run

@benjaminshafii
benjaminshafii merged commit d720739 into dev Aug 3, 2026
26 checks passed
benjaminshafii added a commit that referenced this pull request Aug 3, 2026
…d stop passkey requests hanging for 3 minutes (#3459)" (#3465)

This reverts commit d720739.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant