Skip to content

fix(clerk-js): Only refresh when auth with popup is called #5518

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/curly-carrots-invite.md
Original file line number Diff line number Diff line change
@@ -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.
22 changes: 20 additions & 2 deletions packages/clerk-js/src/core/clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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.
Comment on lines 1528 to 1531
Copy link
Member

Choose a reason for hiding this comment

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

Could this entire thing be done via a postMessage() from the popup? The issue is we don't know which resource we need to fetch so we're just doing both, right?

if (!window.opener) {
if (!window.opener && shouldRefreshResources) {
try {
await signIn.reload();
Copy link
Member

Choose a reason for hiding this comment

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

Can you remind me why doing .reload() is useful, if it always returns a 405 ?

Copy link
Member Author

Choose a reason for hiding this comment

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

It doesn't always return a 405. It only returns a 405 when the underlying resource doesn't exist. So for example if we created a SignIn resource during the popup, signIn.reload() will pick that up, but signUp.reload() will return a 405.

Copy link
Member

Choose a reason for hiding this comment

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

oh i see, thanks for clarifying.

} catch {
Expand Down
2 changes: 2 additions & 0 deletions packages/clerk-js/src/core/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ export const SIGN_UP_MODES: Record<string, SignUpModes> = {

// 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';
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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,
Expand Down
Loading