From a5ad23ca99303f5acf228703787f2a2f222a1ad2 Mon Sep 17 00:00:00 2001 From: Iago Dahlem Lorensini Date: Wed, 10 Jun 2026 10:35:52 -0300 Subject: [PATCH] feat(ui,localizations,shared): rename the organization profile SSO page to Security The OrganizationProfile navbar entry is now labeled "Security" with a shield icon and lives at the organization-security route path. A new organizationProfile.navbar.security localization key replaces organizationProfile.navbar.selfServeSSO. --- .changeset/perky-plums-agree.md | 8 +++++++ packages/localizations/src/en-US.ts | 2 +- packages/shared/src/types/localization.ts | 2 +- .../OrganizationProfileRoutes.tsx | 12 +++++----- ...OPage.tsx => OrganizationSecurityPage.tsx} | 4 ++-- .../__tests__/OrganizationProfile.test.tsx | 12 +++++----- packages/ui/src/constants.ts | 2 +- .../components/OrganizationProfile.ts | 6 ++--- packages/ui/src/utils/createCustomPages.tsx | 22 +++++++++---------- 9 files changed, 39 insertions(+), 31 deletions(-) create mode 100644 .changeset/perky-plums-agree.md rename packages/ui/src/components/OrganizationProfile/{OrganizationSelfServeSSOPage.tsx => OrganizationSecurityPage.tsx} (73%) diff --git a/.changeset/perky-plums-agree.md b/.changeset/perky-plums-agree.md new file mode 100644 index 00000000000..dcff561aad5 --- /dev/null +++ b/.changeset/perky-plums-agree.md @@ -0,0 +1,8 @@ +--- +'@clerk/localizations': patch +'@clerk/clerk-js': patch +'@clerk/shared': patch +'@clerk/ui': patch +--- + +Rename the `` SSO page to "Security". The navbar entry is now labeled "Security" with a shield icon, its route path changed from `organization-self-serve-sso` to `organization-security`, and a new `organizationProfile.navbar.security` localization key replaces `organizationProfile.navbar.selfServeSSO`. diff --git a/packages/localizations/src/en-US.ts b/packages/localizations/src/en-US.ts index 5ac237a6cd2..d288e183684 100644 --- a/packages/localizations/src/en-US.ts +++ b/packages/localizations/src/en-US.ts @@ -999,7 +999,7 @@ export const enUS: LocalizationResource = { navbar: { apiKeys: 'API keys', billing: 'Billing', - selfServeSSO: 'Single Sign-On (SSO)', + security: 'Security', description: 'Manage your organization.', general: 'General', members: 'Members', diff --git a/packages/shared/src/types/localization.ts b/packages/shared/src/types/localization.ts index ba4e114c4b9..757b01b64c3 100644 --- a/packages/shared/src/types/localization.ts +++ b/packages/shared/src/types/localization.ts @@ -1021,7 +1021,7 @@ export type __internal_LocalizationResource = { members: LocalizationValue; billing: LocalizationValue; apiKeys: LocalizationValue; - selfServeSSO: LocalizationValue; + security: LocalizationValue; }; badge__unverified: LocalizationValue; badge__automaticInvitation: LocalizationValue; diff --git a/packages/ui/src/components/OrganizationProfile/OrganizationProfileRoutes.tsx b/packages/ui/src/components/OrganizationProfile/OrganizationProfileRoutes.tsx index 6711bfb15d8..cae7a66cf3d 100644 --- a/packages/ui/src/components/OrganizationProfile/OrganizationProfileRoutes.tsx +++ b/packages/ui/src/components/OrganizationProfile/OrganizationProfileRoutes.tsx @@ -37,9 +37,9 @@ const OrganizationPaymentAttemptPage = lazy(() => })), ); -const OrganizationSelfServeSSOPage = lazy(() => - import(/* webpackChunkName: "op-self-serve-sso-page"*/ './OrganizationSelfServeSSOPage').then(module => ({ - default: module.OrganizationSelfServeSSOPage, +const OrganizationSecurityPage = lazy(() => + import(/* webpackChunkName: "op-security-page"*/ './OrganizationSecurityPage').then(module => ({ + default: module.OrganizationSecurityPage, })), ); @@ -54,7 +54,7 @@ export const OrganizationProfileRoutes = ({ contentRef }: OrganizationProfileRou isGeneralPageRoot, isBillingPageRoot, isAPIKeysPageRoot, - isSelfServeSsoPageRoot, + isSecurityPageRoot, shouldShowBilling, shouldShowSelfServeSSO, apiKeysProps, @@ -155,11 +155,11 @@ export const OrganizationProfileRoutes = ({ contentRef }: OrganizationProfileRou )} {shouldShowSelfServeSSO ? ( - + - + diff --git a/packages/ui/src/components/OrganizationProfile/OrganizationSelfServeSSOPage.tsx b/packages/ui/src/components/OrganizationProfile/OrganizationSecurityPage.tsx similarity index 73% rename from packages/ui/src/components/OrganizationProfile/OrganizationSelfServeSSOPage.tsx rename to packages/ui/src/components/OrganizationProfile/OrganizationSecurityPage.tsx index 9086097f711..0dd215f9f77 100644 --- a/packages/ui/src/components/OrganizationProfile/OrganizationSelfServeSSOPage.tsx +++ b/packages/ui/src/components/OrganizationProfile/OrganizationSecurityPage.tsx @@ -2,11 +2,11 @@ import { useOrganization } from '@clerk/shared/react'; import { ConfigureSSOContent } from '../ConfigureSSO/ConfigureSSO'; -type OrganizationSelfServeSSOPageProps = { +type OrganizationSecurityPageProps = { contentRef: React.RefObject; }; -export const OrganizationSelfServeSSOPage = ({ contentRef }: OrganizationSelfServeSSOPageProps) => { +export const OrganizationSecurityPage = ({ contentRef }: OrganizationSecurityPageProps) => { const { organization } = useOrganization(); if (!organization) { diff --git a/packages/ui/src/components/OrganizationProfile/__tests__/OrganizationProfile.test.tsx b/packages/ui/src/components/OrganizationProfile/__tests__/OrganizationProfile.test.tsx index 1b97d664ecf..80442b9810f 100644 --- a/packages/ui/src/components/OrganizationProfile/__tests__/OrganizationProfile.test.tsx +++ b/packages/ui/src/components/OrganizationProfile/__tests__/OrganizationProfile.test.tsx @@ -5,7 +5,7 @@ import { bindCreateFixtures } from '@/test/create-fixtures'; import { cleanup, render, screen, waitFor } from '@/test/utils'; import { OrganizationProfile } from '../'; -import { OrganizationSelfServeSSOPage } from '../OrganizationSelfServeSSOPage'; +import { OrganizationSecurityPage } from '../OrganizationSecurityPage'; const { createFixtures } = bindCreateFixtures('OrganizationProfile'); @@ -495,7 +495,7 @@ describe('OrganizationProfile', () => { }); render(, { wrapper }); - expect(await screen.findByText('Single Sign-On (SSO)')).toBeDefined(); + expect(await screen.findByText('Security')).toBeDefined(); }); it('does not include SSO when disabled at the instance level', async () => { @@ -515,7 +515,7 @@ describe('OrganizationProfile', () => { }); const { queryByText } = render(, { wrapper }); - await waitFor(() => expect(queryByText('Single Sign-On (SSO)')).toBeNull()); + await waitFor(() => expect(queryByText('Security')).toBeNull()); }); it('does not include SSO when the org has not opted in, even if the instance has it enabled', async () => { @@ -535,7 +535,7 @@ describe('OrganizationProfile', () => { }); const { queryByText } = render(, { wrapper }); - await waitFor(() => expect(queryByText('Single Sign-On (SSO)')).toBeNull()); + await waitFor(() => expect(queryByText('Security')).toBeNull()); }); it('includes SSO even when the user does not have the manage enterprise connections permission, but the page surfaces a warning', async () => { @@ -557,10 +557,10 @@ describe('OrganizationProfile', () => { fixtures.clerk.user?.getEnterpriseConnections.mockResolvedValue([]); render(, { wrapper }); - expect(await screen.findByText('Single Sign-On (SSO)')).toBeDefined(); + expect(await screen.findByText('Security')).toBeDefined(); cleanup(); - render(, { wrapper }); + render(, { wrapper }); expect(await screen.findByText(/you do not have permission to manage single sign-on/i)).toBeDefined(); expect( screen.queryByText(/contact your organization.*administrator to upgrade your permissions/i), diff --git a/packages/ui/src/constants.ts b/packages/ui/src/constants.ts index 410f39bd0c4..5974e6c1b46 100644 --- a/packages/ui/src/constants.ts +++ b/packages/ui/src/constants.ts @@ -12,7 +12,7 @@ export const ORGANIZATION_PROFILE_NAVBAR_ROUTE_ID = { MEMBERS: 'members', BILLING: 'billing', API_KEYS: 'apiKeys', - SELF_SERVE_SSO: 'selfServeSSO', + SECURITY: 'security', }; export const USER_BUTTON_ITEM_ID = { diff --git a/packages/ui/src/contexts/components/OrganizationProfile.ts b/packages/ui/src/contexts/components/OrganizationProfile.ts index 57eb50c8b36..8a44bad818e 100644 --- a/packages/ui/src/contexts/components/OrganizationProfile.ts +++ b/packages/ui/src/contexts/components/OrganizationProfile.ts @@ -25,7 +25,7 @@ export type OrganizationProfileContextType = OrganizationProfileCtx & { isGeneralPageRoot: boolean; isBillingPageRoot: boolean; isAPIKeysPageRoot: boolean; - isSelfServeSsoPageRoot: boolean; + isSecurityPageRoot: boolean; shouldShowBilling: boolean; shouldShowSelfServeSSO: boolean; }; @@ -81,7 +81,7 @@ export const useOrganizationProfileContext = (): OrganizationProfileContextType const isGeneralPageRoot = pages.routes[0].id === ORGANIZATION_PROFILE_NAVBAR_ROUTE_ID.GENERAL; const isBillingPageRoot = pages.routes[0].id === ORGANIZATION_PROFILE_NAVBAR_ROUTE_ID.BILLING; const isAPIKeysPageRoot = pages.routes[0].id === ORGANIZATION_PROFILE_NAVBAR_ROUTE_ID.API_KEYS; - const isSelfServeSsoPageRoot = pages.routes[0].id === ORGANIZATION_PROFILE_NAVBAR_ROUTE_ID.SELF_SERVE_SSO; + const isSecurityPageRoot = pages.routes[0].id === ORGANIZATION_PROFILE_NAVBAR_ROUTE_ID.SECURITY; const navigateToGeneralPageRoot = () => navigate(isGeneralPageRoot ? '../' : isMembersPageRoot ? './organization-general' : '../organization-general'); @@ -95,7 +95,7 @@ export const useOrganizationProfileContext = (): OrganizationProfileContextType isGeneralPageRoot, isBillingPageRoot, isAPIKeysPageRoot, - isSelfServeSsoPageRoot, + isSecurityPageRoot, shouldShowBilling, shouldShowSelfServeSSO, }; diff --git a/packages/ui/src/utils/createCustomPages.tsx b/packages/ui/src/utils/createCustomPages.tsx index 381e3e1182c..fdc01ff01e4 100644 --- a/packages/ui/src/utils/createCustomPages.tsx +++ b/packages/ui/src/utils/createCustomPages.tsx @@ -10,7 +10,7 @@ import type { CustomPage, EnvironmentResource, LoadedClerk } from '@clerk/shared import { ORGANIZATION_PROFILE_NAVBAR_ROUTE_ID, USER_PROFILE_NAVBAR_ROUTE_ID } from '../constants'; import type { NavbarRoute } from '../elements/Navbar'; -import { Building, Code, Connections, CreditCard, ShieldCheck, UserCircle, Users } from '../icons'; +import { Building, Code, CreditCard, ShieldCheck, UserCircle, Users } from '../icons'; import { localizationKeys } from '../localization'; import { ExternalElementMounter } from './ExternalElementMounter'; import { isDevelopmentSDK } from './runtimeEnvironment'; @@ -52,11 +52,11 @@ type CreateCustomPagesParams = { getDefaultRoutes: ({ commerce, apiKeys, - selfServeSSO, + security, }: { commerce: boolean; apiKeys: boolean; - selfServeSSO: boolean; + security: boolean; }) => GetDefaultRoutesReturnType; setFirstPathToRoot: (routes: NavbarRoute[]) => NavbarRoute[]; excludedPathsFromDuplicateWarning: string[]; @@ -118,7 +118,7 @@ const createCustomPages = ( apiKeys: organization ? !disabledOrganizationAPIKeysFeature(clerk, environment) : !disabledUserAPIKeysFeature(clerk, environment), - selfServeSSO: organization ? shouldShowSelfServeSSO && !disabledSelfServeSSOFeature(clerk, environment) : false, + security: organization ? shouldShowSelfServeSSO && !disabledSelfServeSSOFeature(clerk, environment) : false, }); if (isDevelopmentSDK(clerk)) { @@ -328,11 +328,11 @@ const getUserProfileDefaultRoutes = ({ const getOrganizationProfileDefaultRoutes = ({ commerce, apiKeys, - selfServeSSO, + security, }: { commerce: boolean; apiKeys: boolean; - selfServeSSO: boolean; + security: boolean; }): GetDefaultRoutesReturnType => { const INITIAL_ROUTES: NavbarRoute[] = [ { @@ -364,12 +364,12 @@ const getOrganizationProfileDefaultRoutes = ({ path: 'organization-api-keys', }); } - if (selfServeSSO) { + if (security) { INITIAL_ROUTES.push({ - name: localizationKeys('organizationProfile.navbar.selfServeSSO'), - id: ORGANIZATION_PROFILE_NAVBAR_ROUTE_ID.SELF_SERVE_SSO, - icon: Connections, - path: 'organization-self-serve-sso', + name: localizationKeys('organizationProfile.navbar.security'), + id: ORGANIZATION_PROFILE_NAVBAR_ROUTE_ID.SECURITY, + icon: ShieldCheck, + path: 'organization-security', }); }