diff --git a/.changeset/ten-pigs-flash.md b/.changeset/ten-pigs-flash.md new file mode 100644 index 00000000000..72f373e7b3c --- /dev/null +++ b/.changeset/ten-pigs-flash.md @@ -0,0 +1,5 @@ +--- +"@clerk/clerk-js": patch +--- + +Support `phone_code` as first factor for the experimental UserVerification component. diff --git a/packages/clerk-js/src/ui/components/UserVerification/UVFactorOnePhoneCodeCard.tsx b/packages/clerk-js/src/ui/components/UserVerification/UVFactorOnePhoneCodeCard.tsx new file mode 100644 index 00000000000..9ba5c0b778f --- /dev/null +++ b/packages/clerk-js/src/ui/components/UserVerification/UVFactorOnePhoneCodeCard.tsx @@ -0,0 +1,21 @@ +import type { PhoneCodeFactor } from '@clerk/types'; + +import { Flow, localizationKeys } from '../../customizables'; +import type { UVFactorOneCodeCard } from './UVFactorOneCodeForm'; +import { UVFactorOneCodeForm } from './UVFactorOneCodeForm'; + +type UVFactorOnePhoneCodeCardProps = UVFactorOneCodeCard & { factor: PhoneCodeFactor }; + +export const UVFactorOnePhoneCodeCard = (props: UVFactorOnePhoneCodeCardProps) => { + return ( + + + + ); +}; diff --git a/packages/clerk-js/src/ui/components/UserVerification/UserVerificationFactorOne.tsx b/packages/clerk-js/src/ui/components/UserVerification/UserVerificationFactorOne.tsx index 79d191c58ca..804ed28a183 100644 --- a/packages/clerk-js/src/ui/components/UserVerification/UserVerificationFactorOne.tsx +++ b/packages/clerk-js/src/ui/components/UserVerification/UserVerificationFactorOne.tsx @@ -11,6 +11,7 @@ import { AlternativeMethods } from './AlternativeMethods'; import { UserVerificationFactorOnePasswordCard } from './UserVerificationFactorOnePassword'; import { useUserVerificationSession, withUserVerificationSessionGuard } from './useUserVerificationSession'; import { UVFactorOneEmailCodeCard } from './UVFactorOneEmailCodeCard'; +import { UVFactorOnePhoneCodeCard } from './UVFactorOnePhoneCodeCard'; const factorKey = (factor: SignInFactor | null | undefined) => { if (!factor) { @@ -116,6 +117,15 @@ export function _UserVerificationFactorOne(): JSX.Element | null { factor={currentFactor} /> ); + case 'phone_code': + return ( + + ); default: return ; } diff --git a/packages/clerk-js/src/ui/components/UserVerification/__tests__/UVFactorOne.test.tsx b/packages/clerk-js/src/ui/components/UserVerification/__tests__/UVFactorOne.test.tsx index 87a27836eaa..5fc18ffb964 100644 --- a/packages/clerk-js/src/ui/components/UserVerification/__tests__/UVFactorOne.test.tsx +++ b/packages/clerk-js/src/ui/components/UserVerification/__tests__/UVFactorOne.test.tsx @@ -49,9 +49,29 @@ describe('UserVerificationFactorOne', () => { getByText('Check your email'); getByLabelText(/Enter verification code/i); }); + + expect(fixtures.session?.__experimental_prepareFirstFactorVerification).toHaveBeenCalledTimes(1); }); - it.todo('renders the component for with strategy:phone_code'); + it('renders the component for with strategy:phone_code', async () => { + const { wrapper, fixtures } = await createFixtures(f => { + f.withUser({ username: 'clerkuser' }); + f.withPreferredSignInStrategy({ strategy: 'otp' }); + }); + fixtures.session?.__experimental_startVerification.mockResolvedValue({ + status: 'needs_first_factor', + supportedFirstFactors: [{ strategy: 'password' }, { strategy: 'phone_code' }], + }); + fixtures.session?.__experimental_prepareFirstFactorVerification.mockResolvedValue({}); + const { getByLabelText, getByText } = render(, { wrapper }); + + await waitFor(() => { + getByText('Check your phone'); + getByLabelText(/Enter verification code/i); + }); + + expect(fixtures.session?.__experimental_prepareFirstFactorVerification).toHaveBeenCalledTimes(1); + }); describe('Submitting', () => { it('navigates to UserVerificationFactorTwo page when user submits first factor and second factor is enabled', async () => { @@ -110,6 +130,7 @@ describe('UserVerificationFactorOne', () => { await waitFor(() => { expect(fixtures.clerk.setActive).toHaveBeenCalled(); }); + expect(fixtures.session?.__experimental_attemptFirstFactorVerification).toHaveBeenCalledTimes(1); }); });