| author | |
| committer | |
| log | 1b4830ff06bf80e505dbf669deef189af85f77d7 |
| tree | f2214ae794823b509bf13ee42764eadb1c6da7d6 |
| parent | 694f8d1c6eaaabafbf5c2861ae524174919ef625 |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: Julius Marminge <julius0216@outlook.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>4 files changed, 40 insertions(+), 3 deletions(-)
apps/web/src/components/clerk/authRedirect.test.ts created+18| ... | @@ -0,0 +1,18 @@ | ||
| 1 | import { describe, expect, it } from "vite-plus/test"; | ||
| 2 | |||
| 3 | import { resolveClerkSignInProps } from "./authRedirect"; | ||
| 4 | |||
| 5 | describe("resolveClerkSignInProps", () => { | ||
| 6 | it("returns to the current browser URL on the web", () => { | ||
| 7 | const href = "https://app.t3.codes/connect?state=state-1#details"; | ||
| 8 | expect(resolveClerkSignInProps(href, false)).toEqual({ forceRedirectUrl: href }); | ||
| 9 | }); | ||
| 10 | |||
| 11 | it("omits the redirect override on packaged desktop", () => { | ||
| 12 | expect(resolveClerkSignInProps("t3code://app/#/settings/general", true)).toEqual({}); | ||
| 13 | }); | ||
| 14 | |||
| 15 | it("omits the redirect override on development desktop", () => { | ||
| 16 | expect(resolveClerkSignInProps("t3code-dev://app/#/settings/general", true)).toEqual({}); | ||
| 17 | }); | ||
| 18 | }); | ||
apps/web/src/components/clerk/authRedirect.ts created+12| ... | @@ -0,0 +1,12 @@ | ||
| 1 | export interface ClerkSignInProps { | ||
| 2 | forceRedirectUrl?: string; | ||
| 3 | } | ||
| 4 | |||
| 5 | // Clerk's native-app allowlist only authorizes the bare renderer root | ||
| 6 | // (t3code://app/), which @clerk/electron's OAuth transport already supplies, | ||
| 7 | // so any page-derived redirect override gets the whole sign-in request | ||
| 8 | // rejected. On Electron, omit the override and let Clerk use its defaults. | ||
| 9 | export function resolveClerkSignInProps(href: string, isElectron: boolean): ClerkSignInProps { | ||
| 10 | if (isElectron) return {}; | ||
| 11 | return { forceRedirectUrl: href }; | ||
| 12 | } | ||
apps/web/src/components/clerk/useT3ConnectAuthPrompt.tsx+4-1| ... | @@ -1,9 +1,12 @@ | ... | @@ -1,9 +1,12 @@ |
| 1 | import { useClerk } from "@clerk/react"; | 1 | import { useClerk } from "@clerk/react"; |
| 2 | 2 | ||
| 3 | import { isElectron } from "../../env"; | ||
| 4 | import { resolveClerkSignInProps } from "./authRedirect"; | ||
| 5 | |||
| 3 | export function useT3ConnectAuthPrompt() { | 6 | export function useT3ConnectAuthPrompt() { |
| 4 | const clerk = useClerk(); | 7 | const clerk = useClerk(); |
| 5 | const openAuthPrompt = () => { | 8 | const openAuthPrompt = () => { |
| 6 | clerk.openSignIn({ forceRedirectUrl: window.location.href }); | 9 | clerk.openSignIn(resolveClerkSignInProps(window.location.href, isElectron)); |
| 7 | }; | 10 | }; |
| 8 | return { authPrompt: null, openAuthPrompt }; | 11 | return { authPrompt: null, openAuthPrompt }; |
| 9 | } | 12 | } |
apps/web/src/components/cloud/ConnectCliAuthSurface.tsx+6-2| ... | @@ -8,8 +8,10 @@ import { | ... | @@ -8,8 +8,10 @@ import { |
| 8 | readConnectCliCallbackResult, | 8 | readConnectCliCallbackResult, |
| 9 | rememberConnectCliAuthState, | 9 | rememberConnectCliAuthState, |
| 10 | } from "../../cloud/connectCliAuth"; | 10 | } from "../../cloud/connectCliAuth"; |
| 11 | import { isElectron } from "../../env"; | ||
| 11 | import { useCopyToClipboard } from "../../hooks/useCopyToClipboard"; | 12 | import { useCopyToClipboard } from "../../hooks/useCopyToClipboard"; |
| 12 | import { AuthSurfaceShell } from "../auth/AuthSurfaceShell"; | 13 | import { AuthSurfaceShell } from "../auth/AuthSurfaceShell"; |
| 14 | import { resolveClerkSignInProps } from "../clerk/authRedirect"; | ||
| 13 | import { Button } from "../ui/button"; | 15 | import { Button } from "../ui/button"; |
| 14 | 16 | ||
| 15 | function ConnectCliAuthMessage({ | 17 | function ConnectCliAuthMessage({ |
| ... | @@ -59,7 +61,7 @@ export function ConnectCliAuthorizeSurface() { | ... | @@ -59,7 +61,7 @@ export function ConnectCliAuthorizeSurface() { |
| 59 | if (!isSignedIn) { | 61 | if (!isSignedIn) { |
| 60 | if (!signInOpened.current) { | 62 | if (!signInOpened.current) { |
| 61 | signInOpened.current = true; | 63 | signInOpened.current = true; |
| 62 | clerk.openSignIn({ forceRedirectUrl: window.location.href }); | 64 | clerk.openSignIn(resolveClerkSignInProps(window.location.href, isElectron)); |
| 63 | } | 65 | } |
| 64 | return; | 66 | return; |
| 65 | } | 67 | } |
| ... | @@ -95,7 +97,9 @@ export function ConnectCliAuthorizeSurface() { | ... | @@ -95,7 +97,9 @@ export function ConnectCliAuthorizeSurface() { |
| 95 | <div className="mt-6"> | 97 | <div className="mt-6"> |
| 96 | <Button | 98 | <Button |
| 97 | type="button" | 99 | type="button" |
| 98 | onClick={() => clerk.openSignIn({ forceRedirectUrl: window.location.href })} | 100 | onClick={() => |
| 101 | clerk.openSignIn(resolveClerkSignInProps(window.location.href, isElectron)) | ||
| 102 | } | ||
| 99 | > | 103 | > |
| 100 | Sign in | 104 | Sign in |
| 101 | </Button> | 105 | </Button> |