Skip to content

Commit

Permalink
feat(clerk-js): Improve redirects on OAuth callback
Browse files Browse the repository at this point in the history
Currently, if you try to sign up with a provider that allows unverified accounts, the flow appears to be broken because it asks for the email after the OAuth callback. With this change, it will navigate to the appropriate change when needed.
  • Loading branch information
kostaspt committed Aug 9, 2023
1 parent 52ce791 commit 349a4cd
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 17 deletions.
2 changes: 2 additions & 0 deletions .changeset/tender-icons-bake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
23 changes: 21 additions & 2 deletions packages/clerk-js/src/core/clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import type {
} from '@clerk/types';

import type { MountComponentRenderer } from '../ui/Components';
import { handleMissingRequirements } from '../ui/components/SignUp/util';
import {
appendAsQueryParams,
buildURL,
Expand Down Expand Up @@ -834,6 +835,8 @@ export default class Clerk implements ClerkInterface {
const { externalAccount } = signUp.verifications;
const su = {
status: signUp.status,
missingFields: signUp.missingFields,
unverifiedFields: signUp.unverifiedFields,
externalAccountStatus: externalAccount.status,
externalAccountErrorCode: externalAccount.error?.code,
externalAccountSessionId: externalAccount.error?.meta?.sessionId,
Expand Down Expand Up @@ -873,6 +876,22 @@ export default class Clerk implements ClerkInterface {
buildURL({ base: displayConfig.signUpUrl, hashPath: '/continue' }, { stringify: true }),
);

const navigateToNextStepSignUp = () => {
if (su.unverifiedFields.length > 0 && su.missingFields.length === 0) {
return handleMissingRequirements({
signUp,
verifyEmailPath:
params.verifyEmailAddressUrl ||
buildURL({ base: displayConfig.signUpUrl, hashPath: '/verify-email-address' }, { stringify: true }),
verifyPhonePath:
params.verifyPhoneNumberUrl ||
buildURL({ base: displayConfig.signUpUrl, hashPath: '/verify-phone-number' }, { stringify: true }),
navigate,
});
}
return navigateToContinueSignUp();
};

const userExistsButNeedsToSignIn =
su.externalAccountStatus === 'transferable' && su.externalAccountErrorCode === 'external_account_exists';

Expand Down Expand Up @@ -902,7 +921,7 @@ export default class Clerk implements ClerkInterface {
beforeEmit: navigateAfterSignUp,
});
case 'missing_requirements':
return navigateToContinueSignUp();
return navigateToNextStepSignUp();
default:
clerkOAuthCallbackDidNotCompleteSignInSignUp('sign in');
}
Expand Down Expand Up @@ -938,7 +957,7 @@ export default class Clerk implements ClerkInterface {
}

if (su.externalAccountStatus === 'verified' && su.status === 'missing_requirements') {
return navigateToContinueSignUp();
return navigateToNextStepSignUp();
}

return navigateToSignIn();
Expand Down
2 changes: 2 additions & 0 deletions packages/clerk-js/src/ui/components/SignUp/SignUp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ function SignUpRoutes(): JSX.Element {
redirectUrl={signUpContext.redirectUrl}
secondFactorUrl={signUpContext.secondFactorUrl}
continueSignUpUrl='../continue'
verifyEmailAddressUrl='../verify-email-address'
verifyPhoneNumberUrl='../verify-phone-number'
/>
</Route>
<Route path='verify'>
Expand Down
50 changes: 35 additions & 15 deletions packages/clerk-js/src/ui/components/SignUp/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,32 @@ type CompleteSignUpFlowProps = {
redirectUrlComplete?: string;
};

export const handleMissingRequirements = ({
signUp,
verifyEmailPath,
verifyPhonePath,
navigate,
redirectUrl = '',
redirectUrlComplete = '',
}: CompleteSignUpFlowProps): Promise<unknown> | undefined => {
if (signUp.missingFields.some(mf => mf === 'saml')) {
return signUp.authenticateWithRedirect({
strategy: 'saml',
redirectUrl,
redirectUrlComplete,
continueSignUp: true,
});
}

if (signUp.unverifiedFields?.includes('email_address') && verifyEmailPath) {
return navigate(verifyEmailPath);
}
if (signUp.unverifiedFields?.includes('phone_number') && verifyPhonePath) {
return navigate(verifyPhonePath);
}
return;
};

export const completeSignUpFlow = ({
signUp,
verifyEmailPath,
Expand All @@ -19,24 +45,18 @@ export const completeSignUpFlow = ({
redirectUrl = '',
redirectUrlComplete = '',
}: CompleteSignUpFlowProps): Promise<unknown> | undefined => {
if (signUp.status === 'complete') {
return handleComplete && handleComplete();
} else if (signUp.status === 'missing_requirements') {
if (signUp.missingFields.some(mf => mf === 'saml')) {
return signUp.authenticateWithRedirect({
strategy: 'saml',
switch (signUp.status) {
case 'complete':
return handleComplete && handleComplete();
case 'missing_requirements':
return handleMissingRequirements({
signUp,
verifyEmailPath,
verifyPhonePath,
navigate,
redirectUrl,
redirectUrlComplete,
continueSignUp: true,
});
}

if (signUp.unverifiedFields?.includes('email_address') && verifyEmailPath) {
return navigate(verifyEmailPath);
}
if (signUp.unverifiedFields?.includes('phone_number') && verifyPhonePath) {
return navigate(verifyPhonePath);
}
}
return;
};
10 changes: 10 additions & 0 deletions packages/types/src/clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,16 @@ export type HandleOAuthCallbackParams = {
* Full URL or path to navigate after an incomplete sign up.
*/
continueSignUpUrl?: string | null;

/**
* Full URL or path to navigate after requesting email verification.
*/
verifyEmailAddressUrl?: string | null;

/**
* Full URL or path to navigate after requesting phone verification.
*/
verifyPhoneNumberUrl?: string | null;
};

/**
Expand Down

0 comments on commit 349a4cd

Please sign in to comment.