From b7d39ac29ef43739ceb73e3f1a3d976a80af108b Mon Sep 17 00:00:00 2001 From: Tom Milewski Date: Wed, 1 May 2024 14:55:44 -0400 Subject: [PATCH 1/4] chore(elements): Add addtional misconfigured instance error messaging --- .changeset/olive-points-own.md | 5 +++++ packages/elements/examples/nextjs/next.config.js | 2 +- .../src/internals/machines/sign-in/verification.machine.ts | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .changeset/olive-points-own.md diff --git a/.changeset/olive-points-own.md b/.changeset/olive-points-own.md new file mode 100644 index 00000000000..fbdb020ee3c --- /dev/null +++ b/.changeset/olive-points-own.md @@ -0,0 +1,5 @@ +--- +'@clerk/elements': patch +--- + +Add appropriate messaging for an invalid instance configuration vs implemented Elements strategies diff --git a/packages/elements/examples/nextjs/next.config.js b/packages/elements/examples/nextjs/next.config.js index 38d9318fcc9..840f438e060 100644 --- a/packages/elements/examples/nextjs/next.config.js +++ b/packages/elements/examples/nextjs/next.config.js @@ -1,7 +1,7 @@ /** @type {import('next').NextConfig} */ const nextConfig = { // Disable React strict mode when using the state machine inspector - reactStrictMode: process.env['NEXT_PUBLIC_CLERK_ELEMENTS_DEBUG'] !== 'true', + reactStrictMode: false, typescript: { ignoreBuildErrors: true, }, diff --git a/packages/elements/src/internals/machines/sign-in/verification.machine.ts b/packages/elements/src/internals/machines/sign-in/verification.machine.ts index 9be31fab59a..80570b7a678 100644 --- a/packages/elements/src/internals/machines/sign-in/verification.machine.ts +++ b/packages/elements/src/internals/machines/sign-in/verification.machine.ts @@ -109,11 +109,16 @@ const SignInVerificationMachine = setup({ if ( process.env.NODE_ENV === 'development' && + context.currentFactor?.strategy && !context.registeredStrategies.has(context.currentFactor?.strategy as unknown as SignInFactor) ) { throw new ClerkElementsRuntimeError( `Your sign-in attempt is missing a ${context.currentFactor?.strategy} strategy. Make sure is rendered in your flow. For more information, visit the documentation: https://clerk.com/docs/elements/reference/sign-in#strategy`, ); + } else if (process.env.NODE_ENV === 'development' && !context.currentFactor?.strategy) { + throw new ClerkElementsRuntimeError( + 'Your Clerk configuration is missing a valid authentication strategy. Please verify your instance configuration. For more information, visit the documentation: https://clerk.com/docs/elements/reference/sign-in#strategy', + ); } }, sendToNext: ({ context, event }) => From 83ca418976d903223132f53edf7b8f0676df406d Mon Sep 17 00:00:00 2001 From: Tom Milewski Date: Wed, 1 May 2024 15:07:50 -0400 Subject: [PATCH 2/4] Update packages/elements/src/internals/machines/sign-in/verification.machine.ts Co-authored-by: Bryce Kalow --- .../src/internals/machines/sign-in/verification.machine.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/elements/src/internals/machines/sign-in/verification.machine.ts b/packages/elements/src/internals/machines/sign-in/verification.machine.ts index 80570b7a678..0e12e01bca1 100644 --- a/packages/elements/src/internals/machines/sign-in/verification.machine.ts +++ b/packages/elements/src/internals/machines/sign-in/verification.machine.ts @@ -117,7 +117,7 @@ const SignInVerificationMachine = setup({ ); } else if (process.env.NODE_ENV === 'development' && !context.currentFactor?.strategy) { throw new ClerkElementsRuntimeError( - 'Your Clerk configuration is missing a valid authentication strategy. Please verify your instance configuration. For more information, visit the documentation: https://clerk.com/docs/elements/reference/sign-in#strategy', + 'Unable to determine an authentication strategy to verify. This means your instance is misconfigured. Visit the Clerk Dashboard and verify that your instance has authentication strategies enabled: https://dashboard.clerk.com/last-active?path=/user-authentication/email-phone-username, ); } }, From 7ad5bc7b5ed3337895774b3f70b666a8ac11ca11 Mon Sep 17 00:00:00 2001 From: Bryce Kalow Date: Wed, 1 May 2024 14:48:04 -0500 Subject: [PATCH 3/4] Update packages/elements/src/internals/machines/sign-in/verification.machine.ts --- .../src/internals/machines/sign-in/verification.machine.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/elements/src/internals/machines/sign-in/verification.machine.ts b/packages/elements/src/internals/machines/sign-in/verification.machine.ts index 0e12e01bca1..fba96f032a4 100644 --- a/packages/elements/src/internals/machines/sign-in/verification.machine.ts +++ b/packages/elements/src/internals/machines/sign-in/verification.machine.ts @@ -117,7 +117,7 @@ const SignInVerificationMachine = setup({ ); } else if (process.env.NODE_ENV === 'development' && !context.currentFactor?.strategy) { throw new ClerkElementsRuntimeError( - 'Unable to determine an authentication strategy to verify. This means your instance is misconfigured. Visit the Clerk Dashboard and verify that your instance has authentication strategies enabled: https://dashboard.clerk.com/last-active?path=/user-authentication/email-phone-username, + 'Unable to determine an authentication strategy to verify. This means your instance is misconfigured. Visit the Clerk Dashboard and verify that your instance has authentication strategies enabled: https://dashboard.clerk.com/last-active?path=/user-authentication/email-phone-username', ); } }, From 8c25cdbe4bb9d2235805f26c65b2abcf20148228 Mon Sep 17 00:00:00 2001 From: Bryce Kalow Date: Wed, 1 May 2024 14:49:04 -0500 Subject: [PATCH 4/4] fix(elements): Prevent multiple verification codes from being sent (#3305) * fix(elements): Prevent multiple verification codes from being sent at once * Update packages/elements/src/react/sign-in/context/router.context.ts --- .changeset/violet-lobsters-scream.md | 5 +++++ .../machines/sign-in/verification.machine.ts | 19 +++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 .changeset/violet-lobsters-scream.md diff --git a/.changeset/violet-lobsters-scream.md b/.changeset/violet-lobsters-scream.md new file mode 100644 index 00000000000..f533bcefc06 --- /dev/null +++ b/.changeset/violet-lobsters-scream.md @@ -0,0 +1,5 @@ +--- +'@clerk/elements': patch +--- + +Fixes a bug where multiple verification codes were sent at once. diff --git a/packages/elements/src/internals/machines/sign-in/verification.machine.ts b/packages/elements/src/internals/machines/sign-in/verification.machine.ts index fba96f032a4..9b6aef44ac6 100644 --- a/packages/elements/src/internals/machines/sign-in/verification.machine.ts +++ b/packages/elements/src/internals/machines/sign-in/verification.machine.ts @@ -34,9 +34,11 @@ type Parent = ActorRefFrom; export type PrepareFirstFactorInput = WithParams & { parent: Parent; + resendable: boolean; }; export type PrepareSecondFactorInput = WithParams & { parent: Parent; + resendable: boolean; }; export type AttemptFirstFactorInput = { parent: Parent; fields: FormFields; currentFactor: SignInFirstFactor | null }; @@ -176,6 +178,7 @@ const SignInVerificationMachine = setup({ src: 'prepare', input: ({ context }) => ({ parent: context.parent, + resendable: context.resendable, params: context.currentFactor as SignInFirstFactor | null, }), onDone: { @@ -272,10 +275,14 @@ const SignInVerificationMachine = setup({ export const SignInFirstFactorMachine = SignInVerificationMachine.provide({ actors: { prepare: fromPromise(async ({ input }) => { - const { params, parent } = input; + const { params, parent, resendable } = input; const clerk = parent.getSnapshot().context.clerk; - if (!params?.strategy || params.strategy === 'password') { + // If a prepare call has already been fired recently, don't re-send + const currentVerificationExpiration = clerk.client.signIn.firstFactorVerification.expireAt; + const needsPrepare = resendable || !currentVerificationExpiration || currentVerificationExpiration < new Date(); + + if (!params?.strategy || params.strategy === 'password' || !needsPrepare) { return Promise.resolve(clerk.client.signIn); } @@ -364,12 +371,16 @@ export const SignInFirstFactorMachine = SignInVerificationMachine.provide({ export const SignInSecondFactorMachine = SignInVerificationMachine.provide({ actors: { prepare: fromPromise(({ input }) => { - const { params, parent } = input; + const { params, parent, resendable } = input; const clerk = parent.getSnapshot().context.clerk; + // If a prepare call has already been fired recently, don't re-send + const currentVerificationExpiration = clerk.client.signIn.secondFactorVerification.expireAt; + const needsPrepare = resendable || !currentVerificationExpiration || currentVerificationExpiration < new Date(); + assertIsDefined(params); - if (params.strategy !== 'phone_code') { + if (params.strategy !== 'phone_code' || !needsPrepare) { return Promise.resolve(clerk.client.signIn); }