Commit Graph

4 Commits

Author SHA1 Message Date
shankar0123 70ebef5d3a test(client): mock headers.get() so 401 tests survive HIGH-8 WWW-Authenticate read
Audit 2026-05-10 HIGH-8 closure landed a parseWWWAuthenticateCause()
call in api/client.ts (line 144) that reads res.headers.get(...) on the
401 path. The two test files in web/src/api/ both provide a Response
mock with no headers property, so every 401 test threw 'Cannot read
properties of undefined (reading get)' instead of the expected
'Authentication required'.

13 tests fail without this fix: 12 in client.error.test.ts (one per
401-mapped endpoint helper) + 1 in client.test.ts (the auth-required
event-dispatch test).

Fix: add headers: { get: () => null } to both mockErrorResponse helpers.
The null return short-circuits parseWWWAuthenticateCause to the default
'Authentication required' message, so every existing 401 assertion
keeps passing.
2026-05-11 14:37:36 +00:00
shankar0123 a00b20cc97 test(web): drop unused mock helpers in client.error.test.ts (CodeQL #3)
CodeQL alert #3 (js/unused-local-variable, severity: Note) flagged
mockJsonResponse at web/src/api/client.error.test.ts:39 as dead.

Audit: client.error.test.ts is the error-path companion to
client.test.ts. Every test in this file drives a non-2xx response
through the client function under test via mockErrorResponse (52
call sites). Both mockJsonResponse AND mockBlobResponse were drafted
alongside the scaffolding but never used — the success-path coverage
lives in client.test.ts, not this file.

CodeQL only flagged mockJsonResponse, but mockBlobResponse is the
same shape (defined, never called). Cleaning both up for
consistency with the file's error-only scope.

Replaced with a one-paragraph comment explaining the file's scope
so future contributors don't re-add the helpers expecting them to
be used.

Verified locally:
  tsc --noEmit: exit 0.
  grep -c mockJsonResponse + mockBlobResponse:
    1 each (the comment mention only).
  No behavioral change.

Reference: https://github.com/certctl-io/certctl/security/code-scanning/3
Closes CodeQL alert #3 (js/unused-local-variable).
2026-05-04 05:13:03 +00:00
shankar0123 097995e503 fix(web,ci): close orphan-CRUD GUI gaps + dead exportCertificatePEM (B-1 master)
Closes four 2026-04-24 audit findings via per-page Edit modals on five
existing pages, a brand-new RenewalPoliciesPage for the rp-* CRUD surface,
and removal of one dead duplicate so the public client surface stops
growing without consumers. Anchored by a CI grep guardrail that fails
the build if any of the eight previously-orphan client functions loses
its non-test page consumer or if exportCertificatePEM is resurrected.

Per-page Edit modals (mirroring existing CreateXModal scaffolding):
- web/src/pages/OwnersPage.tsx — EditOwnerModal (name/email/team_id)
- web/src/pages/TeamsPage.tsx — EditTeamModal (name/description)
- web/src/pages/AgentGroupsPage.tsx — EditAgentGroupModal (full match-rule
  set: name/description/match_os/match_architecture/match_ip_cidr/
  match_version/enabled)
- web/src/pages/IssuersPage.tsx — EditIssuerModal (rename-only; type
  locked, config blob preserved untouched, footer note about delete+
  recreate for credential rotation)
- web/src/pages/ProfilesPage.tsx — EditProfileModal (rename + description
  only; policy fields preserved untouched, footer note about deferred
  policy editing)

New page (closes cat-b-4631ca092bee — RenewalPolicy CRUD orphan):
- web/src/pages/RenewalPoliciesPage.tsx — full CRUD page with shared
  PolicyFormModal for Create + Edit (form shape identical), 7-column
  DataTable (Policy/RenewalWindow/Auto/Retries/AlertThresholds/Created/
  Actions), comma-separated alert_thresholds_days input parser, and
  alert() surfacing of repository.ErrRenewalPolicyInUse (409) on Delete
  so operators can re-target dependent certs before deletion.
- web/src/main.tsx — adds /renewal-policies route.
- web/src/components/Layout.tsx — adds sidebar nav item slotted between
  Policies and Profiles.

Removed (closes cat-b-9b97ffb35ef7 — dead duplicate):
- web/src/api/client.ts::exportCertificatePEM — zero consumers across
  web/, MCP, CLI, tests; downloadCertificatePEM is the actual call site
  in CertificateDetailPage. Test references in client.test.ts and
  client.error.test.ts also removed.

CI regression guardrail:
- .github/workflows/ci.yml — adds 'Forbidden orphan-CRUD client function
  regression guard (B-1)' step. Greps for all eight previously-orphan
  fns (updateOwner/updateTeam/updateAgentGroup/updateIssuer/updateProfile
  + createRenewalPolicy/updateRenewalPolicy/deleteRenewalPolicy) under
  web/src/pages/ and fails the build if any has zero non-test consumers.
  Also blocks resurrection of exportCertificatePEM. Verified locally
  (all 8 fns have ≥2 consumers; exportCertificatePEM is gone) and
  against synthetic regressions.

Documentation:
- CHANGELOG.md — new B-1 section above L-1 under [unreleased].
- docs/architecture.md — Web Dashboard section gains a new paragraph
  capturing the 'every backend CRUD must have a GUI consumer' rule
  with reference to the CI guardrail.
- coverage-gap-audit-2026-04-24-v5/unified-audit.md — flips four
  findings to  RESOLVED with detailed Status blocks; bumps Live
  Tracker score 16/47 → 20/47 (P1: 9→12, P3: 1→2); adds B-1 row to
  closed-bundle index.

Verification:
- cd web && tsc --noEmit — clean
- cd web && vitest run — 9 test files, 294 tests, all passing
- cd web && vite build — clean (no new warnings)
- B-1 guardrail dry-run — all 8 client fns have ≥2 page consumers,
  exportCertificatePEM removed (good), FAIL=0

Audit findings closed:
- cat-b-31ceb6aaa9f1 (P1, updateOwner/updateTeam/updateAgentGroup orphan)
- cat-b-7a34f893a8f9 (P1, updateIssuer/updateProfile orphan, rename-only)
- cat-b-4631ca092bee (P1, RenewalPolicy CRUD orphan)
- cat-b-9b97ffb35ef7 (P3, exportCertificatePEM dead duplicate)

Deferred follow-ups:
- Fuller EditIssuerModal with credential-rotation flow (needs threat
  model: rotation reuse window, in-flight CSR cancellation, audit-trail
  granularity).
- Fuller EditProfileModal with policy-field editing (max-TTL, allowed
  EKUs, allowed key algorithms — affect already-issued cert evaluation).
- Per-page Vitest coverage for the new Edit modals (CI grep guardrail
  catches the same regression vector at lower cost).
2026-04-25 15:23:15 +00:00
shankar0123 03472072b8 test + docs: close 12 test gaps (~250 new tests) and expand testing guide to 34 parts
Implements all P0-P2 test gaps from docs/test-gap-prompt.md:
- Deployment service tests (20), target service tests (18), scheduler tests (8)
- Agent binary tests (48), CSR renewal tests (8), short-lived cert tests (7)
- Domain model tests (25), context cancellation tests (9), concurrency tests (7)
- Handler negative-path tests (23 across 5 files)
- Frontend error handling tests (86) and API client tests (7)

Expands testing-guide.md from 28 to 34 parts covering certificate export,
S/MIME/EKU, OCSP/DER CRL, body size limits, Apache/HAProxy connectors,
and sub-CA mode. Fixes stale profile count (4->5) and updates sign-off table.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 17:57:25 -04:00