From c69a63d0866dac9583404082a6ed6d7b506fcc09 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 26 May 2026 18:22:06 +0000 Subject: [PATCH 1/2] fix(react-ui): fix OAuth prefetch race when dialog opens before auth init Co-Authored-By: Jonathan Derbyshire --- .../client/ui/react-ui/src/hooks/useOAuthWindowListener.ts | 2 +- .../ui/react-ui/src/providers/CrossmintAuthProvider.tsx | 2 +- .../ui/react-ui/src/providers/auth/OAuthFlowProvider.tsx | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/client/ui/react-ui/src/hooks/useOAuthWindowListener.ts b/packages/client/ui/react-ui/src/hooks/useOAuthWindowListener.ts index 0fc7a6891..a879ca0d9 100644 --- a/packages/client/ui/react-ui/src/hooks/useOAuthWindowListener.ts +++ b/packages/client/ui/react-ui/src/hooks/useOAuthWindowListener.ts @@ -48,7 +48,7 @@ export const useOAuthWindowListener = (oauthUrlMap: OAuthUrlMap, setError: (erro const prefetchedUrl = oauthUrlMap[provider]; const resolvedUrl = prefetchedUrl || (await crossmintAuth?.getOAuthUrl(provider)); - if (resolvedUrl == null) { + if (!resolvedUrl) { throw new Error("Failed to resolve OAuth URL"); } baseUrl = new URL(resolvedUrl); diff --git a/packages/client/ui/react-ui/src/providers/CrossmintAuthProvider.tsx b/packages/client/ui/react-ui/src/providers/CrossmintAuthProvider.tsx index 3a049c96e..62881b279 100644 --- a/packages/client/ui/react-ui/src/providers/CrossmintAuthProvider.tsx +++ b/packages/client/ui/react-ui/src/providers/CrossmintAuthProvider.tsx @@ -128,7 +128,7 @@ function CrossmintAuthProviderContent({ defaultEmail, }} > - + {children} diff --git a/packages/client/ui/react-ui/src/providers/auth/OAuthFlowProvider.tsx b/packages/client/ui/react-ui/src/providers/auth/OAuthFlowProvider.tsx index d13260ddf..ecc39e464 100644 --- a/packages/client/ui/react-ui/src/providers/auth/OAuthFlowProvider.tsx +++ b/packages/client/ui/react-ui/src/providers/auth/OAuthFlowProvider.tsx @@ -38,7 +38,7 @@ export function OAuthFlowProvider({ const { setError } = useAuthForm(); const [oauthUrlMap, setOauthUrlMap] = useState(initialOAuthUrlMap); - const [isLoadingOauthUrlMap, setIsLoadingOauthUrlMap] = useState(true); + const [isLoadingOauthUrlMap, setIsLoadingOauthUrlMap] = useState(false); const { createPopupAndSetupListeners, @@ -47,6 +47,9 @@ export function OAuthFlowProvider({ } = useOAuthWindowListener(oauthUrlMap, setError); const preFetchAndSetOauthUrl = useCallback(async () => { + if (crossmintAuth == null) { + return; + } setIsLoadingOauthUrlMap(true); try { const oauthProviders = (loginMethods || []).filter( From bb644163dae8014776674d14dc1796b76604a0c1 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 26 May 2026 18:22:32 +0000 Subject: [PATCH 2/2] chore: add changeset for OAuth prefetch fix Co-Authored-By: Jonathan Derbyshire --- .changeset/fix-oauth-prefetch-race.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .changeset/fix-oauth-prefetch-race.md diff --git a/.changeset/fix-oauth-prefetch-race.md b/.changeset/fix-oauth-prefetch-race.md new file mode 100644 index 000000000..9cf755b02 --- /dev/null +++ b/.changeset/fix-oauth-prefetch-race.md @@ -0,0 +1,10 @@ +--- +"@crossmint/client-sdk-react-ui": patch +--- + +Fix OAuth URL prefetch race condition when auth dialog opens before initialization completes. + +- Gate prefetch on `jwt == null` instead of `getAuthStatus() === "logged-out"` so the prefetch still runs when the dialog is open during initialization. +- Skip prefetch when `crossmintAuth` is not yet available to avoid fetching with a null client. +- Initialize `isLoadingOauthUrlMap` to `false` so consumers are not stuck in a loading state when the prefetch has not started. +- Strengthen URL validation to reject empty strings in addition to null/undefined.