diff --git a/.changeset/grumpy-lamps-study.md b/.changeset/grumpy-lamps-study.md new file mode 100644 index 00000000000..e42cd0b0f91 --- /dev/null +++ b/.changeset/grumpy-lamps-study.md @@ -0,0 +1,8 @@ +--- +'@clerk/clerk-js': patch +'@clerk/types': patch +--- + +Fixes stale `SignIn` object on `authenticateWithRedirect` for `saml` and `enterprise_sso` custom flows + +Previously, the same connection identifier would be used on every `authenticateWithRedirect` call leading to redirecting to the wrong identity provider diff --git a/packages/clerk-js/src/core/resources/SignIn.ts b/packages/clerk-js/src/core/resources/SignIn.ts index cf39bbab220..e53e5bd07f2 100644 --- a/packages/clerk-js/src/core/resources/SignIn.ts +++ b/packages/clerk-js/src/core/resources/SignIn.ts @@ -231,25 +231,27 @@ export class SignIn extends BaseResource implements SignInResource { params: AuthenticateWithRedirectParams, navigateCallback: (url: URL | string) => void, ): Promise => { - const { strategy, redirectUrl, redirectUrlComplete, identifier, oidcPrompt } = params || {}; - - const { firstFactorVerification } = - (strategy === 'saml' || strategy === 'enterprise_sso') && this.id - ? await this.prepareFirstFactor({ - strategy, - redirectUrl: SignIn.clerk.buildUrlWithAuth(redirectUrl), - actionCompleteRedirectUrl: redirectUrlComplete, - oidcPrompt, - }) - : await this.create({ - strategy, - identifier, - redirectUrl: SignIn.clerk.buildUrlWithAuth(redirectUrl), - actionCompleteRedirectUrl: redirectUrlComplete, - oidcPrompt, - }); - - const { status, externalVerificationRedirectURL } = firstFactorVerification; + const { strategy, redirectUrl, redirectUrlComplete, identifier, oidcPrompt, continueSignIn } = params || {}; + + if (!this.id || !continueSignIn) { + await this.create({ + strategy, + identifier, + redirectUrl: SignIn.clerk.buildUrlWithAuth(redirectUrl), + actionCompleteRedirectUrl: redirectUrlComplete, + }); + } + + if (strategy === 'saml' || strategy === 'enterprise_sso') { + await this.prepareFirstFactor({ + strategy, + redirectUrl: SignIn.clerk.buildUrlWithAuth(redirectUrl), + actionCompleteRedirectUrl: redirectUrlComplete, + oidcPrompt, + }); + } + + const { status, externalVerificationRedirectURL } = this.firstFactorVerification; if (status === 'unverified' && externalVerificationRedirectURL) { navigateCallback(externalVerificationRedirectURL); diff --git a/packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx b/packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx index 7a69de6312d..ebd91c4836b 100644 --- a/packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx +++ b/packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx @@ -405,6 +405,7 @@ function SignInStartInternal(): JSX.Element { redirectUrl, redirectUrlComplete, oidcPrompt: ctx.oidcPrompt, + continueSignIn: true, }); }; diff --git a/packages/clerk-js/src/ui/components/SignIn/__tests__/SignInStart.test.tsx b/packages/clerk-js/src/ui/components/SignIn/__tests__/SignInStart.test.tsx index 868da61eddc..85cb044bbee 100644 --- a/packages/clerk-js/src/ui/components/SignIn/__tests__/SignInStart.test.tsx +++ b/packages/clerk-js/src/ui/components/SignIn/__tests__/SignInStart.test.tsx @@ -291,6 +291,7 @@ describe('SignInStart', () => { strategy: 'enterprise_sso', redirectUrl: 'http://localhost/#/sso-callback', redirectUrlComplete: '/', + continueSignIn: true, }); }); }); @@ -314,6 +315,7 @@ describe('SignInStart', () => { strategy: 'enterprise_sso', redirectUrl: 'http://localhost/#/sso-callback', redirectUrlComplete: '/', + continueSignIn: true, }); }); }); diff --git a/packages/types/src/redirects.ts b/packages/types/src/redirects.ts index a960e7e40fd..2418931b5bf 100644 --- a/packages/types/src/redirects.ts +++ b/packages/types/src/redirects.ts @@ -61,6 +61,11 @@ export type AuthenticateWithRedirectParams = { */ continueSignUp?: boolean; + /** + * Whether to continue existing SignIn (if present) or create a new SignIn. + */ + continueSignIn?: boolean; + /** * One of the supported OAuth providers you can use to authenticate with, eg 'oauth_google'. * Alternatively `saml` or `enterprise_sso`, to authenticate with Enterprise SSO.