diff --git a/.changeset/dry-keys-look.md b/.changeset/dry-keys-look.md new file mode 100644 index 00000000000..aa64460b151 --- /dev/null +++ b/.changeset/dry-keys-look.md @@ -0,0 +1,15 @@ +--- +'@clerk/react-router': minor +'@clerk/clerk-js': minor +'@clerk/nextjs': minor +'@clerk/shared': minor +'@clerk/clerk-react': minor +'@clerk/remix': minor +--- + +Introduce `EmailLinkErrorCodeStatus` to support users in custom flows and mark `EmailLinkErrorCode` as deprecated. + +```diff +- import { EmailLinkErrorCode } from '@clerk/nextjs/errors' ++ import { EmailLinkErrorCodeStatus } from '@clerk/nextjs/errors' +``` diff --git a/packages/clerk-js/src/core/__tests__/clerk.test.ts b/packages/clerk-js/src/core/__tests__/clerk.test.ts index 72f72c6d09a..eb085dce250 100644 --- a/packages/clerk-js/src/core/__tests__/clerk.test.ts +++ b/packages/clerk-js/src/core/__tests__/clerk.test.ts @@ -6,7 +6,7 @@ import type { DevBrowser } from '../auth/devBrowser'; import { Clerk } from '../clerk'; import { eventBus, events } from '../events'; import type { DisplayConfig, Organization } from '../resources/internal'; -import { BaseResource, Client, EmailLinkErrorCode, Environment, SignIn, SignUp } from '../resources/internal'; +import { BaseResource, Client, EmailLinkErrorCodeStatus, Environment, SignIn, SignUp } from '../resources/internal'; import { mockJwt } from '../test/fixtures'; const mockClientFetch = jest.fn(); @@ -1878,7 +1878,7 @@ describe('Clerk singleton', () => { await expect(async () => { await sut.handleEmailLinkVerification({}); - }).rejects.toThrow(EmailLinkErrorCode.Expired); + }).rejects.toThrow(EmailLinkErrorCodeStatus.Expired); expect(mockSetActive).not.toHaveBeenCalled(); }); @@ -1900,7 +1900,7 @@ describe('Clerk singleton', () => { await expect(async () => { await sut.handleEmailLinkVerification({}); - }).rejects.toThrow(EmailLinkErrorCode.Failed); + }).rejects.toThrow(EmailLinkErrorCodeStatus.Failed); expect(mockSetActive).not.toHaveBeenCalled(); }); @@ -1946,7 +1946,7 @@ describe('Clerk singleton', () => { sut.setActive = mockSetActive; await expect(async () => { await sut.handleEmailLinkVerification({}); - }).rejects.toThrow(EmailLinkErrorCode.Failed); + }).rejects.toThrow(EmailLinkErrorCodeStatus.Failed); expect(mockSetActive).not.toHaveBeenCalled(); }); @@ -1972,7 +1972,7 @@ describe('Clerk singleton', () => { await expect(async () => { await sut.handleEmailLinkVerification({}); - }).rejects.toThrow(EmailLinkErrorCode.Failed); + }).rejects.toThrow(EmailLinkErrorCodeStatus.Failed); expect(mockSetActive).not.toHaveBeenCalled(); }); }); diff --git a/packages/clerk-js/src/core/clerk.ts b/packages/clerk-js/src/core/clerk.ts index 8e70cfbbd25..80351c9ef8f 100644 --- a/packages/clerk-js/src/core/clerk.ts +++ b/packages/clerk-js/src/core/clerk.ts @@ -1,6 +1,6 @@ import { inBrowser as inClientSide, isValidBrowserOnline } from '@clerk/shared/browser'; import { deprecated } from '@clerk/shared/deprecated'; -import { ClerkRuntimeError, is4xxError, isClerkAPIResponseError } from '@clerk/shared/error'; +import { ClerkRuntimeError, EmailLinkErrorCodeStatus, is4xxError, isClerkAPIResponseError } from '@clerk/shared/error'; import { parsePublishableKey } from '@clerk/shared/keys'; import { LocalStorageBroadcastChannel } from '@clerk/shared/localStorageBroadcastChannel'; import { logger } from '@clerk/shared/logger'; @@ -120,7 +120,6 @@ import { BaseResource, Client, EmailLinkError, - EmailLinkErrorCode, Environment, isClerkRuntimeError, Organization, @@ -1216,11 +1215,11 @@ export class Clerk implements ClerkInterface { const verificationStatus = getClerkQueryParam('__clerk_status'); if (verificationStatus === 'expired') { - throw new EmailLinkError(EmailLinkErrorCode.Expired); + throw new EmailLinkError(EmailLinkErrorCodeStatus.Expired); } else if (verificationStatus === 'client_mismatch') { - throw new EmailLinkError(EmailLinkErrorCode.ClientMismatch); + throw new EmailLinkError(EmailLinkErrorCodeStatus.ClientMismatch); } else if (verificationStatus !== 'verified') { - throw new EmailLinkError(EmailLinkErrorCode.Failed); + throw new EmailLinkError(EmailLinkErrorCodeStatus.Failed); } const newSessionId = getClerkQueryParam('__clerk_created_session'); diff --git a/packages/clerk-js/src/core/resources/Error.ts b/packages/clerk-js/src/core/resources/Error.ts index e10b056a29a..385fa95d69d 100644 --- a/packages/clerk-js/src/core/resources/Error.ts +++ b/packages/clerk-js/src/core/resources/Error.ts @@ -3,6 +3,7 @@ export { ClerkAPIResponseError, EmailLinkError, EmailLinkErrorCode, + EmailLinkErrorCodeStatus, isClerkAPIResponseError, isClerkRuntimeError, isEmailLinkError, diff --git a/packages/clerk-js/src/ui/common/EmailLinkVerify.tsx b/packages/clerk-js/src/ui/common/EmailLinkVerify.tsx index e67d25be897..b4f1edf9fb5 100644 --- a/packages/clerk-js/src/ui/common/EmailLinkVerify.tsx +++ b/packages/clerk-js/src/ui/common/EmailLinkVerify.tsx @@ -1,4 +1,4 @@ -import { EmailLinkErrorCode, isEmailLinkError } from '@clerk/shared/error'; +import { EmailLinkErrorCodeStatus, isEmailLinkError } from '@clerk/shared/error'; import { useClerk } from '@clerk/shared/react'; import React from 'react'; @@ -42,10 +42,10 @@ export const EmailLinkVerify = (props: EmailLinkVerifyProps) => { }); } catch (err) { let status: VerificationStatus = 'failed'; - if (isEmailLinkError(err) && err.code === EmailLinkErrorCode.Expired) { + if (isEmailLinkError(err) && err.code === EmailLinkErrorCodeStatus.Expired) { status = 'expired'; } - if (isEmailLinkError(err) && err.code === EmailLinkErrorCode.ClientMismatch) { + if (isEmailLinkError(err) && err.code === EmailLinkErrorCodeStatus.ClientMismatch) { status = 'client_mismatch'; } setVerificationStatus(status); diff --git a/packages/clerk-js/src/ui/components/SignUp/__tests__/SignUpEmailLinkFlowComplete.test.tsx b/packages/clerk-js/src/ui/components/SignUp/__tests__/SignUpEmailLinkFlowComplete.test.tsx index 8391e93bca0..7f4dbcf97ef 100644 --- a/packages/clerk-js/src/ui/components/SignUp/__tests__/SignUpEmailLinkFlowComplete.test.tsx +++ b/packages/clerk-js/src/ui/components/SignUp/__tests__/SignUpEmailLinkFlowComplete.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { EmailLinkError, EmailLinkErrorCode } from '../../../../core/resources'; +import { EmailLinkError, EmailLinkErrorCodeStatus } from '../../../../core/resources'; import { render, runFakeTimers, screen, waitFor } from '../../../../testUtils'; import { SignUpEmailLinkFlowComplete } from '../../../common/EmailLinkCompleteFlowCard'; import { bindCreateFixtures } from '../../../utils/test/createFixtures'; @@ -50,7 +50,7 @@ describe('SignUpEmailLinkFlowComplete', () => { }); fixtures.clerk.handleEmailLinkVerification.mockImplementationOnce( await Promise.resolve(() => { - throw new EmailLinkError(EmailLinkErrorCode.Expired); + throw new EmailLinkError(EmailLinkErrorCodeStatus.Expired); }), ); @@ -68,7 +68,7 @@ describe('SignUpEmailLinkFlowComplete', () => { }); fixtures.clerk.handleEmailLinkVerification.mockImplementationOnce( await Promise.resolve(() => { - throw new EmailLinkError(EmailLinkErrorCode.Failed); + throw new EmailLinkError(EmailLinkErrorCodeStatus.Failed); }), ); await runFakeTimers(async timers => { diff --git a/packages/nextjs/src/client-boundary/hooks.ts b/packages/nextjs/src/client-boundary/hooks.ts index 7aecceaff5f..5aa5621ffdc 100644 --- a/packages/nextjs/src/client-boundary/hooks.ts +++ b/packages/nextjs/src/client-boundary/hooks.ts @@ -20,6 +20,7 @@ export { isKnownError, isMetamaskError, EmailLinkErrorCode, + EmailLinkErrorCodeStatus, } from '@clerk/clerk-react/errors'; export { usePromisifiedAuth as useAuth } from './PromisifiedAuthProvider'; diff --git a/packages/nextjs/src/errors.ts b/packages/nextjs/src/errors.ts index 2ade23d7517..86d28f2f247 100644 --- a/packages/nextjs/src/errors.ts +++ b/packages/nextjs/src/errors.ts @@ -4,6 +4,7 @@ export { isKnownError, isMetamaskError, EmailLinkErrorCode, + EmailLinkErrorCodeStatus, } from './client-boundary/hooks'; export { isClerkAPIResponseError } from '@clerk/clerk-react/errors'; diff --git a/packages/react-router/src/errors.ts b/packages/react-router/src/errors.ts index 96c4094f029..9548c1104db 100644 --- a/packages/react-router/src/errors.ts +++ b/packages/react-router/src/errors.ts @@ -4,4 +4,5 @@ export { isKnownError, isMetamaskError, EmailLinkErrorCode, + EmailLinkErrorCodeStatus, } from '@clerk/clerk-react/errors'; diff --git a/packages/react/src/errors.ts b/packages/react/src/errors.ts index cf2f8d0a5c3..5ccfdd8c1fe 100644 --- a/packages/react/src/errors.ts +++ b/packages/react/src/errors.ts @@ -5,4 +5,5 @@ export { isKnownError, isMetamaskError, EmailLinkErrorCode, + EmailLinkErrorCodeStatus, } from '@clerk/shared/error'; diff --git a/packages/remix/src/errors.ts b/packages/remix/src/errors.ts index 96c4094f029..9548c1104db 100644 --- a/packages/remix/src/errors.ts +++ b/packages/remix/src/errors.ts @@ -4,4 +4,5 @@ export { isKnownError, isMetamaskError, EmailLinkErrorCode, + EmailLinkErrorCodeStatus, } from '@clerk/clerk-react/errors'; diff --git a/packages/shared/src/error.ts b/packages/shared/src/error.ts index 7b58b9fa46a..bcbff86b276 100644 --- a/packages/shared/src/error.ts +++ b/packages/shared/src/error.ts @@ -210,12 +210,19 @@ export function isEmailLinkError(err: Error): err is EmailLinkError { return err.name === 'EmailLinkError'; } +/** @deprecated Please use `EmailLinkErrorCodeStatus` instead.*/ export const EmailLinkErrorCode = { Expired: 'expired', Failed: 'failed', ClientMismatch: 'client_mismatch', }; +export const EmailLinkErrorCodeStatus = { + Expired: 'expired', + Failed: 'failed', + ClientMismatch: 'client_mismatch', +} as const; + const DefaultMessages = Object.freeze({ InvalidProxyUrlErrorMessage: `The proxyUrl passed to Clerk is invalid. The expected value for proxyUrl is an absolute URL or a relative path with a leading '/'. (key={{url}})`, InvalidPublishableKeyErrorMessage: `The publishableKey passed to Clerk is invalid. You can get your Publishable key at https://dashboard.clerk.com/last-active?path=api-keys. (key={{key}})`, diff --git a/packages/tanstack-start/src/errors.ts b/packages/tanstack-start/src/errors.ts index 96c4094f029..9548c1104db 100644 --- a/packages/tanstack-start/src/errors.ts +++ b/packages/tanstack-start/src/errors.ts @@ -4,4 +4,5 @@ export { isKnownError, isMetamaskError, EmailLinkErrorCode, + EmailLinkErrorCodeStatus, } from '@clerk/clerk-react/errors';