Skip to content

Commit f63f334

Browse files
committed
feat: Prep work to support email_code as a second factor
1 parent 4ee26f2 commit f63f334

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+367
-4
lines changed

.changeset/bright-heads-start.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@clerk/localizations': minor
3+
'@clerk/clerk-js': minor
4+
'@clerk/types': minor
5+
---
6+
7+
Prep work to support `email_code` as a second factor when necessary. (Note: Currently behind a feature flag.)

packages/clerk-js/src/ui/components/SignIn/SignInFactorTwo.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { withRedirectToAfterSignIn, withRedirectToSignInTask } from '../../commo
88
import { useCoreSignIn } from '../../contexts';
99
import { SignInFactorTwoAlternativeMethods } from './SignInFactorTwoAlternativeMethods';
1010
import { SignInFactorTwoBackupCodeCard } from './SignInFactorTwoBackupCodeCard';
11+
import { SignInFactorTwoEmailCodeCard } from './SignInFactorTwoEmailCodeCard';
1112
import { SignInFactorTwoPhoneCodeCard } from './SignInFactorTwoPhoneCodeCard';
1213
import { SignInFactorTwoTOTPCard } from './SignInFactorTwoTOTPCard';
1314
import { determineStartingSignInSecondFactor } from './utils';
@@ -77,6 +78,15 @@ function SignInFactorTwoInternal(): JSX.Element {
7778
);
7879
case 'backup_code':
7980
return <SignInFactorTwoBackupCodeCard onShowAlternativeMethodsClicked={toggleAllStrategies} />;
81+
case 'email_code':
82+
return (
83+
<SignInFactorTwoEmailCodeCard
84+
factorAlreadyPrepared={lastPreparedFactorKeyRef.current === factorKey(currentFactor)}
85+
onFactorPrepare={handleFactorPrepare}
86+
factor={currentFactor}
87+
onShowAlternativeMethodsClicked={toggleAllStrategies}
88+
/>
89+
);
8090
default:
8191
return <LoadingCard />;
8292
}

packages/clerk-js/src/ui/components/SignIn/SignInFactorTwoAlternativeMethods.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ export function getButtonLabel(factor: SignInFactor): LocalizationKey {
103103
return localizationKeys('signIn.alternativeMethods.blockButton__totp');
104104
case 'backup_code':
105105
return localizationKeys('signIn.alternativeMethods.blockButton__backupCode');
106+
case 'email_code':
107+
return localizationKeys('signIn.alternativeMethods.blockButton__emailCode', {
108+
identifier: formatSafeIdentifier(factor.safeIdentifier) || '',
109+
});
106110
default:
107111
throw new Error(`Invalid sign in strategy: "${factor.strategy}"`);
108112
}

packages/clerk-js/src/ui/components/SignIn/SignInFactorTwoCodeForm.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { isUserLockedError } from '@clerk/shared/error';
22
import { useClerk } from '@clerk/shared/react';
3-
import type { PhoneCodeFactor, SignInResource, TOTPFactor } from '@clerk/types';
3+
import type { EmailCodeFactor, PhoneCodeFactor, SignInResource, TOTPFactor } from '@clerk/types';
44
import React from 'react';
55

66
import { useCardState } from '@/ui/elements/contexts';
@@ -17,7 +17,7 @@ import { useRouter } from '../../router';
1717
import { isResetPasswordStrategy } from './utils';
1818

1919
export type SignInFactorTwoCodeCard = Pick<VerificationCodeCardProps, 'onShowAlternativeMethodsClicked'> & {
20-
factor: PhoneCodeFactor | TOTPFactor;
20+
factor: EmailCodeFactor | PhoneCodeFactor | TOTPFactor;
2121
factorAlreadyPrepared: boolean;
2222
onFactorPrepare: () => void;
2323
prepare?: () => Promise<SignInResource>;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import type { EmailCodeFactor } from '@clerk/types';
2+
3+
import { useCoreSignIn } from '../../contexts';
4+
import { Flow, localizationKeys } from '../../customizables';
5+
import type { SignInFactorTwoCodeCard } from './SignInFactorTwoCodeForm';
6+
import { SignInFactorTwoCodeForm } from './SignInFactorTwoCodeForm';
7+
8+
type SignInFactorTwoEmailCodeCardProps = SignInFactorTwoCodeCard & { factor: EmailCodeFactor };
9+
10+
export const SignInFactorTwoEmailCodeCard = (props: SignInFactorTwoEmailCodeCardProps) => {
11+
const signIn = useCoreSignIn();
12+
13+
const prepare = () => {
14+
// TODO: Why does the BE throw an error if I simply pass
15+
// the whole factor?
16+
const { emailAddressId, strategy } = props.factor;
17+
return signIn.prepareSecondFactor({ emailAddressId, strategy });
18+
};
19+
20+
// TODO: Update the part, card title, etc.
21+
return (
22+
<Flow.Part part='emailCode2Fa'>
23+
<SignInFactorTwoCodeForm
24+
{...props}
25+
cardTitle={localizationKeys('signIn.emailCodeMfa.title')}
26+
cardSubtitle={localizationKeys('signIn.emailCodeMfa.subtitle')}
27+
inputLabel={localizationKeys('signIn.emailCodeMfa.formTitle')}
28+
resendButton={localizationKeys('signIn.emailCodeMfa.resendButton')}
29+
prepare={prepare}
30+
/>
31+
</Flow.Part>
32+
);
33+
};

packages/clerk-js/src/ui/elements/contexts/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export type FlowMetadata = {
105105
part?:
106106
| 'start'
107107
| 'emailCode'
108+
| 'emailCode2Fa'
108109
| 'phoneCode'
109110
| 'phoneCode2Fa'
110111
| 'totp2Fa'

packages/localizations/src/ar-SA.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,12 @@ export const arSA: LocalizationResource = {
604604
subtitle: 'للمتابعة إلى {{applicationName}}',
605605
title: 'التحقق من البريد الإلكتروني',
606606
},
607+
emailCodeMfa: {
608+
formTitle: undefined,
609+
resendButton: undefined,
610+
subtitle: undefined,
611+
title: undefined,
612+
},
607613
emailLink: {
608614
clientMismatch: {
609615
subtitle: 'للمتابعة, قم بفتح رابط التحقق عبر نفس الجهاز والمتصفح الذي انشأت محاولة تسجيل الدخول منه',

packages/localizations/src/be-BY.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,12 @@ export const beBY: LocalizationResource = {
610610
subtitle: 'каб працягнуць працу ў "{{applicationName}}"',
611611
title: 'Праверце вашу пошту',
612612
},
613+
emailCodeMfa: {
614+
formTitle: undefined,
615+
resendButton: undefined,
616+
subtitle: undefined,
617+
title: undefined,
618+
},
613619
emailLink: {
614620
clientMismatch: {
615621
subtitle:

packages/localizations/src/bg-BG.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,12 @@ export const bgBG: LocalizationResource = {
607607
subtitle: 'за да продължите към {{applicationName}}',
608608
title: 'Проверете вашия имейл',
609609
},
610+
emailCodeMfa: {
611+
formTitle: undefined,
612+
resendButton: undefined,
613+
subtitle: undefined,
614+
title: undefined,
615+
},
610616
emailLink: {
611617
clientMismatch: {
612618
subtitle: undefined,

packages/localizations/src/bn-IN.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,12 @@ export const bnIN: LocalizationResource = {
609609
subtitle: '{{applicationName}}-এ চালিয়ে যাওয়ার জন্য',
610610
title: 'আপনার ইমেইল চেক করুন',
611611
},
612+
emailCodeMfa: {
613+
formTitle: undefined,
614+
resendButton: undefined,
615+
subtitle: undefined,
616+
title: undefined,
617+
},
612618
emailLink: {
613619
clientMismatch: {
614620
subtitle: 'চালিয়ে যেতে, যে ডিভাইস এবং ব্রাউজার থেকে আপনি সাইন-ইন শুরু করেছেন সেখানে যাচাইকরণ লিংক খুলুন',

0 commit comments

Comments
 (0)