diff --git a/packages/clerk-js/src/core/resources/EmailAddress.ts b/packages/clerk-js/src/core/resources/EmailAddress.ts index 6f6f9d0c32..ea16f8090e 100644 --- a/packages/clerk-js/src/core/resources/EmailAddress.ts +++ b/packages/clerk-js/src/core/resources/EmailAddress.ts @@ -80,13 +80,13 @@ export class EmailAddress extends BaseResource implements EmailAddressResource { return { startEmailLinkFlow, cancelEmailLinkFlow: stop }; }; - createEnterpriseConnectionLinkFlow = (): CreateEnterpriseConnectionLinkFlowReturn< + createEnterpriseSsoLinkFlow = (): CreateEnterpriseConnectionLinkFlowReturn< StartEnterpriseConnectionLinkFlowParams, EmailAddressResource > => { const { run, stop } = Poller(); - const startEnterpriseConnectionLinkFlow = async ({ + const startEnterpriseSsoLinkFlow = async ({ redirectUrl, }: StartEnterpriseConnectionLinkFlowParams): Promise => { if (!this.id) { @@ -94,7 +94,7 @@ export class EmailAddress extends BaseResource implements EmailAddressResource { } const response = await this.prepareVerification({ strategy: 'enterprise_sso', - redirectUrl: redirectUrl, + redirectUrl, }); if (!response.verification.externalVerificationRedirectURL) { throw Error('Unexpected: External verification redirect URL is missing'); @@ -116,7 +116,7 @@ export class EmailAddress extends BaseResource implements EmailAddressResource { }); }); }; - return { startEnterpriseConnectionLinkFlow, cancelEnterpriseConnectionLinkFlow: stop }; + return { startEnterpriseSsoLinkFlow, cancelEnterpriseSsoLinkFlow: stop }; }; destroy = (): Promise => this._baseDelete(); diff --git a/packages/clerk-js/src/ui/common/redirects.ts b/packages/clerk-js/src/ui/common/redirects.ts index 212dfeca9d..975bf08a03 100644 --- a/packages/clerk-js/src/ui/common/redirects.ts +++ b/packages/clerk-js/src/ui/common/redirects.ts @@ -2,9 +2,9 @@ import { buildURL } from '../../utils/url'; import type { SignInContextType, SignUpContextType, UserProfileContextType } from './../contexts'; const SSO_CALLBACK_PATH_ROUTE = '/sso-callback'; -const MAGIC_LINK_VERIFY_PATH_ROUTE = '/verify'; +const VERIFICATION_PATH_ROUTE = '/verify'; -export function buildEmailLinkRedirectUrl( +export function buildVerificationRedirectUrl( ctx: SignInContextType | SignUpContextType | UserProfileContextType, baseUrl: string | undefined = '', ): string { @@ -14,7 +14,7 @@ export function buildEmailLinkRedirectUrl( baseUrl, authQueryString, path, - endpoint: MAGIC_LINK_VERIFY_PATH_ROUTE, + endpoint: VERIFICATION_PATH_ROUTE, }); } diff --git a/packages/clerk-js/src/ui/components/SignIn/SignInFactorOneEmailLinkCard.tsx b/packages/clerk-js/src/ui/components/SignIn/SignInFactorOneEmailLinkCard.tsx index f9275a0283..1a98157df8 100644 --- a/packages/clerk-js/src/ui/components/SignIn/SignInFactorOneEmailLinkCard.tsx +++ b/packages/clerk-js/src/ui/components/SignIn/SignInFactorOneEmailLinkCard.tsx @@ -4,7 +4,7 @@ import type { EmailLinkFactor, SignInResource } from '@clerk/types'; import React from 'react'; import { EmailLinkStatusCard } from '../../common'; -import { buildEmailLinkRedirectUrl } from '../../common/redirects'; +import { buildVerificationRedirectUrl } from '../../common/redirects'; import { useCoreSignIn, useSignInContext } from '../../contexts'; import { Flow, localizationKeys, useLocalizations } from '../../customizables'; import type { VerificationCodeCardProps } from '../../elements'; @@ -45,7 +45,7 @@ export const SignInFactorOneEmailLinkCard = (props: SignInFactorOneEmailLinkCard const startEmailLinkVerification = () => { startEmailLinkFlow({ emailAddressId: props.factor.emailAddressId, - redirectUrl: buildEmailLinkRedirectUrl(signInContext, signInUrl), + redirectUrl: buildVerificationRedirectUrl(signInContext, signInUrl), }) .then(res => handleVerificationResult(res)) .catch(err => { diff --git a/packages/clerk-js/src/ui/components/SignUp/SignUpEmailLinkCard.tsx b/packages/clerk-js/src/ui/components/SignUp/SignUpEmailLinkCard.tsx index a5b701e4c9..d6d29ccb62 100644 --- a/packages/clerk-js/src/ui/components/SignUp/SignUpEmailLinkCard.tsx +++ b/packages/clerk-js/src/ui/components/SignUp/SignUpEmailLinkCard.tsx @@ -3,7 +3,7 @@ import type { SignUpResource } from '@clerk/types'; import React from 'react'; import { EmailLinkStatusCard } from '../../common'; -import { buildEmailLinkRedirectUrl } from '../../common/redirects'; +import { buildVerificationRedirectUrl } from '../../common/redirects'; import { useCoreSignUp, useEnvironment, useSignUpContext } from '../../contexts'; import { Flow, localizationKeys, useLocalizations } from '../../customizables'; import { VerificationLinkCard } from '../../elements'; @@ -36,7 +36,7 @@ export const SignUpEmailLinkCard = () => { }; const startEmailLinkVerification = () => { - return startEmailLinkFlow({ redirectUrl: buildEmailLinkRedirectUrl(signUpContext, displayConfig.signUpUrl) }) + return startEmailLinkFlow({ redirectUrl: buildVerificationRedirectUrl(signUpContext, displayConfig.signUpUrl) }) .then(res => handleVerificationResult(res)) .catch(err => { handleError(err, [], card.setError); diff --git a/packages/clerk-js/src/ui/components/UserProfile/EmailForm.tsx b/packages/clerk-js/src/ui/components/UserProfile/EmailForm.tsx index fce6291686..457612f36c 100644 --- a/packages/clerk-js/src/ui/components/UserProfile/EmailForm.tsx +++ b/packages/clerk-js/src/ui/components/UserProfile/EmailForm.tsx @@ -1,5 +1,5 @@ import { useReverification, useUser } from '@clerk/shared/react'; -import type { EmailAddressResource } from '@clerk/types'; +import type { EmailAddressResource, PrepareEmailAddressVerificationParams } from '@clerk/types'; import React from 'react'; import { useWizard, Wizard } from '../../common'; @@ -8,7 +8,7 @@ import { localizationKeys } from '../../customizables'; import type { FormProps } from '../../elements'; import { Form, FormButtons, FormContainer, useCardState, withCardStateProvider } from '../../elements'; import { handleError, useFormControl } from '../../utils'; -import { emailLinksEnabledForInstance, getVerificationStrategy } from './utils'; +import { emailLinksEnabledForInstance } from './utils'; import { VerifyWithCode } from './VerifyWithCode'; import { VerifyWithEnterpriseConnection } from './VerifyWithEnterpriseConnection'; import { VerifyWithLink } from './VerifyWithLink'; @@ -24,7 +24,7 @@ export const EmailForm = withCardStateProvider((props: EmailFormProps) => { const preferEmailLinks = emailLinksEnabledForInstance(environment); const [createEmailAddress] = useReverification(() => user?.createEmailAddress({ email: emailField.value })); const emailAddressRef = React.useRef(user?.emailAddresses.find(a => a.id === id)); - const strategy = getVerificationStrategy(emailAddressRef.current, preferEmailLinks); + const strategy = getEmailAddressVerificationStrategy(emailAddressRef.current, preferEmailLinks); const wizard = useWizard({ defaultStep: emailAddressRef.current ? 1 : 0, onNextStep: () => card.setError(undefined), @@ -80,6 +80,7 @@ export const EmailForm = withCardStateProvider((props: EmailFormProps) => { { onReset={onReset} /> )} - {strategy === 'saml' && ( + {strategy === 'enterprise_sso' && ( { ); }); + +// TODO - Handle `preferEmailLinks` +export const getEmailAddressVerificationStrategy = ( + emailAddress: EmailAddressResource | undefined, + preferLinks: boolean, +): PrepareEmailAddressVerificationParams['strategy'] => { + if (emailAddress?.matchesEnterpriseConnection) { + return 'enterprise_sso'; + } + + return preferLinks ? 'email_link' : 'email_code'; +}; diff --git a/packages/clerk-js/src/ui/components/UserProfile/VerifyWithEnterpriseConnection.tsx b/packages/clerk-js/src/ui/components/UserProfile/VerifyWithEnterpriseConnection.tsx index bb62c1f51b..c5ea328f03 100644 --- a/packages/clerk-js/src/ui/components/UserProfile/VerifyWithEnterpriseConnection.tsx +++ b/packages/clerk-js/src/ui/components/UserProfile/VerifyWithEnterpriseConnection.tsx @@ -2,11 +2,11 @@ import type { EmailAddressResource } from '@clerk/types'; import React from 'react'; import { EmailLinkStatusCard } from '../../common'; -import { buildEmailLinkRedirectUrl } from '../../common/redirects'; +import { buildVerificationRedirectUrl } from '../../common/redirects'; import { useEnvironment, useUserProfileContext } from '../../contexts'; import { Button, descriptors, localizationKeys } from '../../customizables'; import { FormButtonContainer, useCardState, VerificationLink } from '../../elements'; -import { useEnterpriseConnectionLink } from '../../hooks'; +import { useEnterpriseSsoLink } from '../../hooks'; import { handleError } from '../../utils'; type VerifyWithEnterpriseConnectionProps = { @@ -19,7 +19,7 @@ export const VerifyWithEnterpriseConnection = (props: VerifyWithEnterpriseConnec const { email, nextStep, onReset } = props; const card = useCardState(); const profileContext = useUserProfileContext(); - const { startEnterpriseConnectionLinkFlow } = useEnterpriseConnectionLink(email); + const { startEnterpriseSsoLinkFlow } = useEnterpriseSsoLink(email); const { displayConfig } = useEnvironment(); React.useEffect(() => { @@ -36,14 +36,15 @@ export const VerifyWithEnterpriseConnection = (props: VerifyWithEnterpriseConnec */ const { routing } = profileContext; const baseUrl = routing === 'virtual' ? displayConfig.userProfileUrl : ''; - const redirectUrl = buildEmailLinkRedirectUrl(profileContext, baseUrl); - startEnterpriseConnectionLinkFlow({ redirectUrl }) + const redirectUrl = buildVerificationRedirectUrl(profileContext, baseUrl); + startEnterpriseSsoLinkFlow({ redirectUrl }) .then(() => nextStep()) .catch(err => handleError(err, [], card.setError)); } return ( <> + {/* TODO - Handle localization */} { const { routing } = profileContext; const baseUrl = routing === 'virtual' ? displayConfig.userProfileUrl : ''; - const redirectUrl = buildEmailLinkRedirectUrl(profileContext, baseUrl); + const redirectUrl = buildVerificationRedirectUrl(profileContext, baseUrl); startEmailLinkFlow({ redirectUrl }) .then(() => nextStep()) .catch(err => handleError(err, [], card.setError)); diff --git a/packages/clerk-js/src/ui/components/UserProfile/utils.ts b/packages/clerk-js/src/ui/components/UserProfile/utils.ts index 2c96886446..0d00038fb1 100644 --- a/packages/clerk-js/src/ui/components/UserProfile/utils.ts +++ b/packages/clerk-js/src/ui/components/UserProfile/utils.ts @@ -3,7 +3,6 @@ import type { EmailAddressResource, EnvironmentResource, PhoneNumberResource, - PrepareEmailAddressVerificationParams, UserResource, } from '@clerk/types'; @@ -77,14 +76,3 @@ export function sortIdentificationBasedOnVerification { - if (emailAddress?.matchesEnterpriseConnection) { - return 'saml'; - } - - return preferLinks ? 'email_link' : 'email_code'; -}; diff --git a/packages/clerk-js/src/ui/hooks/index.ts b/packages/clerk-js/src/ui/hooks/index.ts index 33af5e3c8c..9769448f17 100644 --- a/packages/clerk-js/src/ui/hooks/index.ts +++ b/packages/clerk-js/src/ui/hooks/index.ts @@ -18,4 +18,4 @@ export * from './useDebounce'; export * from './useScrollLock'; export * from './useClerkModalStateParams'; export * from './useNavigateToFlowStart'; -export * from './useEnterpriseConnectionLink'; +export * from './useEnterpriseSsoLink'; diff --git a/packages/clerk-js/src/ui/hooks/useEnterpriseConnectionLink.ts b/packages/clerk-js/src/ui/hooks/useEnterpriseConnectionLink.ts deleted file mode 100644 index 20f491d095..0000000000 --- a/packages/clerk-js/src/ui/hooks/useEnterpriseConnectionLink.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type { - CreateEnterpriseConnectionLinkFlowReturn, - EmailAddressResource, - StartEnterpriseConnectionLinkFlowParams, -} from '@clerk/types'; -import React from 'react'; - -type EnterpriseConnectionLinkable = EmailAddressResource; -type EnterpriseConnectionLinkEmailAddressReturn = CreateEnterpriseConnectionLinkFlowReturn< - StartEnterpriseConnectionLinkFlowParams, - EmailAddressResource ->; - -function useEnterpriseConnectionLink( - resource: EnterpriseConnectionLinkable, -): EnterpriseConnectionLinkEmailAddressReturn { - const { startEnterpriseConnectionLinkFlow, cancelEnterpriseConnectionLinkFlow } = React.useMemo( - () => resource.createEnterpriseConnectionLinkFlow(), - [resource], - ); - - React.useEffect(() => { - return cancelEnterpriseConnectionLinkFlow; - }, []); - - return { - startEnterpriseConnectionLinkFlow, - cancelEnterpriseConnectionLinkFlow, - }; -} - -export { useEnterpriseConnectionLink }; diff --git a/packages/clerk-js/src/ui/hooks/useEnterpriseSsoLink.ts b/packages/clerk-js/src/ui/hooks/useEnterpriseSsoLink.ts new file mode 100644 index 0000000000..8eaa397979 --- /dev/null +++ b/packages/clerk-js/src/ui/hooks/useEnterpriseSsoLink.ts @@ -0,0 +1,29 @@ +import type { + CreateEnterpriseSsoFlowReturn, + EmailAddressResource, + StartEnterpriseSsoLinkFlowParams, +} from '@clerk/types'; +import React from 'react'; + +type EnterpriseSsoLinkEmailAddressReturn = CreateEnterpriseSsoFlowReturn< + StartEnterpriseSsoLinkFlowParams, + EmailAddressResource +>; + +function useEnterpriseSsoLink(resource: EmailAddressResource): EnterpriseSsoLinkEmailAddressReturn { + const { startEnterpriseSsoLinkFlow, cancelEnterpriseSsoLinkFlow } = React.useMemo( + () => resource.createEnterpriseSsoLinkFlow(), + [resource], + ); + + React.useEffect(() => { + return cancelEnterpriseSsoLinkFlow; + }, []); + + return { + startEnterpriseSsoLinkFlow, + cancelEnterpriseSsoLinkFlow, + }; +} + +export { useEnterpriseSsoLink }; diff --git a/packages/types/src/emailAddress.ts b/packages/types/src/emailAddress.ts index ace11cc4a4..e33b3d0ab5 100644 --- a/packages/types/src/emailAddress.ts +++ b/packages/types/src/emailAddress.ts @@ -3,9 +3,9 @@ import type { ClerkResource } from './resource'; import type { EmailCodeStrategy, EmailLinkStrategy, EnterpriseSSOStrategy } from './strategies'; import type { CreateEmailLinkFlowReturn, + CreateEnterpriseSsoFlowReturn, StartEmailLinkFlowParams, - StartEnterpriseSsoFlowParams, - StartEnterpriseSsoFlowReturn, + StartEnterpriseSsoLinkFlowParams, VerificationResource, } from './verification'; @@ -36,8 +36,8 @@ export interface EmailAddressResource extends ClerkResource { prepareVerification: (params: PrepareEmailAddressVerificationParams) => Promise; attemptVerification: (params: AttemptEmailAddressVerificationParams) => Promise; createEmailLinkFlow: () => CreateEmailLinkFlowReturn; - createEnterpriseConnectionLinkFlow: () => StartEnterpriseSsoFlowReturn< - StartEnterpriseSsoFlowParams, + createEnterpriseSsoLinkFlow: () => CreateEnterpriseSsoFlowReturn< + StartEnterpriseSsoLinkFlowParams, EmailAddressResource >; destroy: () => Promise; diff --git a/packages/types/src/verification.ts b/packages/types/src/verification.ts index dfa448e06e..de5152d47e 100644 --- a/packages/types/src/verification.ts +++ b/packages/types/src/verification.ts @@ -42,11 +42,11 @@ export type CreateEmailLinkFlowReturn = { cancelEmailLinkFlow: () => void; }; -export interface StartEnterpriseSsoFlowParams { +export interface StartEnterpriseSsoLinkFlowParams { redirectUrl: string; } -export type StartEnterpriseSsoFlowReturn = { - startEnterpriseConnectionLinkFlow: (params: Params) => Promise; - cancelEnterpriseConnectionLinkFlow: () => void; +export type CreateEnterpriseSsoFlowReturn = { + startEnterpriseSsoLinkFlow: (params: Params) => Promise; + cancelEnterpriseSsoLinkFlow: () => void; };