diff --git a/apps/client/src/components/settings/settings-sidebar.tsx b/apps/client/src/components/settings/settings-sidebar.tsx index 1c49f918..6ac3587f 100644 --- a/apps/client/src/components/settings/settings-sidebar.tsx +++ b/apps/client/src/components/settings/settings-sidebar.tsx @@ -46,6 +46,7 @@ interface DataItem { isCloud?: boolean; isEnterprise?: boolean; isAdmin?: boolean; + isOwner?: boolean; isSelfhosted?: boolean; showDisabledInNonEE?: boolean; } @@ -123,8 +124,9 @@ const groupedData: DataGroup[] = [ icon: IconHistory, path: "/settings/audit", isEnterprise: true, - isAdmin: true, + isOwner: true, isSelfhosted: true, + showDisabledInNonEE: true, }, ], }, @@ -145,7 +147,7 @@ export default function SettingsSidebar() { const location = useLocation(); const [active, setActive] = useState(location.pathname); const { goBack } = useSettingsNavigation(); - const { isAdmin } = useUserRole(); + const { isAdmin, isOwner } = useUserRole(); const [workspace] = useAtom(workspaceAtom); const [mobileSidebarOpened] = useAtom(mobileSidebarAtom); const toggleMobileSidebar = useToggleSidebar(mobileSidebarAtom); @@ -154,34 +156,36 @@ export default function SettingsSidebar() { setActive(location.pathname); }, [location.pathname]); + const hasRoleAccess = (item: DataItem) => { + if (item.isOwner) return isOwner; + if (item.isAdmin) return isAdmin; + return true; + }; + const canShowItem = (item: DataItem) => { if (item.showDisabledInNonEE && item.isEnterprise) { - // Check admin permission regardless of license - return item.isAdmin ? isAdmin : true; + if (item.isSelfhosted && isCloud()) return false; + return hasRoleAccess(item); } if (item.isCloud && item.isEnterprise) { if (!(isCloud() || workspace?.hasLicenseKey)) return false; - return item.isAdmin ? isAdmin : true; + return hasRoleAccess(item); } if (item.isCloud) { - return isCloud() ? (item.isAdmin ? isAdmin : true) : false; + return isCloud() ? hasRoleAccess(item) : false; } if (item.isSelfhosted) { - return !isCloud() ? (item.isAdmin ? isAdmin : true) : false; + return !isCloud() ? hasRoleAccess(item) : false; } if (item.isEnterprise) { - return workspace?.hasLicenseKey ? (item.isAdmin ? isAdmin : true) : false; + return workspace?.hasLicenseKey ? hasRoleAccess(item) : false; } - if (item.isAdmin) { - return isAdmin; - } - - return true; + return hasRoleAccess(item); }; const isItemDisabled = (item: DataItem) => { diff --git a/apps/client/src/ee/audit/pages/audit-logs.tsx b/apps/client/src/ee/audit/pages/audit-logs.tsx index 10e390d8..05f7881a 100644 --- a/apps/client/src/ee/audit/pages/audit-logs.tsx +++ b/apps/client/src/ee/audit/pages/audit-logs.tsx @@ -47,7 +47,7 @@ function retentionToDays(amount: number, unit: RetentionUnit): number { export default function AuditLogs() { const { t } = useTranslation(); - const { isAdmin } = useUserRole(); + const { isOwner } = useUserRole(); const { cursor, goNext, goPrev, resetCursor } = useCursorPaginate(); const [eventFilter, setEventFilter] = useState(null); @@ -86,7 +86,7 @@ export default function AuditLogs() { const { data, isLoading } = useAuditLogsQuery(params); - if (!isAdmin) { + if (!isOwner) { return null; } diff --git a/apps/server/src/core/casl/abilities/workspace-ability.factory.ts b/apps/server/src/core/casl/abilities/workspace-ability.factory.ts index 7344fcbb..683cf4b6 100644 --- a/apps/server/src/core/casl/abilities/workspace-ability.factory.ts +++ b/apps/server/src/core/casl/abilities/workspace-ability.factory.ts @@ -41,6 +41,7 @@ function buildWorkspaceOwnerAbility() { can(WorkspaceCaslAction.Manage, WorkspaceCaslSubject.Member); can(WorkspaceCaslAction.Manage, WorkspaceCaslSubject.Attachment); can(WorkspaceCaslAction.Manage, WorkspaceCaslSubject.API); + can(WorkspaceCaslAction.Manage, WorkspaceCaslSubject.Audit); return build(); } diff --git a/apps/server/src/core/casl/interfaces/workspace-ability.type.ts b/apps/server/src/core/casl/interfaces/workspace-ability.type.ts index 00d1677d..896b5338 100644 --- a/apps/server/src/core/casl/interfaces/workspace-ability.type.ts +++ b/apps/server/src/core/casl/interfaces/workspace-ability.type.ts @@ -12,6 +12,7 @@ export enum WorkspaceCaslSubject { Group = 'group', Attachment = 'attachment', API = 'api_key', + Audit = 'audit', } export type IWorkspaceAbility = @@ -20,4 +21,5 @@ export type IWorkspaceAbility = | [WorkspaceCaslAction, WorkspaceCaslSubject.Space] | [WorkspaceCaslAction, WorkspaceCaslSubject.Group] | [WorkspaceCaslAction, WorkspaceCaslSubject.Attachment] - | [WorkspaceCaslAction, WorkspaceCaslSubject.API]; + | [WorkspaceCaslAction, WorkspaceCaslSubject.API] + | [WorkspaceCaslAction, WorkspaceCaslSubject.Audit]; diff --git a/apps/server/src/ee b/apps/server/src/ee index c9f8c198..33a93a46 160000 --- a/apps/server/src/ee +++ b/apps/server/src/ee @@ -1 +1 @@ -Subproject commit c9f8c1983e9993fbfdf7406e8cc5830eba01bd7d +Subproject commit 33a93a46af1b89a6fc169b3c22bd5b9bddf0e86b