From baba9e6ede03ebd340e233740572515e7c8509cf Mon Sep 17 00:00:00 2001 From: Jake Howell Date: Mon, 6 Apr 2026 22:32:51 +1000 Subject: [PATCH] feat: disallow auditors from editing `` settings (#22382) Auditors are still able to access and read this page but they won't be aren't able to update any of the content, we should show that to them. Should also be noted that this page isn't shown to the user in the sidebar when they are an Auditor. --- .../NotificationsPage/NotificationEvents.tsx | 10 ++++++++++ .../NotificationsPage/NotificationsPage.tsx | 6 +++++- .../NotificationsPage/Troubleshooting.tsx | 10 ++++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationEvents.tsx b/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationEvents.tsx index 3342483f5b..4fcb956a36 100644 --- a/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationEvents.tsx +++ b/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationEvents.tsx @@ -36,6 +36,7 @@ type NotificationEventsProps = { availableMethods: NotificationMethod[]; templatesByGroup: ReturnType; deploymentConfig: DeploymentValues; + canEdit?: boolean; }; export const NotificationEvents: FC = ({ @@ -43,6 +44,7 @@ export const NotificationEvents: FC = ({ availableMethods, templatesByGroup, deploymentConfig, + canEdit = true, }) => { // Webhook const hasWebhookNotifications = Object.values(templatesByGroup) @@ -128,6 +130,7 @@ export const NotificationEvents: FC = ({ templateId={tpl.id} options={availableMethods} value={value} + canEdit={canEdit} /> {!isLastItem && } @@ -152,12 +155,14 @@ type MethodToggleGroupProps = { templateId: string; options: NotificationMethod[]; value: NotificationMethod; + canEdit: boolean; }; const MethodToggleGroup: FC = ({ value, options, templateId, + canEdit, }) => { const queryClient = useQueryClient(); const updateMethodMutation = useMutation( @@ -169,9 +174,13 @@ const MethodToggleGroup: FC = ({ exclusive value={value} size="small" + disabled={!canEdit} aria-label="Notification method" css={styles.toggleGroup} onChange={async (_, method) => { + if (!method) { + return; + } try { await updateMethodMutation.mutateAsync({ method, @@ -196,6 +205,7 @@ const MethodToggleGroup: FC = ({ { // Retain the value if the user clicks the same button, ensuring // at least one value remains selected. diff --git a/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationsPage.tsx b/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationsPage.tsx index 38133891cd..66526b1387 100644 --- a/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationsPage.tsx +++ b/site/src/pages/DeploymentSettingsPage/NotificationsPage/NotificationsPage.tsx @@ -19,6 +19,7 @@ import { TabsList, TabsTrigger, } from "#/components/Tabs/Tabs"; +import { useAuthenticated } from "#/hooks/useAuthenticated"; import { useSearchParamsKey } from "#/hooks/useSearchParamsKey"; import { useDeploymentConfig } from "#/modules/management/DeploymentConfigProvider"; import { castNotificationMethod } from "#/modules/notifications/utils"; @@ -38,7 +39,9 @@ function isNotificationTab( } const NotificationsPage: FC = () => { + const { permissions } = useAuthenticated(); const { deploymentConfig } = useDeploymentConfig(); + const canEditDeploymentConfig = permissions.editDeploymentConfig; const [systemTemplatesByGroup, customTemplatesByGroup, dispatchMethods] = useQueries({ queries: [ @@ -102,6 +105,7 @@ const NotificationsPage: FC = () => { { /> - + )} diff --git a/site/src/pages/DeploymentSettingsPage/NotificationsPage/Troubleshooting.tsx b/site/src/pages/DeploymentSettingsPage/NotificationsPage/Troubleshooting.tsx index 8a9e76069d..a388e62b11 100644 --- a/site/src/pages/DeploymentSettingsPage/NotificationsPage/Troubleshooting.tsx +++ b/site/src/pages/DeploymentSettingsPage/NotificationsPage/Troubleshooting.tsx @@ -7,7 +7,13 @@ import { getErrorDetail } from "#/api/errors"; import { Button } from "#/components/Button/Button"; import { Spinner } from "#/components/Spinner/Spinner"; -export const Troubleshooting: FC = () => { +type TroubleshootingProps = { + canEdit?: boolean; +}; + +export const Troubleshooting: FC = ({ + canEdit = true, +}) => { const { mutate: sendTestNotificationApi, isPending } = useMutation({ mutationFn: API.postTestNotification, onSuccess: () => toast.success("Test notification sent."), @@ -35,7 +41,7 @@ export const Troubleshooting: FC = () => {