@@ -2,13 +2,25 @@ import { __internal_useUserEnterpriseConnections, useOrganization, useUser } fro
22import type { __experimental_ConfigureSSOProps } from '@clerk/shared/types' ;
33import React from 'react' ;
44
5+ import { useProtect } from '@/common' ;
56import { useEnvironment , withCoreUserGuard } from '@/contexts' ;
6- import { Box , Col , descriptors , Flex , Flow , Icon , localizationKeys , Text , useAppearance } from '@/customizables' ;
7+ import {
8+ Box ,
9+ Col ,
10+ descriptors ,
11+ Flex ,
12+ Flow ,
13+ Heading ,
14+ Icon ,
15+ localizationKeys ,
16+ Text ,
17+ useAppearance ,
18+ } from '@/customizables' ;
719import { ApplicationLogo } from '@/elements/ApplicationLogo' ;
820import { withCardStateProvider } from '@/elements/contexts' ;
921import { NavBar , NavbarContextProvider } from '@/elements/Navbar' ;
1022import { ProfileCard } from '@/elements/ProfileCard' ;
11- import { BoxIcon } from '@/icons' ;
23+ import { BoxIcon , ExclamationTriangle } from '@/icons' ;
1224import { Route , Switch } from '@/router' ;
1325
1426import { ConfigureSSOFlowProvider , useConfigureSSOFlow } from './ConfigureSSOContext' ;
@@ -41,14 +53,24 @@ const AuthenticatedContent = withCoreUserGuard(() => {
4153 const { parsedOptions } = useAppearance ( ) ;
4254 const hasLogo = Boolean ( parsedOptions . logoImageUrl || logoImageUrl ) ;
4355
56+ // Gate the entire wizard behind the org-level permission. When the
57+ // user can't manage enterprise connections, we still render the
58+ // outer sidebar/title chrome but replace the wizard with a
59+ // permissions-error message so the layout stays consistent
60+ const canManageEnterpriseConnections = useProtect ( {
61+ permission : 'org:sys_enterprise_connections:manage' ,
62+ } ) ;
63+
4464 const {
4565 data : enterpriseConnections ,
4666 isLoading : isLoadingEnterpriseConnections ,
4767 createEnterpriseConnection,
4868 updateEnterpriseConnection,
4969 deleteEnterpriseConnection,
5070 revalidate : revalidateEnterpriseConnections ,
51- } = __internal_useUserEnterpriseConnections ( { enabled : true } ) ;
71+ } = __internal_useUserEnterpriseConnections ( {
72+ enabled : canManageEnterpriseConnections ,
73+ } ) ;
5274 // Currently FAPI only supports one enterprise connection per user
5375 const enterpriseConnection = enterpriseConnections ?. [ 0 ] ;
5476
@@ -126,16 +148,20 @@ const AuthenticatedContent = withCoreUserGuard(() => {
126148 flex : 1 ,
127149 } ) }
128150 >
129- < ConfigureSSOFlowProvider
130- enterpriseConnection = { enterpriseConnection }
131- isLoading = { isLoadingEnterpriseConnections }
132- createEnterpriseConnection = { createEnterpriseConnection }
133- updateEnterpriseConnection = { updateEnterpriseConnection }
134- deleteEnterpriseConnection = { deleteEnterpriseConnection }
135- revalidate = { revalidateEnterpriseConnections }
136- >
137- < ConfigureSSOSteps />
138- </ ConfigureSSOFlowProvider >
151+ { canManageEnterpriseConnections ? (
152+ < ConfigureSSOFlowProvider
153+ enterpriseConnection = { enterpriseConnection }
154+ isLoading = { isLoadingEnterpriseConnections }
155+ createEnterpriseConnection = { createEnterpriseConnection }
156+ updateEnterpriseConnection = { updateEnterpriseConnection }
157+ deleteEnterpriseConnection = { deleteEnterpriseConnection }
158+ revalidate = { revalidateEnterpriseConnections }
159+ >
160+ < ConfigureSSOSteps />
161+ </ ConfigureSSOFlowProvider >
162+ ) : (
163+ < NoPermission />
164+ ) }
139165 </ Col >
140166 </ NavbarContextProvider >
141167 </ ProfileCard . Root >
@@ -228,5 +254,41 @@ const OrganizationSidebarSubtitle = () => {
228254 ) ;
229255} ;
230256
257+ /**
258+ * Rendered in place of the wizard when the user lacks the
259+ * `org:sys_enterprise_connections:manage` permission. The outer
260+ * sidebar / title chrome stays the same; only the body changes
261+ */
262+ const NoPermission = ( ) => (
263+ < Flex
264+ align = 'center'
265+ justify = 'center'
266+ sx = { t => ( { flex : 1 , padding : t . space . $8 } ) }
267+ >
268+ < Col
269+ align = 'center'
270+ sx = { t => ( { gap : t . space . $2 , textAlign : 'center' , maxWidth : t . sizes . $66 } ) }
271+ >
272+ < Icon
273+ icon = { ExclamationTriangle }
274+ sx = { t => ( { width : t . sizes . $8 , height : t . sizes . $8 , color : t . colors . $neutralAlpha600 } ) }
275+ />
276+ < Heading
277+ textVariant = 'h1'
278+ sx = { t => ( { color : t . colors . $colorForeground , fontSize : t . fontSizes . $sm } ) }
279+ >
280+ You do not have permission to manage enterprise connections
281+ </ Heading >
282+ < Text
283+ as = 'p'
284+ variant = 'body'
285+ sx = { t => ( { color : t . colors . $colorMutedForeground } ) }
286+ >
287+ Contact your organization administrator in order to have permissions to manage enterprise connections.
288+ </ Text >
289+ </ Col >
290+ </ Flex >
291+ ) ;
292+
231293export const ConfigureSSO : React . ComponentType < __experimental_ConfigureSSOProps > =
232294 withCardStateProvider ( ConfigureSSOInternal ) ;
0 commit comments