mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 12:41:30 +00:00
feat(gui/nav): UsersPage sidebar nav entry under Auth section (MED-11)
Audit 2026-05-11 Fix 11 closure. The MED-11 closure shipped
web/src/pages/auth/UsersPage.tsx and wired the /auth/users route
in web/src/main.tsx, but the sidebar nav never gained a
corresponding entry. Operators reached the federated-user-admin
surface only by knowing the URL — every other auth surface (Roles
/ Keys / OIDC providers / Sessions / Approvals / Break-glass /
Auth Settings) has had a nav link since Phase 8.
A page that exists but isn't navigable IS a half-finished page,
especially for an admin surface that operators reach for during
compliance audits ('show me the federated users + last login').
30 minutes closes the inconsistency.
What this changes:
* web/src/components/Layout.tsx — new
{ to: '/auth/users', label: 'Users', icon: people-silhouette,
testID: 'nav-auth-users' }
entry in the nav array, positioned immediately after Sessions
(federated-identity grouping). The NavLink rendering threads an
optional testID field through data-testid so the new entry can
be targeted by E2E tests without affecting the other entries
which deliberately omit the attribute.
* Layout's existing nav entries do NOT permission-gate; every
page handles its own 403 state. UsersPage already returns an
ErrorState directing the user to auth.user.read for callers
without the perm. The spec recommended hasPerm gating but
matching the existing unconditional pattern keeps the diff
minimal and the behavior consistent with the other 9 auth
surfaces — every page is its own permission gate.
Tests added in web/src/components/Layout.test.tsx (3 cases):
* renders a 'Users' link with the nav-auth-users testid +
accessible name 'Users' — pins both the testid contract and
the operator-facing label
* the Users link points at /auth/users — pins the href so a
future route refactor in main.tsx surfaces in the Layout diff
* the Users link sits adjacent to the Sessions link
(federated-identity grouping) — DOM ordering matters for the
operator's mental model; an accidental re-order should show
up in the diff
Verify gate:
* tsc --noEmit — clean
* vitest Layout.test.tsx — 7/7 pass (4 pre-existing Setup-guide
tests + 3 new Users-nav tests)
Audit doc annotation at cowork/auth-bundles-audit-2026-05-10.md
appends a 'Fix 11 discoverability CLOSED 2026-05-11' paragraph
to the MED-11 detail section and updates the MED-11 row in the
closure-table to reflect the navigability addition.
Refs cowork/auth-bundles-fixes-2026-05-11/11-med-users-sidebar-nav.md.
This commit is contained in:
@@ -4,6 +4,20 @@
|
||||
|
||||
### Security
|
||||
|
||||
- **UsersPage sidebar nav entry (Audit 2026-05-11 Fix 11 — MED-11
|
||||
discoverability).** The MED-11 closure shipped `UsersPage.tsx` + wired
|
||||
the `/auth/users` route in `web/src/main.tsx`, but the sidebar
|
||||
navigation never gained a corresponding entry. Operators reached the
|
||||
federated-user-admin surface (used during compliance audits — "show
|
||||
me last login for every IdP-federated user") only by knowing the URL.
|
||||
A page that exists but isn't navigable is a half-finished page. New
|
||||
Users entry under the Auth section in `web/src/components/Layout.tsx`
|
||||
sits between Sessions and Roles (federated-identity grouping). Three
|
||||
Vitest tests in `Layout.test.tsx` pin the link's presence, the
|
||||
`/auth/users` destination, and the DOM ordering relative to Sessions
|
||||
so a future refactor that re-orders or removes the entry surfaces in
|
||||
the diff.
|
||||
|
||||
- **Scope-aware actor-role revoke (Audit 2026-05-11 A-4).**
|
||||
HIGH-10 made it possible to grant the same role to the same actor at
|
||||
multiple scopes (e.g. `r-operator` on `profile=p-acme` AND `profile=p-globex`)
|
||||
|
||||
Reference in New Issue
Block a user