Skip to content

Commit d8a8c2a

Browse files
committed
Show CTA when user does not have manage permission
1 parent a7071b0 commit d8a8c2a

2 files changed

Lines changed: 78 additions & 16 deletions

File tree

packages/ui/src/components/ConfigureSSO/ConfigureSSO.tsx

Lines changed: 75 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,25 @@ import { __internal_useUserEnterpriseConnections, useOrganization, useUser } fro
22
import type { __experimental_ConfigureSSOProps } from '@clerk/shared/types';
33
import React from 'react';
44

5+
import { useProtect } from '@/common';
56
import { 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';
719
import { ApplicationLogo } from '@/elements/ApplicationLogo';
820
import { withCardStateProvider } from '@/elements/contexts';
921
import { NavBar, NavbarContextProvider } from '@/elements/Navbar';
1022
import { ProfileCard } from '@/elements/ProfileCard';
11-
import { BoxIcon } from '@/icons';
23+
import { BoxIcon, ExclamationTriangle } from '@/icons';
1224
import { Route, Switch } from '@/router';
1325

1426
import { 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+
231293
export const ConfigureSSO: React.ComponentType<__experimental_ConfigureSSOProps> =
232294
withCardStateProvider(ConfigureSSOInternal);

packages/ui/src/components/ConfigureSSO/steps/VerifyDomainStep.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,16 +145,16 @@ export const VerifyDomainStep = (): JSX.Element | null => {
145145
<Col sx={t => ({ gap: t.space.$1, textAlign: 'center', maxWidth: t.sizes.$66 })}>
146146
<Heading
147147
textVariant='h1'
148-
sx={t => ({ color: t.colors.$colorForeground, fontSize: t.fontSizes.$sm })}
148+
sx={t => ({ color: t.colors.$colorForeground, fontSize: t.fontSizes.$md })}
149149
>
150-
That domain is already used for a different enterprise connection.
150+
That domain already has an SSO connection
151151
</Heading>
152152
<Text
153153
as='p'
154154
variant='body'
155155
sx={t => ({ color: t.colors.$colorMutedForeground })}
156156
>
157-
Contact the application owner to configure an SSO connection using the same domain.
157+
Contact the application's administrator to get access through the existing connection.
158158
</Text>
159159
</Col>
160160
</>

0 commit comments

Comments
 (0)