From a031b607d77211c6d4ed56618c412f1557a33242 Mon Sep 17 00:00:00 2001 From: Dylan Staley <88163+dstaley@users.noreply.github.com> Date: Wed, 2 Apr 2025 13:44:58 -0700 Subject: [PATCH] fix(clerk-js): Only refresh when auth with popup is called --- .changeset/curly-carrots-invite.md | 5 +++++ packages/clerk-js/src/core/clerk.ts | 22 +++++++++++++++++-- packages/clerk-js/src/core/constants.ts | 2 ++ .../components/SignIn/SignInSocialButtons.tsx | 7 ++++++ .../components/SignUp/SignUpSocialButtons.tsx | 7 ++++++ 5 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 .changeset/curly-carrots-invite.md diff --git a/.changeset/curly-carrots-invite.md b/.changeset/curly-carrots-invite.md new file mode 100644 index 00000000000..f842b4c6b38 --- /dev/null +++ b/.changeset/curly-carrots-invite.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Only refresh signIn and signUp resources during an SSO callback if the authentication was performed via a popup. diff --git a/packages/clerk-js/src/core/clerk.ts b/packages/clerk-js/src/core/clerk.ts index 23b07d02abb..4b62ea82d3d 100644 --- a/packages/clerk-js/src/core/clerk.ts +++ b/packages/clerk-js/src/core/clerk.ts @@ -112,7 +112,13 @@ import { memoizeListenerCallback } from '../utils/memoizeStateListenerCallback'; import { RedirectUrls } from '../utils/redirectUrls'; import { AuthCookieService } from './auth/AuthCookieService'; import { CaptchaHeartbeat } from './auth/CaptchaHeartbeat'; -import { CLERK_SATELLITE_URL, CLERK_SUFFIXED_COOKIES, CLERK_SYNCED, ERROR_CODES } from './constants'; +import { + CLERK_SATELLITE_URL, + CLERK_SUFFIXED_COOKIES, + CLERK_SYNCED, + ERROR_CODES, + SESSION_STORAGE_AUTH_WITH_POPUP_KEY, +} from './constants'; import { clerkErrorInitFailed, clerkInvalidSignInUrlFormat, @@ -1507,11 +1513,23 @@ export class Clerk implements ClerkInterface { return; } + let shouldRefreshResources = false; + try { + const hasCalledAuthWithPopup = sessionStorage.getItem(SESSION_STORAGE_AUTH_WITH_POPUP_KEY); + if (hasCalledAuthWithPopup) { + shouldRefreshResources = true; + } + } catch { + // In the event that sessionStorage is disabled, assume the resource needs to be refreshed. Refreshing when not + // needed doesn't break anything, but it does cause 405 network errors. + shouldRefreshResources = true; + } + // If `handleRedirectCallback` is called on a window without an opener property (such as when the OAuth flow popup // directs the opening page to navigate to the /sso-callback route), we need to reload the signIn and signUp resources // to ensure that we have the latest state. This operation can fail when we try reloading a resource that doesn't // exist (such as when reloading a signIn resource during a signUp attempt), but this can be safely ignored. - if (!window.opener) { + if (!window.opener && shouldRefreshResources) { try { await signIn.reload(); } catch { diff --git a/packages/clerk-js/src/core/constants.ts b/packages/clerk-js/src/core/constants.ts index 347b6263b9f..53398f1e782 100644 --- a/packages/clerk-js/src/core/constants.ts +++ b/packages/clerk-js/src/core/constants.ts @@ -51,3 +51,5 @@ export const SIGN_UP_MODES: Record = { // This is the currently supported version of the Frontend API export const SUPPORTED_FAPI_VERSION = '2024-10-01'; + +export const SESSION_STORAGE_AUTH_WITH_POPUP_KEY = 'hasUsedAuthenticateWithPopup'; diff --git a/packages/clerk-js/src/ui/components/SignIn/SignInSocialButtons.tsx b/packages/clerk-js/src/ui/components/SignIn/SignInSocialButtons.tsx index 5a3754a9db1..e0d8ab76e50 100644 --- a/packages/clerk-js/src/ui/components/SignIn/SignInSocialButtons.tsx +++ b/packages/clerk-js/src/ui/components/SignIn/SignInSocialButtons.tsx @@ -1,6 +1,7 @@ import { useClerk } from '@clerk/shared/react'; import React from 'react'; +import { SESSION_STORAGE_AUTH_WITH_POPUP_KEY } from '../../../core/constants'; import { buildSSOCallbackURL } from '../../common/redirects'; import { useCoreSignIn, useSignInContext } from '../../contexts'; import { useEnvironment } from '../../contexts/EnvironmentContext'; @@ -38,6 +39,12 @@ export const SignInSocialButtons = React.memo((props: SocialButtonsProps) => { } }, 500); + try { + window.sessionStorage.setItem(SESSION_STORAGE_AUTH_WITH_POPUP_KEY, 'true'); + } catch { + // It's okay if sessionStorage is disabled since we will treat the failure to read the value as it being true. + } + return signIn .authenticateWithPopup({ strategy, redirectUrl, redirectUrlComplete, popup }) .catch(err => handleError(err, [], card.setError)); diff --git a/packages/clerk-js/src/ui/components/SignUp/SignUpSocialButtons.tsx b/packages/clerk-js/src/ui/components/SignUp/SignUpSocialButtons.tsx index 2eaa170f5eb..4333ec0e457 100644 --- a/packages/clerk-js/src/ui/components/SignUp/SignUpSocialButtons.tsx +++ b/packages/clerk-js/src/ui/components/SignUp/SignUpSocialButtons.tsx @@ -2,6 +2,7 @@ import { useClerk } from '@clerk/shared/react'; import type { OAuthStrategy } from '@clerk/types'; import React from 'react'; +import { SESSION_STORAGE_AUTH_WITH_POPUP_KEY } from '../../../core/constants'; import { useCoreSignUp, useSignUpContext } from '../../contexts'; import { useCardState } from '../../elements'; import type { SocialButtonsProps } from '../../elements/SocialButtons'; @@ -39,6 +40,12 @@ export const SignUpSocialButtons = React.memo((props: SignUpSocialButtonsProps) } }, 500); + try { + window.sessionStorage.setItem(SESSION_STORAGE_AUTH_WITH_POPUP_KEY, 'true'); + } catch { + // It's okay if sessionStorage is disabled since we will treat the failure to read the value as it being true. + } + return signUp .authenticateWithPopup({ strategy,