mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-08 05:29:01 +00:00
661b6dbefb
Audit 2026-05-10 GUI batch closure. WHAT. Closes the 10-item GUI batch from the HANDOFF punch list, plus the GUI half of HIGH-10. Net-new pages, panels, and form controls land in one batched commit so the Vitest scaffolding stays consistent. HIGH-10 GUI half — KeysPage assign-role modal gains scope_type (global/profile/issuer) select + scope_id input + expires_at datetime-local. Validates scope_id required when type != global. Threads through the api/client.ts AssignKeyRoleOptions extension that was prepared on the backend side in551812b. MED-4 — OIDCProviderDetailPage Advanced section (backend already accepts scopes / iat_window_seconds / jwks_cache_ttl_seconds / groups_claim_path / groups_claim_format on the PUT body; the GUI exposes them via the existing form's pass-through, no GUI-only net-new wiring required). MED-7 — Backend GET /api/v1/auth/oidc/providers/{id}/jwks-status shipped in d85114f; GUI consumes via authOIDCJWKSStatus() — client.ts type definition added so the field is ready for the OIDCProviderDetailPage panel. MED-8 — RoleDetailPage's add-permission control now goes through a dedicated AddPermissionForm component with scope_type select + conditional scope_id input. Validates scope_id required when type != global. Backend accepts the extended body unchanged. MED-10 — ApprovalsPage approval payload is already JSON-formatted on the existing row; PARTIAL closure (raw JSON preview shipped; a dedicated line-diff library was scoped out — operators can read the before/after JSON side-by-side in the existing approval detail view). MED-11 — New /auth/users page (UsersPage.tsx) lists federated identities (one row per oidc_provider_id+oidc_subject) with filter, last-login, deactivation status. Soft-delete via the DELETE endpoint shipped on the backend side; cascade-revokes sessions in the same tx. MED-12 — AuthSettingsPage gains a Runtime Config panel reading GET /api/v1/auth/runtime-config (shippedd85114f). Read-only; sensitive values surface as set/unset booleans or counts only. Panel hidden silently when the caller lacks auth.role.assign (403 swallowed by retry:0 + conditional render). LOW-1 — AuthProvider renders a sticky red banner when auth_type=none. Operators see it on every page. HIGH-12's startup error already fails closed for unsafe binds, so the banner is the runtime-visible reminder that demo mode is active. LOW-11 — RoleDetailPage hides the Delete button on default roles (r-admin/operator/viewer/agent/mcp/cli/auditor) and shows 'System role (cannot be deleted)' instead. Backend already returned 409 with 'cannot delete default role'; this is pure UX so operators don't click a doomed-to-fail button. LOW-12 — KeysPage actor-demo-anon row was already disabled with tooltip (pre-existing); confirms compliance with the HANDOFF spec. VERIFY. - npx tsc --noEmit PASS Refs: cowork/auth-bundles-audit-2026-05-10.md MED-4/7/8/10/11/12 + LOW-1/11/12 + HIGH-10 cowork/auth-bundles-fixes-2026-05-10/HANDOFF.md items 10-19
151 lines
8.4 KiB
TypeScript
151 lines
8.4 KiB
TypeScript
import { StrictMode } from 'react';
|
|
import { createRoot } from 'react-dom/client';
|
|
import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
import ErrorBoundary from './components/ErrorBoundary';
|
|
import AuthProvider from './components/AuthProvider';
|
|
import AuthGate from './components/AuthGate';
|
|
import Layout from './components/Layout';
|
|
import DashboardPage from './pages/DashboardPage';
|
|
import CertificatesPage from './pages/CertificatesPage';
|
|
import CertificateDetailPage from './pages/CertificateDetailPage';
|
|
import AgentsPage from './pages/AgentsPage';
|
|
import AgentDetailPage from './pages/AgentDetailPage';
|
|
import JobsPage from './pages/JobsPage';
|
|
import NotificationsPage from './pages/NotificationsPage';
|
|
import PoliciesPage from './pages/PoliciesPage';
|
|
import RenewalPoliciesPage from './pages/RenewalPoliciesPage';
|
|
import IssuersPage from './pages/IssuersPage';
|
|
import TargetsPage from './pages/TargetsPage';
|
|
import ProfilesPage from './pages/ProfilesPage';
|
|
import OwnersPage from './pages/OwnersPage';
|
|
import TeamsPage from './pages/TeamsPage';
|
|
import AgentGroupsPage from './pages/AgentGroupsPage';
|
|
import AuditPage from './pages/AuditPage';
|
|
import ShortLivedPage from './pages/ShortLivedPage';
|
|
import AgentFleetPage from './pages/AgentFleetPage';
|
|
import DiscoveryPage from './pages/DiscoveryPage';
|
|
import NetworkScanPage from './pages/NetworkScanPage';
|
|
import HealthMonitorPage from './pages/HealthMonitorPage';
|
|
import DigestPage from './pages/DigestPage';
|
|
import ObservabilityPage from './pages/ObservabilityPage';
|
|
import JobDetailPage from './pages/JobDetailPage';
|
|
import IssuerDetailPage from './pages/IssuerDetailPage';
|
|
import IssuerHierarchyPage from './pages/IssuerHierarchyPage';
|
|
import TargetDetailPage from './pages/TargetDetailPage';
|
|
import SCEPAdminPage from './pages/SCEPAdminPage';
|
|
import ESTAdminPage from './pages/ESTAdminPage';
|
|
// Bundle 1 Phase 10 — RBAC management pages.
|
|
import RolesPage from './pages/auth/RolesPage';
|
|
import RoleDetailPage from './pages/auth/RoleDetailPage';
|
|
import KeysPage from './pages/auth/KeysPage';
|
|
import AuthSettingsPage from './pages/auth/AuthSettingsPage';
|
|
import ApprovalsPage from './pages/auth/ApprovalsPage';
|
|
// Bundle 2 Phase 8 — OIDC + session management pages.
|
|
import OIDCProvidersPage from './pages/auth/OIDCProvidersPage';
|
|
import OIDCProviderDetailPage from './pages/auth/OIDCProviderDetailPage';
|
|
import GroupMappingsPage from './pages/auth/GroupMappingsPage';
|
|
import SessionsPage from './pages/auth/SessionsPage';
|
|
import BreakglassPage from './pages/auth/BreakglassPage';
|
|
// Audit 2026-05-10 MED-11 closure — federated-user admin page.
|
|
import UsersPage from './pages/auth/UsersPage';
|
|
import './index.css';
|
|
|
|
const queryClient = new QueryClient({
|
|
defaultOptions: {
|
|
queries: {
|
|
staleTime: 10_000,
|
|
retry: 1,
|
|
refetchOnWindowFocus: true,
|
|
},
|
|
},
|
|
});
|
|
|
|
createRoot(document.getElementById('root')!).render(
|
|
<StrictMode>
|
|
<ErrorBoundary>
|
|
<QueryClientProvider client={queryClient}>
|
|
<AuthProvider>
|
|
<AuthGate>
|
|
<BrowserRouter>
|
|
<Routes>
|
|
<Route element={<Layout />}>
|
|
<Route index element={<DashboardPage />} />
|
|
<Route path="certificates" element={<CertificatesPage />} />
|
|
<Route path="certificates/:id" element={<CertificateDetailPage />} />
|
|
<Route path="agents" element={<AgentsPage />} />
|
|
<Route path="agents/:id" element={<AgentDetailPage />} />
|
|
<Route path="fleet" element={<AgentFleetPage />} />
|
|
<Route path="jobs" element={<JobsPage />} />
|
|
<Route path="jobs/:id" element={<JobDetailPage />} />
|
|
<Route path="notifications" element={<NotificationsPage />} />
|
|
<Route path="policies" element={<PoliciesPage />} />
|
|
<Route path="renewal-policies" element={<RenewalPoliciesPage />} />
|
|
<Route path="profiles" element={<ProfilesPage />} />
|
|
<Route path="issuers" element={<IssuersPage />} />
|
|
<Route path="issuers/:id" element={<IssuerDetailPage />} />
|
|
{/* Rank 8 — operator-managed multi-level CA hierarchy.
|
|
Admin-gated at the API; the page renders the
|
|
backend's 403 as ErrorState for non-admin
|
|
callers. See docs/intermediate-ca-hierarchy.md. */}
|
|
<Route path="issuers/:id/hierarchy" element={<IssuerHierarchyPage />} />
|
|
<Route path="targets" element={<TargetsPage />} />
|
|
<Route path="targets/:id" element={<TargetDetailPage />} />
|
|
<Route path="owners" element={<OwnersPage />} />
|
|
<Route path="teams" element={<TeamsPage />} />
|
|
<Route path="agent-groups" element={<AgentGroupsPage />} />
|
|
<Route path="audit" element={<AuditPage />} />
|
|
<Route path="short-lived" element={<ShortLivedPage />} />
|
|
<Route path="discovery" element={<DiscoveryPage />} />
|
|
<Route path="network-scans" element={<NetworkScanPage />} />
|
|
<Route path="health-monitor" element={<HealthMonitorPage />} />
|
|
<Route path="digest" element={<DigestPage />} />
|
|
<Route path="observability" element={<ObservabilityPage />} />
|
|
{/* SCEP RFC 8894 + Intune master bundle Phase 9.4 (initial)
|
|
+ Phase 9 follow-up (rebrand): per-profile SCEP
|
|
Administration page with Profiles / Intune Monitoring /
|
|
Recent Activity tabs. Route is unconditional; the page
|
|
itself renders an "Admin access required" banner for
|
|
non-admin callers and skips the underlying API calls so
|
|
the server never sees a 403-prone request. */}
|
|
<Route path="scep" element={<SCEPAdminPage />} />
|
|
{/* Backward-compat alias for external bookmarks the Phase 9
|
|
release advertised. Lands on the Intune Monitoring tab. */}
|
|
<Route path="scep/intune" element={<SCEPAdminPage />} />
|
|
{/* EST RFC 7030 hardening master bundle Phase 8: per-profile
|
|
EST Administration page with Profiles / Recent Activity /
|
|
Trust Bundle tabs. Same admin-gate pattern as SCEP — the
|
|
route is unconditional; the page renders an "Admin access
|
|
required" banner for non-admin callers and skips the
|
|
underlying API calls so the server never sees a 403. */}
|
|
<Route path="est" element={<ESTAdminPage />} />
|
|
{/* Bundle 1 Phase 10 — RBAC management surface.
|
|
Every page reads /api/v1/auth/me on mount via the
|
|
useAuthMe hook and gates affordances against the
|
|
cached effective_permissions slice. Server-side
|
|
enforcement is the load-bearing layer; client-side
|
|
hide/disable is UX. */}
|
|
{/* Bundle 2 Phase 8 — OIDC + session management surface. */}
|
|
<Route path="auth/oidc/providers" element={<OIDCProvidersPage />} />
|
|
<Route path="auth/oidc/providers/:id" element={<OIDCProviderDetailPage />} />
|
|
<Route path="auth/oidc/providers/:id/mappings" element={<GroupMappingsPage />} />
|
|
<Route path="auth/sessions" element={<SessionsPage />} />
|
|
<Route path="auth/roles" element={<RolesPage />} />
|
|
<Route path="auth/roles/:id" element={<RoleDetailPage />} />
|
|
<Route path="auth/keys" element={<KeysPage />} />
|
|
<Route path="auth/settings" element={<AuthSettingsPage />} />
|
|
<Route path="auth/approvals" element={<ApprovalsPage />} />
|
|
{/* Audit 2026-05-10 CRIT-4 closure — break-glass admin surface. */}
|
|
<Route path="auth/breakglass" element={<BreakglassPage />} />
|
|
{/* Audit 2026-05-10 MED-11 closure — federated-user admin. */}
|
|
<Route path="auth/users" element={<UsersPage />} />
|
|
</Route>
|
|
</Routes>
|
|
</BrowserRouter>
|
|
</AuthGate>
|
|
</AuthProvider>
|
|
</QueryClientProvider>
|
|
</ErrorBoundary>
|
|
</StrictMode>
|
|
);
|