From 04cefebd75d1f93446e30a6ba9fa8544c29558cc Mon Sep 17 00:00:00 2001
From: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Date: Mon, 29 Sep 2025 16:11:39 +0100
Subject: [PATCH] add permissions.canUpdateOrganization to show/hide items in
org navbar (#24142)
---
.../SettingsLayoutAppDirClient.tsx | 28 ++++++++++++++-----
.../settings/(settings-layout)/layout.tsx | 4 ++-
2 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/SettingsLayoutAppDirClient.tsx b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/SettingsLayoutAppDirClient.tsx
index df73593f68..c379f2991b 100644
--- a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/SettingsLayoutAppDirClient.tsx
+++ b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/SettingsLayoutAppDirClient.tsx
@@ -175,6 +175,7 @@ const organizationAdminKeys = ["privacy", "OAuth Clients", "SSO", "directory_syn
export interface SettingsPermissions {
canViewRoles?: boolean;
canViewOrganizationBilling?: boolean;
+ canUpdateOrganization?: boolean;
}
const useTabs = ({
@@ -203,10 +204,13 @@ const useTabs = ({
};
} else if (tab.href === "/settings/organizations") {
const newArray = (tab?.children ?? []).filter(
- (child) => isOrgAdminOrOwner || !organizationAdminKeys.includes(child.name)
+ (child) =>
+ permissions?.canUpdateOrganization ||
+ isOrgAdminOrOwner ||
+ !organizationAdminKeys.includes(child.name)
);
- if (isOrgAdminOrOwner) {
+ if (permissions?.canUpdateOrganization || isOrgAdminOrOwner) {
newArray.splice(4, 0, {
name: "attributes",
href: "/settings/organizations/attributes",
@@ -238,7 +242,7 @@ const useTabs = ({
});
}
} else {
- if (isOrgAdminOrOwner) {
+ if (permissions?.canUpdateOrganization || isOrgAdminOrOwner) {
newArray.push({
name: "billing",
href: "/settings/organizations/billing",
@@ -264,7 +268,8 @@ const useTabs = ({
return { ...tab, children: filtered };
} else if (tab.href === "/settings/developer") {
const filtered = tab?.children?.filter(
- (childTab) => isOrgAdminOrOwner || childTab.name !== "admin_api"
+ (childTab) =>
+ permissions?.canUpdateOrganization || isOrgAdminOrOwner || childTab.name !== "admin_api"
);
return { ...tab, children: filtered };
}
@@ -274,12 +279,21 @@ const useTabs = ({
// check if name is in adminRequiredKeys
return processedTabs.filter((tab) => {
if (organizationRequiredKeys.includes(tab.name)) return !!orgBranding;
- if (tab.name === "other_teams" && !isOrgAdminOrOwner) return false;
+ if (tab.name === "other_teams" && !(permissions?.canUpdateOrganization || isOrgAdminOrOwner))
+ return false;
if (isAdmin) return true;
return !adminRequiredKeys.includes(tab.name);
});
- }, [isAdmin, orgBranding, isOrgAdminOrOwner, user, isDelegationCredentialEnabled, isPbacEnabled, permissions]);
+ }, [
+ isAdmin,
+ orgBranding,
+ isOrgAdminOrOwner,
+ user,
+ isDelegationCredentialEnabled,
+ isPbacEnabled,
+ permissions,
+ ]);
return processTabsMemod;
};
@@ -643,7 +657,7 @@ const SettingsSidebarContainer = ({
- {(!orgBranding?.id || isOrgAdminOrOwner) && (
+ {(!orgBranding?.id || permissions?.canUpdateOrganization || isOrgAdminOrOwner) && (
| null = null;
let canViewRoles = false;
let canViewOrganizationBilling = false;
+ let canUpdateOrganization = false;
const orgId = session?.user?.profile?.organizationId ?? session?.user.org?.id;
// For now we only grab organization features but it would be nice to fetch these on the server side for specific team feature flags
@@ -68,6 +69,7 @@ export default async function SettingsLayoutAppDir(props: SettingsLayoutProps) {
canViewRoles = roleActions[CrudAction.Read] ?? false;
const orgActions = PermissionMapper.toActionMap(organizationPermissions, Resource.Organization);
canViewOrganizationBilling = orgActions[CustomAction.ManageBilling] ?? isOrgAdminOrOwner;
+ canUpdateOrganization = orgActions[CrudAction.Update] ?? isOrgAdminOrOwner;
}
}
@@ -76,7 +78,7 @@ export default async function SettingsLayoutAppDir(props: SettingsLayoutProps) {
>
);