notifications (5/5): notifications UI#456
Conversation
🔐 Codex Security Review
Review SummaryOverall Risk: MEDIUM Findings[MEDIUM] Dashboard Active Notifications Can Be Stale Or Incomplete
NotesThe scoped diff is client-only; I did not see backend, migration, plugin, infrastructure, or protobuf source changes in Generated by Codex Security Review | |
2ace81c to
d7bef30
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2ace81cb65
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| <Button | ||
| variant={variants.secondary} | ||
| size={sizes.compact} | ||
| text="Add channel" | ||
| onClick={() => setShowAddModal(true)} |
There was a problem hiding this comment.
Gate notification mutations on manage permission
For users who have notification:read but not notification:manage, the Notifications settings entry is visible, but this button and the row edit/test/delete actions still call RPCs that server/internal/handlers/middleware/rpc_permissions.go maps to notification:manage. Those read-only users will see mutation controls that only produce permission-denied errors, so the mutation buttons/actions should be hidden or disabled behind useHasPermission("notification:manage").
Useful? React with 👍 / 👎.
| group_id: null, | ||
| site_id: null, | ||
| device_ids: [], |
There was a problem hiding this comment.
Preserve non-rule silence targets when editing
When the backend returns an existing group/site/device-scoped silence, the edit modal initializes scope to that kind, but saving always sends group_id, site_id, and device_ids as empty. The server's validateSilenceScope requires those targets for non-rule scopes, so any edit to such a silence fails with an invalid-argument error instead of preserving the current target; either preserve the existing scope fields or hide editing for unsupported scope kinds.
Useful? React with 👍 / 👎.
| <HistoryTable | ||
| activeOnly | ||
| noDataElement={<div className="py-6 text-center text-text-primary-50">No active notifications.</div>} |
There was a problem hiding this comment.
Don't derive active alerts from one history page
The dashboard card labels this as active notifications, but activeOnly uses refreshHistory(), which fetches only the first 50 history rows, and then hides pagination. In fleets with more than 50 newer notification events, a still-firing alert whose latest firing row is older than that first page will disappear from the active card and can incorrectly show “No active notifications”; the active view needs a complete/current active-alert source or must keep paging until it can safely determine active state.
Useful? React with 👍 / 👎.
6cdd7d2 to
6655a15
Compare
…ation:manage
Two client-side hardening fixes from review:
- Channel destination secrets (webhook bearer header, Slack webhook URL, SMTP
password) used the default text input, leaving capability secrets shoulder-
surfable. Switch them to type=password (Input already ships a show/hide toggle).
- The Rules/Channels/Silences sections rendered create/edit/test/delete/pause/
resume/silence controls to any notification:read user, though the server gates
every mutation on notification:manage. Gate the add buttons, row actions, and
inline-editable channel cells on useHasPermission("notification:manage") so
read-only users see the lists without unusable controls.
Addresses Codex security review findings (MEDIUM) on #456.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
d7bef30 to
76179b2
Compare
|
Codex findings on this PR:
|
6655a15 to
753a5b8
Compare
…ation:manage
Two client-side hardening fixes from review:
- Channel destination secrets (webhook bearer header, Slack webhook URL, SMTP
password) used the default text input, leaving capability secrets shoulder-
surfable. Switch them to type=password (Input already ships a show/hide toggle).
- The Rules/Channels/Silences sections rendered create/edit/test/delete/pause/
resume/silence controls to any notification:read user, though the server gates
every mutation on notification:manage. Gate the add buttons, row actions, and
inline-editable channel cells on useHasPermission("notification:manage") so
read-only users see the lists without unusable controls.
Addresses Codex security review findings (MEDIUM) on #456.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
76179b2 to
c069f13
Compare
Adds the notifications feature (channels, rules, silences, history) with its API hooks, Zustand store, modals, and tables, plus the dashboard active- notifications card. Wires the page into the router, nav, route prefetch, and permission catalog, gated on notification:read. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ation:manage
Two client-side hardening fixes from review:
- Channel destination secrets (webhook bearer header, Slack webhook URL, SMTP
password) used the default text input, leaving capability secrets shoulder-
surfable. Switch them to type=password (Input already ships a show/hide toggle).
- The Rules/Channels/Silences sections rendered create/edit/test/delete/pause/
resume/silence controls to any notification:read user, though the server gates
every mutation on notification:manage. Gate the add buttons, row actions, and
inline-editable channel cells on useHasPermission("notification:manage") so
read-only users see the lists without unusable controls.
Addresses Codex security review findings (MEDIUM) on #456.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
c069f13 to
466fdd6
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 466fdd686a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| useEffect(() => { | ||
| void refresh().catch((error) => { |
There was a problem hiding this comment.
Gate the page before issuing read RPCs
When a user opens /settings/notifications directly without notification:read, the nav item is hidden but the route itself is not guarded, so this effect still calls the notification read RPCs (and HistoryTable does the same) and the server returns permission-denied toasts/empty sections. Match the other permission-gated settings pages by checking useHasPermission("notification:read") and redirecting or avoiding the fetch before mounting the sections.
Useful? React with 👍 / 👎.
Stack 5/5 — base: `eden/notifications-4-server`
Adds the notifications UI.
Stack
🤖 Generated with Claude Code