1- import { __internal_useUserEnterpriseConnections , useSession , useUser } from '@clerk/shared/react/index' ;
2- import type { EnterpriseConnectionResource } from '@clerk/shared/types' ;
1+ import type { UseUserEnterpriseConnectionsReturn } from '@clerk/shared/react/index' ;
2+ import { useSession , useUser } from '@clerk/shared/react/index' ;
3+ import type { EnterpriseConnectionResource , SignedInSessionResource , UserResource } from '@clerk/shared/types' ;
34import React , { type PropsWithChildren , useCallback } from 'react' ;
45
56import { useCardState } from '@/elements/contexts' ;
@@ -32,32 +33,54 @@ export interface ConfigureSSOData {
3233 */
3334 contentRef : React . RefObject < HTMLDivElement > ;
3435 /**
35- * Creates a new enterprise connection.
36+ * Creates a new enterprise connection
3637 */
3738 createEnterpriseConnection : ( provider : ProviderType ) => Promise < void > ;
39+ /**
40+ * Updates an existing enterprise connection
41+ */
42+ updateEnterpriseConnection : UseUserEnterpriseConnectionsReturn [ 'updateEnterpriseConnection' ] ;
43+ /**
44+ * Deletes an enterprise connection
45+ */
46+ deleteEnterpriseConnection : UseUserEnterpriseConnectionsReturn [ 'deleteEnterpriseConnection' ] ;
47+ /**
48+ * Determines if the user's domain is already wired to an enterprise connection that
49+ * doesn't belong to the org they're currently configuring
50+ */
51+ isDomainTakenByOtherOrg : boolean ;
3852}
3953
4054interface ConfigureSSOProviderProps {
4155 enterpriseConnection : EnterpriseConnectionResource | undefined ;
56+ hasSuccessfulTestRun : boolean ;
4257 contentRef : React . RefObject < HTMLDivElement > ;
58+ createEnterpriseConnection : UseUserEnterpriseConnectionsReturn [ 'createEnterpriseConnection' ] ;
59+ updateEnterpriseConnection : UseUserEnterpriseConnectionsReturn [ 'updateEnterpriseConnection' ] ;
60+ deleteEnterpriseConnection : UseUserEnterpriseConnectionsReturn [ 'deleteEnterpriseConnection' ] ;
4361}
4462
4563const ConfigureSSOContext = React . createContext < ConfigureSSOData | null > ( null ) ;
4664ConfigureSSOContext . displayName = 'ConfigureSSOContext' ;
4765
4866export const ConfigureSSOProvider = ( {
4967 enterpriseConnection,
68+ hasSuccessfulTestRun,
5069 contentRef,
70+ createEnterpriseConnection : createEnterpriseConnectionApi ,
71+ updateEnterpriseConnection,
72+ deleteEnterpriseConnection,
5173 children,
5274} : PropsWithChildren < ConfigureSSOProviderProps > ) : JSX . Element => {
5375 const [ provider , setProvider ] = React . useState < ProviderType | undefined > (
5476 enterpriseConnection ?. provider as ProviderType ,
5577 ) ;
56- const enterpriseConnectionApi = __internal_useUserEnterpriseConnections ( ) ;
5778 const { user } = useUser ( ) ;
5879 const { session } = useSession ( ) ;
5980 const card = useCardState ( ) ;
60- const initialStepId = deriveInitialStep ( enterpriseConnection ) ;
81+
82+ const isDomainTakenByOtherOrg = checkDomainTakenByOtherOrg ( user , session , enterpriseConnection ) ;
83+ const initialStepId = deriveInitialStep ( enterpriseConnection , { isDomainTakenByOtherOrg, hasSuccessfulTestRun } ) ;
6184
6285 const createEnterpriseConnection = useCallback (
6386 async ( provider : ProviderType ) : Promise < void > => {
@@ -71,7 +94,7 @@ export const ConfigureSSOProvider = ({
7194 card . setLoading ( ) ;
7295
7396 try {
74- await enterpriseConnectionApi . createEnterpriseConnection ( {
97+ await createEnterpriseConnectionApi ( {
7598 provider,
7699 name : emailDomain ,
77100 organizationId,
@@ -80,19 +103,31 @@ export const ConfigureSSOProvider = ({
80103 card . setIdle ( ) ;
81104 }
82105 } ,
83- [ user , card , session , enterpriseConnectionApi ] ,
106+ [ user , card , session , createEnterpriseConnectionApi ] ,
84107 ) ;
85108
86109 const value = React . useMemo < ConfigureSSOData > (
87110 ( ) => ( {
111+ provider,
112+ contentRef,
113+ setProvider,
88114 initialStepId,
89115 enterpriseConnection,
90- provider ,
116+ isDomainTakenByOtherOrg ,
91117 createEnterpriseConnection,
92- setProvider ,
93- contentRef ,
118+ updateEnterpriseConnection ,
119+ deleteEnterpriseConnection ,
94120 } ) ,
95- [ initialStepId , enterpriseConnection , createEnterpriseConnection , provider , contentRef ] ,
121+ [
122+ provider ,
123+ contentRef ,
124+ initialStepId ,
125+ enterpriseConnection ,
126+ createEnterpriseConnection ,
127+ updateEnterpriseConnection ,
128+ deleteEnterpriseConnection ,
129+ isDomainTakenByOtherOrg ,
130+ ] ,
96131 ) ;
97132
98133 return < ConfigureSSOContext . Provider value = { value } > { children } </ ConfigureSSOContext . Provider > ;
@@ -105,3 +140,20 @@ export const useConfigureSSO = (): ConfigureSSOData => {
105140 }
106141 return ctx ;
107142} ;
143+
144+ /**
145+ * Determines if the user's domain is already wired to an enterprise connection that
146+ * doesn't belong to the org they're currently configuring
147+ */
148+ const checkDomainTakenByOtherOrg = (
149+ user : UserResource | null | undefined ,
150+ session : SignedInSessionResource | null | undefined ,
151+ enterpriseConnection : EnterpriseConnectionResource | undefined ,
152+ ) : boolean => {
153+ const emailToVerify =
154+ user ?. primaryEmailAddress ?? user ?. emailAddresses ?. find ( e => e . verification . status !== 'verified' ) ;
155+ const isVerified = emailToVerify ?. verification . status === 'verified' ;
156+ const activeOrganizationId = session ?. lastActiveOrganizationId ?? null ;
157+
158+ return Boolean ( isVerified && enterpriseConnection && enterpriseConnection . organizationId !== activeOrganizationId ) ;
159+ } ;
0 commit comments