fix(site): ensure notification settings page follows RBAC correctly (#19097)

Ensure template admin and user admins are able to see the correct
notification groups on the notification settings page.

---------

Co-authored-by: ケイラ <mckayla@hey.com>
This commit is contained in:
Danielle Maywood
2025-07-31 21:20:27 +01:00
committed by GitHub
co-authored by ケイラ
parent 8b43503aaf
commit a185d3a2c3
3 changed files with 62 additions and 11 deletions
@@ -40,7 +40,7 @@ const meta = {
},
],
user: MockUserOwner,
permissions: { viewDeploymentConfig: true },
permissions: { createTemplates: true, createUser: true },
},
decorators: [withGlobalSnackbar, withAuthProvider, withDashboardProvider],
} satisfies Meta<typeof NotificationsPage>;
@@ -74,7 +74,19 @@ export const ToggleNotification: Story = {
export const NonAdmin: Story = {
parameters: {
permissions: { viewDeploymentConfig: false },
permissions: { createTemplates: false, createUser: false },
},
};
export const TemplateAdmin: Story = {
parameters: {
permissions: { createTemplates: true, createUser: false },
},
};
export const UserAdmin: Story = {
parameters: {
permissions: { createTemplates: false, createUser: true },
},
};
@@ -28,6 +28,7 @@ import {
methodIcons,
methodLabels,
} from "modules/notifications/utils";
import type { Permissions } from "modules/permissions";
import { type FC, Fragment } from "react";
import { useEffect } from "react";
import { Helmet } from "react-helmet-async";
@@ -46,15 +47,7 @@ const NotificationsPage: FC = () => {
},
{
...systemNotificationTemplates(),
select: (data: NotificationTemplate[]) => {
const groups = selectTemplatesByGroup(data);
return permissions.viewDeploymentConfig
? groups
: {
// Members only have access to the "Workspace Notifications" group
"Workspace Events": groups["Workspace Events"],
};
},
select: (data: NotificationTemplate[]) => selectTemplatesByGroup(data),
},
notificationDispatchMethods(),
],
@@ -103,6 +96,10 @@ const NotificationsPage: FC = () => {
{ready ? (
<Stack spacing={4}>
{Object.entries(templatesByGroup.data).map(([group, templates]) => {
if (!canSeeNotificationGroup(group, permissions)) {
return null;
}
const allDisabled = templates.some((tpl) => {
return notificationIsDisabled(disabledPreferences.data, tpl);
});
@@ -211,6 +208,22 @@ const NotificationsPage: FC = () => {
export default NotificationsPage;
function canSeeNotificationGroup(
group: string,
permissions: Permissions,
): boolean {
switch (group) {
case "Workspace Events":
return true;
case "Template Events":
return permissions.createTemplates;
case "User Events":
return permissions.createUser;
default:
return false;
}
}
function notificationIsDisabled(
disabledPreferences: Record<string, boolean>,
tmpl: NotificationTemplate,
+26
View File
@@ -4404,6 +4404,32 @@ export const MockNotificationTemplates: TypesGen.NotificationTemplate[] = [
kind: "system",
enabled_by_default: true,
},
{
id: "template-event-1",
name: "Template Version Created",
title_template: 'Template version "{{.Labels.version_name}}" created',
body_template:
'Hi {{.UserName}}\nA new version of template "{{.Labels.template_name}}" has been created.',
actions:
'[{"url": "{{ base_url }}/templates/{{.Labels.template_name}}", "label": "View template"}]',
group: "Template Events",
method: "smtp",
kind: "system",
enabled_by_default: true,
},
{
id: "template-event-2",
name: "Template Updated",
title_template: 'Template "{{.Labels.template_name}}" updated',
body_template:
'Hi {{.UserName}}\nTemplate "{{.Labels.template_name}}" has been updated.',
actions:
'[{"url": "{{ base_url }}/templates/{{.Labels.template_name}}", "label": "View template"}]',
group: "Template Events",
method: "webhook",
kind: "system",
enabled_by_default: true,
},
];
export const MockNotificationMethodsResponse: TypesGen.NotificationMethodsResponse =