authorgravatar for me@t3.ggTheo Browne <me@t3.gg> 2026-08-19 06:59:26-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-19 03:59:26-07:00
logf2d5fc91e3030e5c3956fdadc13e1eaa25bcabe3
tree73cf06dd171b24cd61e96bc37001f795eb6d671b
parent24c4ba68f536d56e8482a1e4d7070a6771da551d
signature Signed by PGP key B5690EEEBB952194

fix(desktop): stop automatic passkey prompts (#7522)


4 files changed, 105 insertions(+), 44 deletions(-)

apps/web/src/components/clerk/electronPasskeys.test.ts created+60
...@@ -0,0 +1,60 @@
1import { createPasskeys } from "@clerk/electron/passkeys";
2import { afterEach, describe, expect, it, vi } from "vite-plus/test";
3
4const publicKeyOptions = {
5 allowCredentials: [],
6 challenge: new Uint8Array([1]),
7 rpId: "clerk.t3.codes",
8 timeout: 60_000,
9 userVerification: "preferred" as const,
10};
11
12const stubNativePasskeys = () => {
13 const get = vi.fn().mockResolvedValue({
14 ok: false,
15 error: { code: "cancelled", message: "user cancelled" },
16 });
17
18 vi.stubGlobal("location", { protocol: "t3code:", hostname: "app" });
19 vi.stubGlobal("window", {
20 PublicKeyCredential: vi.fn(),
21 __clerk_internal_electron_passkeys: {
22 platform: "darwin",
23 electronMajor: 41,
24 get,
25 },
26 });
27
28 return get;
29};
30
31describe("Electron passkeys", () => {
32 afterEach(() => {
33 vi.unstubAllGlobals();
34 });
35
36 it("does not send an autofill request to the native bridge", async () => {
37 const get = stubNativePasskeys();
38 const passkeys = createPasskeys();
39
40 const result = await passkeys.get({
41 publicKeyOptions,
42 conditionalUI: true,
43 });
44
45 expect(get).not.toHaveBeenCalled();
46 expect(result.error).toMatchObject({ code: "passkey_operation_aborted" });
47 });
48
49 it("sends an explicit passkey request to the native bridge", async () => {
50 const get = stubNativePasskeys();
51 const passkeys = createPasskeys();
52
53 await passkeys.get({
54 publicKeyOptions,
55 conditionalUI: false,
56 });
57
58 expect(get).toHaveBeenCalledOnce();
59 });
60});
apps/web/src/main.tsx+5-9
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1import React from "react";1import React from "react";
2import ReactDOM from "react-dom/client";2import ReactDOM from "react-dom/client";
3import { ClerkProvider } from "@clerk/react";3import { ClerkProvider } from "@clerk/react";
4import { passkeys as electronPasskeys } from "@clerk/electron/passkeys";4import { passkeys } from "@clerk/electron/passkeys";
5import { ClerkProvider as ElectronClerkProvider } from "@clerk/electron/react";5import { ClerkProvider as ElectronClerkProvider } from "@clerk/electron/react";
6import { createHashHistory, createBrowserHistory } from "@tanstack/react-router";6import { createHashHistory, createBrowserHistory } from "@tanstack/react-router";
77
...@@ -30,14 +30,9 @@ if (isElectron) {...@@ -30,14 +30,9 @@ if (isElectron) {
3030
31const clerkPublishableKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY as string | undefined;31const clerkPublishableKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY as string | undefined;
3232
33// @clerk/electron reports passkey autofill as supported but executes the33// First Clerk UI build containing https://github.com/clerk/javascript/pull/9500.
34// "quiet" autofill request as a modal prompt, so Clerk's sign-in form pops an34const electronClerkUI = {
35// OS passkey dialog the moment it mounts. Report autofill as unsupported; the35 __internal_clerkUIVersion: "1.30.5-canary.v20260819050620",
36// explicit "Use passkey" button keeps working.
37// Upstream: https://github.com/clerk/javascript/issues/9496
38const passkeys = {
39 ...electronPasskeys,
40 isAutoFillSupported: () => Promise.resolve(false),
41};36};
4237
43const app = <AppRoot router={router} />;38const app = <AppRoot router={router} />;
...@@ -47,6 +42,7 @@ ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(...@@ -47,6 +42,7 @@ ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
47 {clerkPublishableKey && hasCloudPublicConfig() ? (42 {clerkPublishableKey && hasCloudPublicConfig() ? (
48 isElectron ? (43 isElectron ? (
49 <ElectronClerkProvider44 <ElectronClerkProvider
45 {...electronClerkUI}
50 appearance={clerkAppearance}46 appearance={clerkAppearance}
51 publishableKey={clerkPublishableKey}47 publishableKey={clerkPublishableKey}
52 passkeys={passkeys}48 passkeys={passkeys}
pnpm-lock.yaml+32-32
...@@ -46,8 +46,8 @@ overrides:...@@ -46,8 +46,8 @@ overrides:
46 '@clerk/clerk-js>@solana/wallet-adapter-react': '-'46 '@clerk/clerk-js>@solana/wallet-adapter-react': '-'
47 '@clerk/clerk-js>@solana/wallet-standard': '-'47 '@clerk/clerk-js>@solana/wallet-standard': '-'
48 '@clerk/clerk-js>@wallet-standard/core': '-'48 '@clerk/clerk-js>@wallet-standard/core': '-'
49 '@clerk/electron': 0.0.3349 '@clerk/electron': 0.0.34-canary.v20260819050620
50 '@clerk/electron-passkeys': 0.0.350 '@clerk/electron-passkeys': 0.0.4-canary.v20260819050620
51 '@clerk/expo': 4.2.051 '@clerk/expo': 4.2.0
52 '@clerk/react': 6.14.452 '@clerk/react': 6.14.4
53 '@clerk/shared': 4.29.253 '@clerk/shared': 4.29.2
...@@ -114,11 +114,11 @@ importers:...@@ -114,11 +114,11 @@ importers:
114 apps/desktop:114 apps/desktop:
115 dependencies:115 dependencies:
116 '@clerk/electron':116 '@clerk/electron':
117 specifier: 0.0.33117 specifier: 0.0.34-canary.v20260819050620
118 version: 0.0.33(@clerk/electron-passkeys@0.0.3)(electron-store@8.2.0)(electron@41.5.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)118 version: 0.0.34-canary.v20260819050620(@clerk/electron-passkeys@0.0.4-canary.v20260819050620)(electron-store@8.2.0)(electron@41.5.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
119 '@clerk/electron-passkeys':119 '@clerk/electron-passkeys':
120 specifier: 0.0.3120 specifier: 0.0.4-canary.v20260819050620
121 version: 0.0.3121 version: 0.0.4-canary.v20260819050620
122 '@effect/platform-node':122 '@effect/platform-node':
123 specifier: 4.0.0-beta.103123 specifier: 4.0.0-beta.103
124 version: 4.0.0-beta.103(bufferutil@4.1.0)(effect@4.0.0-beta.103(patch_hash=af36b7948b6f9c56623074662b51dade5699880c1a7c71245de73e13c3185fb6))(ioredis@5.11.0)(utf-8-validate@6.0.6)124 version: 4.0.0-beta.103(bufferutil@4.1.0)(effect@4.0.0-beta.103(patch_hash=af36b7948b6f9c56623074662b51dade5699880c1a7c71245de73e13c3185fb6))(ioredis@5.11.0)(utf-8-validate@6.0.6)
...@@ -520,8 +520,8 @@ importers:...@@ -520,8 +520,8 @@ importers:
520 specifier: ^1.4.1520 specifier: ^1.4.1
521 version: 1.5.0(@types/react@19.2.16)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)521 version: 1.5.0(@types/react@19.2.16)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
522 '@clerk/electron':522 '@clerk/electron':
523 specifier: 0.0.33523 specifier: 0.0.34-canary.v20260819050620
524 version: 0.0.33(@clerk/electron-passkeys@0.0.3)(electron-store@8.2.0)(electron@41.5.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)524 version: 0.0.34-canary.v20260819050620(@clerk/electron-passkeys@0.0.4-canary.v20260819050620)(electron-store@8.2.0)(electron@41.5.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
525 '@clerk/react':525 '@clerk/react':
526 specifier: 6.14.4526 specifier: 6.14.4
527 version: 6.14.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6)527 version: 6.14.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
...@@ -1721,35 +1721,35 @@ packages:...@@ -1721,35 +1721,35 @@ packages:
1721 resolution: {integrity: sha512-4i4RE+ZQ0hKDDFSRKCISQPBy07SfFeFAhBUhNj2j01Nx2n4pqV+5iyg2Vf27+NKFNkgq7kdmZGvtug24D++8WQ==}1721 resolution: {integrity: sha512-4i4RE+ZQ0hKDDFSRKCISQPBy07SfFeFAhBUhNj2j01Nx2n4pqV+5iyg2Vf27+NKFNkgq7kdmZGvtug24D++8WQ==}
1722 engines: {node: '>=20.9.0'}1722 engines: {node: '>=20.9.0'}
17231723
1724 '@clerk/electron-passkeys-darwin-arm64@0.0.3':1724 '@clerk/electron-passkeys-darwin-arm64@0.0.4-canary.v20260819050620':
1725 resolution: {integrity: sha512-oAlrd+GLqP0oREP3hNRc6yNZhXGaQgJss9iCWRQqXjpw1yZD1ZU+L+E2Gfg84vMj/NSUhxbU0Djy0RXhmeUwgg==}1725 resolution: {integrity: sha512-avxygtEfWBD3YPkxws4lB5mL/75SQvVBMQCg+b1gjFsQInnVOgAqAv4wHR8wgUsEbXY2zEkvqaYjFSnEveC0VA==}
1726 cpu: [arm64]1726 cpu: [arm64]
1727 os: [darwin]1727 os: [darwin]
17281728
1729 '@clerk/electron-passkeys-darwin-x64@0.0.3':1729 '@clerk/electron-passkeys-darwin-x64@0.0.4-canary.v20260819050620':
1730 resolution: {integrity: sha512-0UPAWQEni7o8gjWwd2sP97fPshJmT2w5b8eV/jOPVSP8NqIcFCm5yIFSEx1SfB53LGfzB01A4iEGi2pxiCHqyQ==}1730 resolution: {integrity: sha512-clShldbwDcC2ek6gJT85QKsMfaPyOhEgfz61u2n3YKivbeui33XjJu261d+LO20mqDjXZy3flLGPTIh/Kii80g==}
1731 cpu: [x64]1731 cpu: [x64]
1732 os: [darwin]1732 os: [darwin]
17331733
1734 '@clerk/electron-passkeys-win32-arm64-msvc@0.0.3':1734 '@clerk/electron-passkeys-win32-arm64-msvc@0.0.4-canary.v20260819050620':
1735 resolution: {integrity: sha512-bbRvifm9A/gfPkwC1UyMyF9sYGEs0aen7J2kCcaOIW3K0PXcAbHtsR/gnx4dT0bjFdd21vSa2zlIdERvHc1BiA==}1735 resolution: {integrity: sha512-alIfXJSxyeulnNeHoT4X7+qO0o9/EBhiRWMhCXwKJIbWfwzqnnVrRH1P7HfYRnDepKhqRzsUaBuYTqQzisHG+A==}
1736 cpu: [arm64]1736 cpu: [arm64]
1737 os: [win32]1737 os: [win32]
17381738
1739 '@clerk/electron-passkeys-win32-x64-msvc@0.0.3':1739 '@clerk/electron-passkeys-win32-x64-msvc@0.0.4-canary.v20260819050620':
1740 resolution: {integrity: sha512-gFaVqKlOKTF2SJ3lMwkZ0oonycQn93p1qSrp5kzzeZBeQ+tGB3gQnjXecrhQy21AzDUyWqVJJ8KrP2HRAwifWg==}1740 resolution: {integrity: sha512-QSKKMCdV9AhOt74ls8ExdwR+2ikoLGgN2LdWIjBgNk6epJVs2L1FXVZOM0ZqfVHFSl5y7vLmlOACR6WyJ2eoLg==}
1741 cpu: [x64]1741 cpu: [x64]
1742 os: [win32]1742 os: [win32]
17431743
1744 '@clerk/electron-passkeys@0.0.3':1744 '@clerk/electron-passkeys@0.0.4-canary.v20260819050620':
1745 resolution: {integrity: sha512-OHhIe88qDL+FxyBalXdXNHAS5eEramr6Rerp+6iNkfkjqT8rx4hHNmfpmjg5/T1/am8QfknbOBZkqoXZlCrjPg==}1745 resolution: {integrity: sha512-zOoFEsvOrArv7p4ERNAdkGbYoD86ragDhysLG1NdxJm2jnfw+AfwxUv0FkOPZ7iNuQ0rbJaR/urxdvEwVcuKRA==}
1746 engines: {node: '>=20.9.0'}1746 engines: {node: '>=20.9.0'}
17471747
1748 '@clerk/electron@0.0.33':1748 '@clerk/electron@0.0.34-canary.v20260819050620':
1749 resolution: {integrity: sha512-lP2B7wGHwKWrCAh4zPWPfRUIHoxQ1rwG8iiFeLmI8jBjSGcSoPX1N9bIKUCWL+Z9POmC2aRn6yXvL7e9yzfEVw==}1749 resolution: {integrity: sha512-sfKWkH2SigKcxtR+h36G1NGnmMI5xOlwvqHpr3JYcacS/uokQbeAjCCQzEeV/9zqWYtRL4et5wCD13+gWv4b6w==}
1750 engines: {node: '>=20.9.0'}1750 engines: {node: '>=20.9.0'}
1751 peerDependencies:1751 peerDependencies:
1752 '@clerk/electron-passkeys': 0.0.31752 '@clerk/electron-passkeys': 0.0.4-canary.v20260819050620
1753 electron: '>=28'1753 electron: '>=28'
1754 electron-store: ^8.2.01754 electron-store: ^8.2.0
1755 react: ^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-01755 react: ^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0
...@@ -11580,26 +11580,26 @@ snapshots:...@@ -11580,26 +11580,26 @@ snapshots:
11580 - react11580 - react
11581 - react-dom11581 - react-dom
1158211582
11583 '@clerk/electron-passkeys-darwin-arm64@0.0.3':11583 '@clerk/electron-passkeys-darwin-arm64@0.0.4-canary.v20260819050620':
11584 optional: true11584 optional: true
1158511585
11586 '@clerk/electron-passkeys-darwin-x64@0.0.3':11586 '@clerk/electron-passkeys-darwin-x64@0.0.4-canary.v20260819050620':
11587 optional: true11587 optional: true
1158811588
11589 '@clerk/electron-passkeys-win32-arm64-msvc@0.0.3':11589 '@clerk/electron-passkeys-win32-arm64-msvc@0.0.4-canary.v20260819050620':
11590 optional: true11590 optional: true
1159111591
11592 '@clerk/electron-passkeys-win32-x64-msvc@0.0.3':11592 '@clerk/electron-passkeys-win32-x64-msvc@0.0.4-canary.v20260819050620':
11593 optional: true11593 optional: true
1159411594
11595 '@clerk/electron-passkeys@0.0.3':11595 '@clerk/electron-passkeys@0.0.4-canary.v20260819050620':
11596 optionalDependencies:11596 optionalDependencies:
11597 '@clerk/electron-passkeys-darwin-arm64': 0.0.311597 '@clerk/electron-passkeys-darwin-arm64': 0.0.4-canary.v20260819050620
11598 '@clerk/electron-passkeys-darwin-x64': 0.0.311598 '@clerk/electron-passkeys-darwin-x64': 0.0.4-canary.v20260819050620
11599 '@clerk/electron-passkeys-win32-arm64-msvc': 0.0.311599 '@clerk/electron-passkeys-win32-arm64-msvc': 0.0.4-canary.v20260819050620
11600 '@clerk/electron-passkeys-win32-x64-msvc': 0.0.311600 '@clerk/electron-passkeys-win32-x64-msvc': 0.0.4-canary.v20260819050620
1160111601
11602 '@clerk/electron@0.0.33(@clerk/electron-passkeys@0.0.3)(electron-store@8.2.0)(electron@41.5.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':11602 '@clerk/electron@0.0.34-canary.v20260819050620(@clerk/electron-passkeys@0.0.4-canary.v20260819050620)(electron-store@8.2.0)(electron@41.5.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
11603 dependencies:11603 dependencies:
11604 '@clerk/clerk-js': 6.29.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6)11604 '@clerk/clerk-js': 6.29.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
11605 '@clerk/react': 6.14.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6)11605 '@clerk/react': 6.14.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
...@@ -11608,7 +11608,7 @@ snapshots:...@@ -11608,7 +11608,7 @@ snapshots:
11608 react: 19.2.611608 react: 19.2.6
11609 tslib: 2.8.111609 tslib: 2.8.1
11610 optionalDependencies:11610 optionalDependencies:
11611 '@clerk/electron-passkeys': 0.0.311611 '@clerk/electron-passkeys': 0.0.4-canary.v20260819050620
11612 electron-store: 8.2.011612 electron-store: 8.2.0
11613 react-dom: 19.2.6(react@19.2.6)11613 react-dom: 19.2.6(react@19.2.6)
1161411614
pnpm-workspace.yaml+8-3
...@@ -25,8 +25,8 @@ allowBuilds:...@@ -25,8 +25,8 @@ allowBuilds:
25catalog:25catalog:
26 "@clerk/backend": 3.14.026 "@clerk/backend": 3.14.0
27 "@clerk/clerk-js": 6.29.227 "@clerk/clerk-js": 6.29.2
28 "@clerk/electron": 0.0.3328 "@clerk/electron": 0.0.34-canary.v20260819050620
29 "@clerk/electron-passkeys": 0.0.329 "@clerk/electron-passkeys": 0.0.4-canary.v20260819050620
30 "@clerk/expo": 4.2.030 "@clerk/expo": 4.2.0
31 "@clerk/react": 6.14.431 "@clerk/react": 6.14.4
32 "@clerk/shared": 4.29.232 "@clerk/shared": 4.29.2
...@@ -55,7 +55,8 @@ catalog:...@@ -55,7 +55,8 @@ catalog:
55minimumReleaseAgeExclude:55minimumReleaseAgeExclude:
56 - "@clerk/backend@3.14.0"56 - "@clerk/backend@3.14.0"
57 - "@clerk/clerk-js@6.29.2"57 - "@clerk/clerk-js@6.29.2"
58 - "@clerk/electron@0.0.33"58 - "@clerk/electron@0.0.34-canary.v20260819050620"
59 - "@clerk/electron-passkeys@0.0.4-canary.v20260819050620"
59 - "@clerk/expo@4.2.0"60 - "@clerk/expo@4.2.0"
60 - "@clerk/react@6.14.4"61 - "@clerk/react@6.14.4"
61 - "@clerk/shared@4.29.2"62 - "@clerk/shared@4.29.2"
...@@ -76,6 +77,10 @@ minimumReleaseAgeExclude:...@@ -76,6 +77,10 @@ minimumReleaseAgeExclude:
76 - alchemy@2.0.0-beta.6577 - alchemy@2.0.0-beta.65
77 - effect@4.0.0-beta.10378 - effect@4.0.0-beta.103
78 - "@legendapp/list@3.3.5"79 - "@legendapp/list@3.3.5"
80 - "@clerk/electron-passkeys-darwin-arm64@0.0.4-canary.v20260819050620"
81 - "@clerk/electron-passkeys-darwin-x64@0.0.4-canary.v20260819050620"
82 - "@clerk/electron-passkeys-win32-arm64-msvc@0.0.4-canary.v20260819050620"
83 - "@clerk/electron-passkeys-win32-x64-msvc@0.0.4-canary.v20260819050620"
7984
80overrides:85overrides:
81 "@clerk/backend": "catalog:"86 "@clerk/backend": "catalog:"