From 20287973b1375582184032d00d62078c8bf9a9a2 Mon Sep 17 00:00:00 2001 From: Carlos Monastyrski Date: Thu, 28 Aug 2025 20:33:59 -0300 Subject: [PATCH] Improve Audit Logs permissions --- .../services/audit-log/audit-log-service.ts | 14 +- .../ee/services/permission/default-roles.ts | 5 +- .../ee/services/permission/org-permission.ts | 17 +- .../services/permission/project-permission.ts | 8 +- .../context/OrgPermissionContext/index.tsx | 1 + .../src/context/OrgPermissionContext/types.ts | 6 +- .../ProjectPermissionContext/index.tsx | 1 + .../context/ProjectPermissionContext/types.ts | 6 +- frontend/src/context/index.tsx | 2 + .../AuditLogsPage/components/LogsSection.tsx | 316 ++++++++++-------- .../components/OrgRoleModifySection.utils.ts | 9 +- .../OrgPermissionAuditLogsRow.tsx | 164 +++++++++ .../RolePermissionRow.tsx | 1 + .../RolePermissionsSection.tsx | 10 +- .../ProjectRoleModifySection.utils.tsx | 16 +- .../IntegrationAuditLogsSection.tsx | 4 +- .../components/SecretSyncAuditLogsSection.tsx | 4 +- 17 files changed, 407 insertions(+), 177 deletions(-) create mode 100644 frontend/src/pages/organization/RoleByIDPage/components/RolePermissionsSection/OrgPermissionAuditLogsRow.tsx diff --git a/backend/src/ee/services/audit-log/audit-log-service.ts b/backend/src/ee/services/audit-log/audit-log-service.ts index 06186d54b..ece5edaf9 100644 --- a/backend/src/ee/services/audit-log/audit-log-service.ts +++ b/backend/src/ee/services/audit-log/audit-log-service.ts @@ -6,9 +6,9 @@ import { getConfig } from "@app/lib/config/env"; import { BadRequestError } from "@app/lib/errors"; import { ActorType } from "@app/services/auth/auth-type"; -import { OrgPermissionActions, OrgPermissionSubjects } from "../permission/org-permission"; +import { OrgPermissionAuditLogsActions, OrgPermissionSubjects } from "../permission/org-permission"; import { TPermissionServiceFactory } from "../permission/permission-service-types"; -import { ProjectPermissionActions, ProjectPermissionSub } from "../permission/project-permission"; +import { ProjectPermissionAuditLogsActions, ProjectPermissionSub } from "../permission/project-permission"; import { TAuditLogDALFactory } from "./audit-log-dal"; import { TAuditLogQueueServiceFactory } from "./audit-log-queue"; import { EventType, TAuditLogServiceFactory } from "./audit-log-types"; @@ -41,7 +41,10 @@ export const auditLogServiceFactory = ({ actorOrgId, actionProjectType: ActionProjectType.Any }); - ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.AuditLogs); + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionAuditLogsActions.Read, + ProjectPermissionSub.AuditLogs + ); } else { // Organization-wide logs const { permission } = await permissionService.getOrgPermission( @@ -52,7 +55,10 @@ export const auditLogServiceFactory = ({ actorOrgId ); - ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.AuditLogs); + ForbiddenError.from(permission).throwUnlessCan( + OrgPermissionAuditLogsActions.Read, + OrgPermissionSubjects.AuditLogs + ); } // If project ID is not provided, then we need to return all the audit logs for the organization itself. diff --git a/backend/src/ee/services/permission/default-roles.ts b/backend/src/ee/services/permission/default-roles.ts index 349130d8e..9329c3c7f 100644 --- a/backend/src/ee/services/permission/default-roles.ts +++ b/backend/src/ee/services/permission/default-roles.ts @@ -2,6 +2,7 @@ import { AbilityBuilder, createMongoAbility, MongoAbility } from "@casl/ability" import { ProjectPermissionActions, + ProjectPermissionAuditLogsActions, ProjectPermissionCertificateActions, ProjectPermissionCmekActions, ProjectPermissionCommitsActions, @@ -394,7 +395,7 @@ const buildMemberPermissionRules = () => { ); can([ProjectPermissionActions.Read], ProjectPermissionSub.Role); - can([ProjectPermissionActions.Read], ProjectPermissionSub.AuditLogs); + can([ProjectPermissionAuditLogsActions.Read], ProjectPermissionSub.AuditLogs); can([ProjectPermissionActions.Read], ProjectPermissionSub.IpAllowList); // double check if all CRUD are needed for CA and Certificates @@ -502,7 +503,7 @@ const buildViewerPermissionRules = () => { can(ProjectPermissionActions.Read, ProjectPermissionSub.Settings); can(ProjectPermissionActions.Read, ProjectPermissionSub.Environments); can(ProjectPermissionActions.Read, ProjectPermissionSub.Tags); - can(ProjectPermissionActions.Read, ProjectPermissionSub.AuditLogs); + can(ProjectPermissionAuditLogsActions.Read, ProjectPermissionSub.AuditLogs); can(ProjectPermissionActions.Read, ProjectPermissionSub.IpAllowList); can(ProjectPermissionActions.Read, ProjectPermissionSub.CertificateAuthorities); can(ProjectPermissionCertificateActions.Read, ProjectPermissionSub.Certificates); diff --git a/backend/src/ee/services/permission/org-permission.ts b/backend/src/ee/services/permission/org-permission.ts index 2436dae2a..d0b1ca3dd 100644 --- a/backend/src/ee/services/permission/org-permission.ts +++ b/backend/src/ee/services/permission/org-permission.ts @@ -23,6 +23,10 @@ export enum OrgPermissionAppConnectionActions { Connect = "connect" } +export enum OrgPermissionAuditLogsActions { + Read = "read" +} + export enum OrgPermissionKmipActions { Proxy = "proxy", Setup = "setup" @@ -125,7 +129,7 @@ export type OrgPermissionSet = | [OrgPermissionBillingActions, OrgPermissionSubjects.Billing] | [OrgPermissionIdentityActions, OrgPermissionSubjects.Identity] | [OrgPermissionActions, OrgPermissionSubjects.Kms] - | [OrgPermissionActions, OrgPermissionSubjects.AuditLogs] + | [OrgPermissionAuditLogsActions, OrgPermissionSubjects.AuditLogs] | [OrgPermissionActions, OrgPermissionSubjects.ProjectTemplates] | [OrgPermissionGatewayActions, OrgPermissionSubjects.Gateway] | [ @@ -214,7 +218,9 @@ export const OrgPermissionSchema = z.discriminatedUnion("subject", [ }), z.object({ subject: z.literal(OrgPermissionSubjects.AuditLogs).describe("The entity this permission pertains to."), - action: CASL_ACTION_SCHEMA_NATIVE_ENUM(OrgPermissionActions).describe("Describe what action an entity can take.") + action: CASL_ACTION_SCHEMA_NATIVE_ENUM(OrgPermissionAuditLogsActions).describe( + "Describe what action an entity can take." + ) }), z.object({ subject: z.literal(OrgPermissionSubjects.ProjectTemplates).describe("The entity this permission pertains to."), @@ -340,10 +346,7 @@ const buildAdminPermission = () => { can(OrgPermissionActions.Edit, OrgPermissionSubjects.Kms); can(OrgPermissionActions.Delete, OrgPermissionSubjects.Kms); - can(OrgPermissionActions.Read, OrgPermissionSubjects.AuditLogs); - can(OrgPermissionActions.Create, OrgPermissionSubjects.AuditLogs); - can(OrgPermissionActions.Edit, OrgPermissionSubjects.AuditLogs); - can(OrgPermissionActions.Delete, OrgPermissionSubjects.AuditLogs); + can(OrgPermissionAuditLogsActions.Read, OrgPermissionSubjects.AuditLogs); can(OrgPermissionActions.Read, OrgPermissionSubjects.ProjectTemplates); can(OrgPermissionActions.Create, OrgPermissionSubjects.ProjectTemplates); @@ -416,7 +419,7 @@ const buildMemberPermission = () => { can(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity); can(OrgPermissionIdentityActions.Delete, OrgPermissionSubjects.Identity); - can(OrgPermissionActions.Read, OrgPermissionSubjects.AuditLogs); + can(OrgPermissionAuditLogsActions.Read, OrgPermissionSubjects.AuditLogs); can(OrgPermissionAppConnectionActions.Connect, OrgPermissionSubjects.AppConnections); can(OrgPermissionGatewayActions.ListGateways, OrgPermissionSubjects.Gateway); diff --git a/backend/src/ee/services/permission/project-permission.ts b/backend/src/ee/services/permission/project-permission.ts index ab8fea5df..20b4344d3 100644 --- a/backend/src/ee/services/permission/project-permission.ts +++ b/backend/src/ee/services/permission/project-permission.ts @@ -164,6 +164,10 @@ export enum ProjectPermissionSecretEventActions { SubscribeImportMutations = "subscribe-on-import-mutations" } +export enum ProjectPermissionAuditLogsActions { + Read = "read" +} + export enum ProjectPermissionSub { Role = "role", Member = "member", @@ -304,7 +308,7 @@ export type ProjectPermissionSet = | [ProjectPermissionGroupActions, ProjectPermissionSub.Groups] | [ProjectPermissionActions, ProjectPermissionSub.Integrations] | [ProjectPermissionActions, ProjectPermissionSub.Webhooks] - | [ProjectPermissionActions, ProjectPermissionSub.AuditLogs] + | [ProjectPermissionAuditLogsActions, ProjectPermissionSub.AuditLogs] | [ProjectPermissionActions, ProjectPermissionSub.Environments] | [ProjectPermissionActions, ProjectPermissionSub.IpAllowList] | [ProjectPermissionActions, ProjectPermissionSub.Settings] @@ -645,7 +649,7 @@ const GeneralPermissionSchema = [ }), z.object({ subject: z.literal(ProjectPermissionSub.AuditLogs).describe("The entity this permission pertains to."), - action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( + action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionAuditLogsActions).describe( "Describe what action an entity can take." ) }), diff --git a/frontend/src/context/OrgPermissionContext/index.tsx b/frontend/src/context/OrgPermissionContext/index.tsx index fccd53935..f3bc0195d 100644 --- a/frontend/src/context/OrgPermissionContext/index.tsx +++ b/frontend/src/context/OrgPermissionContext/index.tsx @@ -2,6 +2,7 @@ export { useOrgPermission } from "./OrgPermissionContext"; export type { TOrgPermission } from "./types"; export { OrgPermissionActions, + OrgPermissionAuditLogsActions, OrgPermissionBillingActions, OrgPermissionGroupActions, OrgPermissionIdentityActions, diff --git a/frontend/src/context/OrgPermissionContext/types.ts b/frontend/src/context/OrgPermissionContext/types.ts index 50e147aa0..74d5293e6 100644 --- a/frontend/src/context/OrgPermissionContext/types.ts +++ b/frontend/src/context/OrgPermissionContext/types.ts @@ -71,6 +71,10 @@ export enum OrgPermissionAppConnectionActions { Connect = "connect" } +export enum OrgPermissionAuditLogsActions { + Read = "read" +} + export enum OrgPermissionKmipActions { Proxy = "proxy", Setup = "setup" @@ -118,7 +122,7 @@ export type OrgPermissionSet = | [OrgPermissionBillingActions, OrgPermissionSubjects.Billing] | [OrgPermissionActions, OrgPermissionSubjects.Kms] | [OrgPermissionAdminConsoleAction, OrgPermissionSubjects.AdminConsole] - | [OrgPermissionActions, OrgPermissionSubjects.AuditLogs] + | [OrgPermissionAuditLogsActions, OrgPermissionSubjects.AuditLogs] | [OrgPermissionActions, OrgPermissionSubjects.ProjectTemplates] | [OrgPermissionAppConnectionActions, OrgPermissionSubjects.AppConnections] | [OrgPermissionIdentityActions, OrgPermissionSubjects.Identity] diff --git a/frontend/src/context/ProjectPermissionContext/index.tsx b/frontend/src/context/ProjectPermissionContext/index.tsx index f564ac74e..a1669e18f 100644 --- a/frontend/src/context/ProjectPermissionContext/index.tsx +++ b/frontend/src/context/ProjectPermissionContext/index.tsx @@ -2,6 +2,7 @@ export { useProjectPermission } from "./ProjectPermissionContext"; export type { ProjectPermissionSet, TProjectPermission } from "./types"; export { ProjectPermissionActions, + ProjectPermissionAuditLogsActions, ProjectPermissionCertificateActions, ProjectPermissionCmekActions, ProjectPermissionDynamicSecretActions, diff --git a/frontend/src/context/ProjectPermissionContext/types.ts b/frontend/src/context/ProjectPermissionContext/types.ts index dad72cada..acfab612f 100644 --- a/frontend/src/context/ProjectPermissionContext/types.ts +++ b/frontend/src/context/ProjectPermissionContext/types.ts @@ -150,6 +150,10 @@ export enum ProjectPermissionSecretEventActions { SubscribeImportMutations = "subscribe-on-import-mutations" } +export enum ProjectPermissionAuditLogsActions { + Read = "read" +} + export enum PermissionConditionOperators { $IN = "$in", $ALL = "$all", @@ -365,7 +369,7 @@ export type ProjectPermissionSet = | [ProjectPermissionActions, ProjectPermissionSub.Groups] | [ProjectPermissionActions, ProjectPermissionSub.Integrations] | [ProjectPermissionActions, ProjectPermissionSub.Webhooks] - | [ProjectPermissionActions, ProjectPermissionSub.AuditLogs] + | [ProjectPermissionAuditLogsActions, ProjectPermissionSub.AuditLogs] | [ProjectPermissionActions, ProjectPermissionSub.Environments] | [ProjectPermissionActions, ProjectPermissionSub.IpAllowList] | [ProjectPermissionActions, ProjectPermissionSub.Settings] diff --git a/frontend/src/context/index.tsx b/frontend/src/context/index.tsx index 833956d77..bfb504664 100644 --- a/frontend/src/context/index.tsx +++ b/frontend/src/context/index.tsx @@ -2,6 +2,7 @@ export { useOrganization } from "./OrganizationContext"; export type { TOrgPermission } from "./OrgPermissionContext"; export { OrgPermissionActions, + OrgPermissionAuditLogsActions, OrgPermissionBillingActions, OrgPermissionGroupActions, OrgPermissionIdentityActions, @@ -11,6 +12,7 @@ export { export type { TProjectPermission } from "./ProjectPermissionContext"; export { ProjectPermissionActions, + ProjectPermissionAuditLogsActions, ProjectPermissionCertificateActions, ProjectPermissionCmekActions, ProjectPermissionDynamicSecretActions, diff --git a/frontend/src/pages/organization/AuditLogsPage/components/LogsSection.tsx b/frontend/src/pages/organization/AuditLogsPage/components/LogsSection.tsx index e938aed7d..5bbb42d32 100644 --- a/frontend/src/pages/organization/AuditLogsPage/components/LogsSection.tsx +++ b/frontend/src/pages/organization/AuditLogsPage/components/LogsSection.tsx @@ -4,9 +4,15 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import ms from "ms"; import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal"; -import { OrgPermissionActions, OrgPermissionSubjects, useSubscription } from "@app/context"; +import { + OrgPermissionAuditLogsActions, + OrgPermissionSubjects, + ProjectPermissionAuditLogsActions, + ProjectPermissionSub, + useSubscription +} from "@app/context"; import { Timezone } from "@app/helpers/datetime"; -import { withPermission } from "@app/hoc"; +import { withPermission, withProjectPermission } from "@app/hoc"; import { Workspace } from "@app/hooks/api/workspace/types"; import { usePopUp } from "@app/hooks/usePopUp"; @@ -28,153 +34,173 @@ type Props = { project?: Workspace; }; -export const LogsSection = withPermission( - ({ presets, refetchInterval, showFilters = true, pageView = false, project }: Props) => { - const { subscription } = useSubscription(); +const LogsSectionComponent = ({ + presets, + refetchInterval, + showFilters = true, + pageView = false, + project +}: Props) => { + const { subscription } = useSubscription(); + const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["upgradePlan"] as const); + const [logFilter, setLogFilter] = useState({ + eventType: presets?.eventType || [], + actor: presets?.actorId, + eventMetadata: presets?.eventMetadata + }); + const [timezone, setTimezone] = useState(Timezone.Local); - const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["upgradePlan"] as const); - const [logFilter, setLogFilter] = useState({ - eventType: presets?.eventType || [], - actor: presets?.actorId, - eventMetadata: presets?.eventMetadata - }); - const [timezone, setTimezone] = useState(Timezone.Local); + const [dateFilter, setDateFilter] = useState( + presets?.endDate || presets?.startDate + ? { + type: AuditLogDateFilterType.Absolute, + startDate: presets?.startDate || new Date(Number(new Date()) - ms("1h")), + endDate: presets?.endDate || new Date() + } + : { + startDate: new Date(Number(new Date()) - ms("1h")), + endDate: new Date(), + type: AuditLogDateFilterType.Relative, + relativeModeValue: "1h" + } + ); - const [dateFilter, setDateFilter] = useState( - presets?.endDate || presets?.startDate - ? { - type: AuditLogDateFilterType.Absolute, - startDate: presets?.startDate || new Date(Number(new Date()) - ms("1h")), - endDate: presets?.endDate || new Date() - } - : { - startDate: new Date(Number(new Date()) - ms("1h")), - endDate: new Date(), - type: AuditLogDateFilterType.Relative, - relativeModeValue: "1h" - } - ); - - useEffect(() => { - if (subscription && !subscription.auditLogs) { - handlePopUpOpen("upgradePlan"); - } - }, [subscription]); - - if (pageView) - return ( -
-
-
-
-

Audit History

- -
- - Docs - -
-
-
-
-
- {showFilters && ( - - )} - {showFilters && ( - - )} -
-
-
- - { - handlePopUpToggle("upgradePlan", isOpen); - }} - text="You can use audit logs if you switch to a paid Infisical plan." - /> -
-
- ); + useEffect(() => { + if (subscription && !subscription.auditLogs) { + handlePopUpOpen("upgradePlan"); + } + }, [subscription]); + if (pageView) return ( -
-
- {showFilters && ( - - )} - {showFilters && ( - - )} +
+
+
+
+

Audit History

+ +
+ + Docs + +
+
+
+
+
+ {showFilters && ( + + )} + {showFilters && ( + + )} +
+
+
+ + { + handlePopUpToggle("upgradePlan", isOpen); + }} + text="You can use audit logs if you switch to a paid Infisical plan." + />
- - { - handlePopUpToggle("upgradePlan", isOpen); - }} - text="You can use audit logs if you switch to a paid Infisical plan." - />
); - }, - { action: OrgPermissionActions.Read, subject: OrgPermissionSubjects.AuditLogs } -); + + return ( +
+
+ {showFilters && ( + + )} + {showFilters && ( + + )} +
+ + { + handlePopUpToggle("upgradePlan", isOpen); + }} + text="You can use audit logs if you switch to a paid Infisical plan." + /> +
+ ); +}; + +export const LogsSection = (props: Props) => { + const { project } = props; + + if (project) { + const ProjectLogsSectionWithPermission = withProjectPermission(LogsSectionComponent, { + action: ProjectPermissionAuditLogsActions.Read, + subject: ProjectPermissionSub.AuditLogs + }); + return ; + } + + const OrgLogsSectionWithPermission = withPermission(LogsSectionComponent, { + action: OrgPermissionAuditLogsActions.Read, + subject: OrgPermissionSubjects.AuditLogs + }); + return ; +}; diff --git a/frontend/src/pages/organization/RoleByIDPage/components/OrgRoleModifySection.utils.ts b/frontend/src/pages/organization/RoleByIDPage/components/OrgRoleModifySection.utils.ts index 275b73fd0..03b86f2ab 100644 --- a/frontend/src/pages/organization/RoleByIDPage/components/OrgRoleModifySection.utils.ts +++ b/frontend/src/pages/organization/RoleByIDPage/components/OrgRoleModifySection.utils.ts @@ -5,6 +5,7 @@ import { OrgPermissionSubjects } from "@app/context"; import { OrgGatewayPermissionActions, OrgPermissionAppConnectionActions, + OrgPermissionAuditLogsActions, OrgPermissionBillingActions, OrgPermissionGroupActions, OrgPermissionIdentityActions, @@ -23,6 +24,12 @@ const generalPermissionSchema = z }) .optional(); +const auditLogsPermissionSchema = z + .object({ + [OrgPermissionAuditLogsActions.Read]: z.boolean().optional() + }) + .optional(); + const billingPermissionSchema = z .object({ [OrgPermissionBillingActions.Read]: z.boolean().optional(), @@ -121,7 +128,7 @@ export const formSchema = z.object({ }) .optional(), - "audit-logs": generalPermissionSchema, + "audit-logs": auditLogsPermissionSchema, member: generalPermissionSchema, groups: groupPermissionSchema, role: generalPermissionSchema, diff --git a/frontend/src/pages/organization/RoleByIDPage/components/RolePermissionsSection/OrgPermissionAuditLogsRow.tsx b/frontend/src/pages/organization/RoleByIDPage/components/RolePermissionsSection/OrgPermissionAuditLogsRow.tsx new file mode 100644 index 000000000..82c4966b9 --- /dev/null +++ b/frontend/src/pages/organization/RoleByIDPage/components/RolePermissionsSection/OrgPermissionAuditLogsRow.tsx @@ -0,0 +1,164 @@ +import { useEffect, useMemo } from "react"; +import { Control, Controller, UseFormSetValue, useWatch } from "react-hook-form"; +import { faChevronDown, faChevronRight } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; + +import { createNotification } from "@app/components/notifications"; +import { Checkbox, Select, SelectItem, Td, Tr } from "@app/components/v2"; +import { OrgPermissionAuditLogsActions } from "@app/context/OrgPermissionContext/types"; +import { useToggle } from "@app/hooks"; + +import { TFormSchema } from "../OrgRoleModifySection.utils"; + +type Props = { + isEditable: boolean; + setValue: UseFormSetValue; + control: Control; +}; + +enum Permission { + NoAccess = "no-access", + ReadOnly = "read-only", + FullAccess = "full-access", + Custom = "custom" +} + +const PERMISSION_ACTIONS = [ + { + action: OrgPermissionAuditLogsActions.Read, + label: "View" + } +] as const; + +export const OrgPermissionAuditLogsRow = ({ isEditable, control, setValue }: Props) => { + const [isRowExpanded, setIsRowExpanded] = useToggle(); + const [isCustom, setIsCustom] = useToggle(); + + const rule = useWatch({ + control, + name: "permissions.audit-logs" + }); + + const selectedPermissionCategory = useMemo(() => { + const actions = Object.keys(rule || {}) as Array; + const totalActions = PERMISSION_ACTIONS.length; + const score = actions.map((key) => (rule?.[key] ? 1 : 0)).reduce((a, b) => a + b, 0 as number); + + if (isCustom) return Permission.Custom; + if (score === 0) return Permission.NoAccess; + if (score === totalActions) return Permission.FullAccess; + if (score === 1 && rule?.[OrgPermissionAuditLogsActions.Read]) return Permission.ReadOnly; + + return Permission.Custom; + }, [rule, isCustom]); + + useEffect(() => { + if (selectedPermissionCategory === Permission.Custom) setIsCustom.on(); + else setIsCustom.off(); + }, [selectedPermissionCategory]); + + useEffect(() => { + const isRowCustom = selectedPermissionCategory === Permission.Custom; + if (isRowCustom) { + setIsRowExpanded.on(); + } + }, []); + + const handlePermissionChange = (val: Permission) => { + if (!val) return; + if (val === Permission.Custom) { + setIsRowExpanded.on(); + setIsCustom.on(); + return; + } + setIsCustom.off(); + + switch (val) { + case Permission.FullAccess: + case Permission.ReadOnly: + // For audit logs, both full access and read-only are the same - just read access + setValue( + "permissions.audit-logs", + { + [OrgPermissionAuditLogsActions.Read]: true + }, + { shouldDirty: true } + ); + break; + + case Permission.NoAccess: + default: + setValue( + "permissions.audit-logs", + { + [OrgPermissionAuditLogsActions.Read]: false + }, + { shouldDirty: true } + ); + } + }; + + return ( + <> + setIsRowExpanded.toggle()} + > + + + + Audit Logs + + + + + {isRowExpanded && ( + + +
+ {PERMISSION_ACTIONS.map(({ action, label }) => { + return ( + ( + { + if (!isEditable) { + createNotification({ + type: "error", + text: "Failed to update default role" + }); + return; + } + field.onChange(e); + }} + id={`permissions.audit-logs.${action}`} + > + {label} + + )} + /> + ); + })} +
+ + + )} + + ); +}; diff --git a/frontend/src/pages/organization/RoleByIDPage/components/RolePermissionsSection/RolePermissionRow.tsx b/frontend/src/pages/organization/RoleByIDPage/components/RolePermissionsSection/RolePermissionRow.tsx index e0702b201..0254e8240 100644 --- a/frontend/src/pages/organization/RoleByIDPage/components/RolePermissionsSection/RolePermissionRow.tsx +++ b/frontend/src/pages/organization/RoleByIDPage/components/RolePermissionsSection/RolePermissionRow.tsx @@ -71,6 +71,7 @@ type Props = { | "gateway" | "secret-share" | "billing" + | "audit-logs" | "machine-identity-auth-template" >; setValue: UseFormSetValue; diff --git a/frontend/src/pages/organization/RoleByIDPage/components/RolePermissionsSection/RolePermissionsSection.tsx b/frontend/src/pages/organization/RoleByIDPage/components/RolePermissionsSection/RolePermissionsSection.tsx index 6fd848f56..3b606cbb1 100644 --- a/frontend/src/pages/organization/RoleByIDPage/components/RolePermissionsSection/RolePermissionsSection.tsx +++ b/frontend/src/pages/organization/RoleByIDPage/components/RolePermissionsSection/RolePermissionsSection.tsx @@ -16,6 +16,7 @@ import { TFormSchema } from "../OrgRoleModifySection.utils"; import { OrgPermissionAdminConsoleRow } from "./OrgPermissionAdminConsoleRow"; +import { OrgPermissionAuditLogsRow } from "./OrgPermissionAuditLogsRow"; import { OrgPermissionBillingRow } from "./OrgPermissionBillingRow"; import { OrgGatewayPermissionRow } from "./OrgPermissionGatewayRow"; import { OrgPermissionGroupRow } from "./OrgPermissionGroupRow"; @@ -39,10 +40,6 @@ const SIMPLE_PERMISSION_OPTIONS = [ title: "Incident Contacts", formName: "incident-contact" }, - { - title: "Audit Logs", - formName: "audit-logs" - }, { title: "Organization Profile", formName: "settings" @@ -166,6 +163,11 @@ export const RolePermissionsSection = ({ roleId }: Props) => { /> ); })} + { const { subscription } = useSubscription(); + const { currentWorkspace } = useWorkspace(); const auditLogsRetentionDays = subscription?.auditLogsRetentionDays ?? 30; @@ -30,6 +31,7 @@ export const IntegrationAuditLogsSection = ({ integration }: Props) => { { const { subscription } = useSubscription(); + const { currentWorkspace } = useWorkspace(); const auditLogsRetentionDays = subscription?.auditLogsRetentionDays ?? 30; @@ -36,6 +37,7 @@ export const SecretSyncAuditLogsSection = ({ secretSync }: Props) => {