Commit Graph

299 Commits

Author SHA1 Message Date
jramos
df30430956 feat: add FP submission editing with lifecycle tracking, clickable workflow badges, and edit modal
- Add migration for lifecycle_status, batch UUID, updated_at columns and submission history table
- Add backend endpoints: GET/PUT/POST/PATCH for viewing, editing, adding findings/attachments, and status changes
- Add pure helpers: validateLifecycleTransition, mergeFindings, buildSubmissionHistoryEntry
- Add FpEditModal with tabbed UI (Details, Findings, Attachments, History)
- Make workflow badges clickable for Reworked/Rejected/Expired states with pencil icon
- Add submissions list section to QueuePanel with lifecycle status badges
- Wire state and data flow in ReportingPage for submissions fetch and edit callbacks
2026-04-13 12:27:56 -06:00
jramos
57f11c362b docs: update README with queue redirect, CVE tooltips, FP workflow submission, and missing migrations 2026-04-09 16:18:22 -06:00
jramos
4df83d36dd fix: include hostname overrides in all queue endpoint responses 2026-04-09 16:11:52 -06:00
jramos
0a7a7c2827 feat: add Ivanti Queue redirect for completed items 2026-04-09 16:01:36 -06:00
jramos
1963faf9b8 fix: queue now uses edited hostname override instead of original Ivanti value 2026-04-09 15:25:16 -06:00
jramos
9b36a58959 feat: add CVE tooltip on hover in Reporting Page
- Add GET /api/cves/:cveId/tooltip backend endpoint with description truncation
- Create CveTooltip portal component with caching, severity badges, and viewport-aware positioning
- Integrate tooltip into ReportingPage with 300ms hover delay on CVE badge spans
2026-04-09 14:42:23 -06:00
jramos
690c30aac0 feat: add hostname and IP display to Ivanti queue panel
- Add migration to add hostname column to ivanti_todo_queue table
- Update POST and batch POST endpoints to accept and store hostname
- Pass hostName from findings data when adding items to queue
- Display hostname and IP address in CARD queue section
- Display hostname and IP address in vendor (FP/Archer) queue sections
2026-04-09 11:56:56 -06:00
jramos
fc68097821 fix: remove dual-mode checkbox — clicks always toggle selection, no more popover on first click 2026-04-09 10:01:18 -06:00
jramos
d9fdaf5cbb fix: move selection useEffects after filtered/addPopover declarations to fix ReferenceError 2026-04-09 09:56:33 -06:00
jramos
cb3da6980c Merge feature/batchqueue into master — batch finding disposition 2026-04-09 09:50:24 -06:00
jramos
ccc3576706 feat: add batch finding disposition — multi-select findings and bulk add to Ivanti queue 2026-04-09 09:49:40 -06:00
jramos
5405926550 Merge feature/submit-workflow into master — Ivanti FP workflow submission 2026-04-08 12:45:28 -06:00
jramos
328e48ea8c fix: accept HTTP 202 as success from Ivanti workflow creation
Ivanti returns 202 (Accepted) for async job creation, not just 200/201.
2026-04-08 12:26:35 -06:00
jramos
41f9c35586 fix: correct subjectFilterRequest format and add Ivanti API docs
The subjectFilterRequest field requires a nested structure:
{ subject: 'hostFinding', filterRequest: { filters: [...] } }

Previous attempts with flat { filters: [] } or { subject, filters }
caused Ivanti to return 500. The filterRequest wrapper is required.

Also adds docs/ivanti-api-reference.md documenting all known endpoints,
field formats, and the subjectFilterRequest structure so we don't have
to reverse-engineer the Swagger again.
2026-04-08 12:20:09 -06:00
jramos
729dada05c fix: correct subjectFilterRequest format for Ivanti FP workflow API
The API expects { subject: 'hostFinding', filterRequest: { filters } }
not a flat filter object. Confirmed working via direct curl test —
workflow ID 33418832 created successfully.
2026-04-08 12:18:41 -06:00
jramos
5d417edf82 fix: align subjectFilterRequest with Ivanti search filter schema
Remove extra fields (orWithPrevious, implicitFilters, subject) that
aren't in the Swagger filter schema. Add projection and sort fields
to match the search endpoint format.
2026-04-08 12:08:08 -06:00
jramos
03e60c9daf fix: rewrite FP workflow to use Ivanti multipart/form-data API
The /workflowBatch/falsePositive/request endpoint expects
multipart/form-data with text fields (name, reason, description,
expirationDate, overrideControl, subjectFilterRequest, isEmptyWorkflow)
and inline file uploads — not a JSON body with separate attachment calls.

- Add ivantiFormPost() helper for mixed form fields + files
- Replace buildIvantiPayload with buildIvantiFormFields + buildSubjectFilterRequest
- Remove separate attachment upload loop (files sent inline)
- Update response handling for { id, created } shape
2026-04-08 10:18:45 -06:00
jramos
ee9403ab47 fix: correct Ivanti API endpoint paths for FP workflow creation and attachment
- Creation: /workflowBatch -> /workflowBatch/falsePositive/request
- Attachment: /workflowBatch/{id}/attachment -> /workflowBatch/falsePositive/{uuid}/attach
- Paths confirmed against platform4.risksense.com swagger spec
2026-04-08 10:08:14 -06:00
jramos
3d04cd393f fix: remove no-op status ternary, dead code, and redundant calls
- Fix copy-paste bug in ivantiFpWorkflow.js where both ternary branches
  returned 'partial'; simplified to direct assignment
- Remove unused shouldShowFpButton() from ReportingPage.js (canWrite
  from useAuth() is used instead)
- Hoist repeated isCreateFpButtonEnabled() calls into a single variable
  in QueuePanel render
2026-04-08 09:38:39 -06:00
jramos
382bc81a7e feat: add Ivanti FP workflow submission from Queue
- Add shared ivantiApi.js helper (ivantiPost + ivantiMultipartPost)
- Add ivantiFpWorkflow.js backend route with validation, Ivanti API
  workflow creation, attachment uploads, submission tracking, and audit
- Add add_fp_submissions_table.js migration
- Wire route into server.js at /api/ivanti/fp-workflow
- Add FpWorkflowModal component in ReportingPage.js with form fields,
  drag-and-drop file upload, progress indicator, and result views
- Add Create FP Workflow button to QueuePanel footer (editor/admin only)
- Refactor ivantiWorkflows.js and ivantiFindings.js to use shared helper
2026-04-07 16:20:24 -06:00
jramos
7302ece958 docs: add Upgrade section and Troubleshooting TOC link to README 2026-04-07 13:43:50 -06:00
jramos
80d80c099f docs: add NODE_ENV/Secure cookie warning and troubleshooting section to README 2026-04-07 12:09:27 -06:00
jramos
a2a43a8685 Merge maintenance/security-audit1: security audit remediation and README update 2026-04-07 11:31:41 -06:00
jramos
a711972054 docs: update README for group-based access control, security hardening, and current architecture
- Replace role-based docs with group-based (Admin, Standard_User, Leadership, Read_Only)
- Update API reference with correct group requirements and new endpoints (JIRA tickets, archive, todo-queue)
- Remove hardcoded default credentials from installation instructions
- Document SESSION_SECRET as required with generation instructions
- Add new migrations to install sequence (archive, timestamps, counts history, user_groups, created_by)
- Update architecture tree with new files (ivantiArchive, ComplianceChartsPanel, etc.)
- Update security model with rate limiting, sandbox iframe, rehype-sanitize, Content-Disposition sanitization
- Update database schema docs with created_by columns, user_group triggers, cascade deletes
- Fix middleware reference from requireRole to requireGroup
- Remove stale admin123 references throughout
2026-04-07 11:29:33 -06:00
jramos
8a6a3485e9 security: address audit findings C-4 through M-8
Critical:
- C-4: Add express-rate-limit to login (20 attempts/15min)
- C-5: Remove default credentials from LoginForm.js
- C-6: Add sandbox attribute to KB document iframe

High:
- H-2: Hard-fail on startup if SESSION_SECRET env var is missing
- H-6: Sanitize filenames in Content-Disposition headers
- H-7: Fix KB upload race condition — move file after DB insert succeeds
- H-8: Generate random admin password in setup.js instead of hardcoded
- H-9: Add rehype-sanitize to ReactMarkdown (requires npm install)

Medium:
- M-4: Fix loose equality (==) to strict (===) in users.js self-checks
- M-5: Add hostname format regex validation in compliance notes
- M-6: Fix vendor trim-before-validate in ivantiTodoQueue.js
- M-7: Sanitize original filename in compliance temp JSON
- M-8: Pull CSP frame-ancestors from CORS_ORIGINS env var

New dependencies needed:
- backend: express-rate-limit (npm install in root)
- frontend: rehype-sanitize (npm install in frontend/)
2026-04-07 10:23:10 -06:00
jramos
169a0d2337 Merge feature/usergroups: group-based access control (Admin, Standard_User, Leadership, Read_Only) 2026-04-07 10:11:21 -06:00
jramos
c50fc5d8a8 fix: address all 11 review items for group-based access control
Bugs fixed:
- knowledgeBase.js: logAudit calls converted from positional args to object signature
- archerTickets.js: targetType/targetId renamed to entityType/entityId
- server.js: single CVE delete now has cascade/compliance check for Standard_User

Unprotected endpoints secured:
- ivantiTodoQueue.js: POST/PUT/DELETE now require Admin or Standard_User
- ivantiFindings.js: PUT note and POST sync now require Admin or Standard_User
- compliance.js: POST notes now requires Admin or Standard_User
- ivantiWorkflows.js: POST sync now requires Admin or Standard_User
- auth.js: cleanup-sessions now requires Admin via requireAuth + requireGroup

Additional fixes:
- ExportsPage.js: canExport() guard blocks Read_Only users
- knowledgeBase.js: Standard_User delete checks created_by ownership
- Migration: added INSERT/UPDATE triggers to enforce valid user_group values
2026-04-07 10:09:18 -06:00
jramos
e9e2c0961d fix: address all 11 review items for group-based access control
Bugs fixed:
- knowledgeBase.js: logAudit calls converted from positional args to object signature
- archerTickets.js: targetType/targetId renamed to entityType/entityId
- server.js: single CVE delete now has cascade/compliance check for Standard_User

Unprotected endpoints secured:
- ivantiTodoQueue.js: POST/PUT/DELETE now require Admin or Standard_User
- ivantiFindings.js: PUT note and POST sync now require Admin or Standard_User
- compliance.js: POST notes now requires Admin or Standard_User
- ivantiWorkflows.js: POST sync now requires Admin or Standard_User
- auth.js: cleanup-sessions now requires Admin via requireAuth + requireGroup

Additional fixes:
- ExportsPage.js: canExport() guard blocks Read_Only users
- knowledgeBase.js: Standard_User delete checks created_by ownership
- Migration: added INSERT/UPDATE triggers to enforce valid user_group values
2026-04-07 09:52:26 -06:00
jramos
d910af847e fix: wire up admin page route to render UserManagement component 2026-04-06 16:25:59 -06:00
jramos
73fd747576 feat: implement group-based access control (Admin, Standard_User, Leadership, Read_Only)
- Add user_group migration and created_by column migration
- Replace requireRole middleware with requireGroup
- Update all backend routes to use group-based authorization
- Add Standard_User conditional delete with ownership, state, and compliance checks
- Add cascade impact check for CVE deletes
- Update AuthContext with group-based permission helpers
- Update all frontend components for group-based rendering
- Update UserManagement UI with group dropdown, confirmation dialogs, self-demotion prevention
2026-04-06 16:18:07 -06:00
1ef57b0504 feat(archive): add finding archive tracking to Ivanti sync pipeline
Adds a four-state lifecycle tracker (ACTIVE → ARCHIVED → RETURNED → CLOSED)
to detect and monitor findings that disappear from Ivanti sync results due to
severity score drift rather than actual remediation.

- Archive detection runs automatically after each sync, comparing previous
  and current finding sets to identify disappearances and reappearances
- Full transition history stored in ivanti_finding_archives and
  ivanti_archive_transitions tables with timestamps and severity scores
- Three new API endpoints: /api/ivanti/archive, /api/ivanti/archive/stats,
  /api/ivanti/archive/:findingId/history
- Archive Summary Bar UI on the home page shows counts for each state
  (Active, Archived, Returned, Closed) with click-through finding lists
- Two new migrations: add_finding_archive_tables, add_archer_tickets_timestamps
- Mermaid diagram support added to Knowledge Base viewer
2026-04-06 09:51:56 -06:00
jramos
d1fe0bf455 fix: resolve 5 pre-merge issues in finding archive tracking
1. ACTIVE state never populated — stats endpoint now computes ACTIVE from live findings cache count instead of querying archive table

2. CHECK constraint mismatch — migration now uses 3-state constraint (ARCHIVED, RETURNED, CLOSED) matching runtime initArchiveTables()

3. Archive filter click non-functional — handleArchiveStateClick now fetches and renders filtered archive list below summary bar

4. Hook glob pattern mismatch — changed **/migrate*.js to **/migrations/*.js so hook fires for actual migration filenames

5. Stale stats after sync — ArchiveSummaryBar polls every 60s and refreshes immediately after workflow sync via refreshKey prop
2026-04-03 15:51:18 -06:00
jramos
3f7887eba6 added hooks 2026-04-03 15:29:05 -06:00
jramos
9bd5a52661 feat: implement finding archive tracking system
- Add migration script for ivanti_finding_archives and ivanti_archive_transitions tables
- Add archive detection logic (detectArchiveChanges, detectClosedFindings) in sync pipeline
- Add archive API router with list, stats, and history endpoints at /api/ivanti/archive
- Add ArchiveSummaryBar UI component with four state cards (ACTIVE, ARCHIVED, RETURNED, CLOSED)
- Integrate ArchiveSummaryBar into Ivanti findings page in App.js
- Register archive router in server.js
2026-04-03 15:20:04 -06:00
jramos
2b4ec5d8e2 added kiro specs 2026-04-03 13:48:04 -06:00
jramos
62592e9821 add kiro steering files 2026-04-03 09:27:12 -06:00
2fead2cfef feat(kb): render Mermaid diagrams in Knowledge Base viewer
Installs mermaid v11 and adds a custom ReactMarkdown code renderer
that intercepts fenced mermaid blocks and renders them as SVG diagrams
using the dark theme. SVGs are made responsive (width: 100%).
Non-mermaid code blocks are unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 15:37:00 -06:00
7c0ba41514 fix(migrations): add created_at/updated_at to archer_tickets if missing
Production instances where the table was created before these columns
were added to the schema will see 500 errors on all /api/archer-tickets
endpoints. This migration safely checks PRAGMA table_info before each
ALTER TABLE so it is idempotent and safe to run multiple times.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 15:23:38 -06:00
9c6c03a518 feat: time-based charts, Vulnerability Triage rename, Knowledge Base page
Merges feature/compliance-time-charts into master.

Changes included:
- Compliance page: 6 Recharts trend charts (active totals, deltas, per-team,
  MTTR, recurring items, Archer pipeline)
- Ivanti findings trend chart on Vulnerability Triage page: open/closed
  counts history stored on every sync, aggregated to end-of-day snapshots
- Rename 'Reporting' page to 'Vulnerability Triage' throughout (nav, routes,
  docs, all cross-page navigation references)
- Knowledge Base page: full article library with category filter, search,
  inline viewer, upload/delete for editor+ roles
- Remove Knowledge Base sidebar panel from home page (now lives on KB page);
  home layout adjusts to 2-column (9+3)
- Add ivanti_counts_history migration script for documentation consistency
- Update security-posture-workflow-diagrams.md and team-training-agenda.md
  to reflect Vulnerability Triage page name

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 14:53:13 -06:00
0d48c109b3 refactor(home): remove Knowledge Base panel from home page
The dedicated Knowledge Base page now provides the full library
experience. Remove the KB sidebar panel, viewer inline embed,
upload modal, and all supporting state/functions from App.js.

Home page layout adjusts from 3-column to 2-column (9+3 grid):
main CVE content expands to col-span-9, right panel unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 14:32:36 -06:00
18ad31228e feat(kb): build Knowledge Base page
Replaces the 'coming soon' placeholder with a full library UI.
No backend changes needed — all existing endpoints and components
(KnowledgeBaseViewer, KnowledgeBaseModal) are reused.

Features:
  - Article card grid (responsive auto-fill, min 240px per card)
  - Category filter tabs (Procedure, Guide, Policy, Reference, General)
    with live article counts; tabs only shown for populated categories
  - Search bar — filters by title and description, client-side
  - Inline viewer — clicking a card opens KnowledgeBaseViewer below
    the grid; clicking again or pressing the close button collapses it
  - Upload modal (editor/admin only) refreshes the grid on success
  - Delete button on each card (editor/admin only) with confirmation
  - Graceful empty states for no articles and no search results
  - Loading and error states with retry

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 13:55:51 -06:00
3dcb91a1fc chore(migrations): add migration script for ivanti_counts_history table
Standalone migration script for consistency with other files in
backend/migrations/. The table is also created automatically at server
startup via CREATE TABLE IF NOT EXISTS in initTables() so no manual
step is required on the dev server — just restart the backend after
pulling.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 10:17:33 -06:00
5102a2c5b4 docs: update 'Reporting page' references to 'Vulnerability Triage'
Updated all human-readable references in documentation to reflect the
page rename. File path citations in security-audit-2026-04-01.md
(ReportingPage.js:51) are left unchanged as the file itself was not
renamed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 10:15:51 -06:00
a0a8979c63 fix(triage): fix missed setCurrentPage('reporting') in Archer ticket filter button
One reference to the old page ID was missed in the previous rename commit.
The Archer ticket EXC filter button in App.js was still navigating to
'reporting', which would silently fail to navigate. Updated to 'triage'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 10:13:57 -06:00
15ad207464 feat(triage): Ivanti findings trend chart + rename Reporting to Vulnerability Triage
Add time-based open/closed tracking for Ivanti findings (Tier 2 from
the reporting recommendations doc) and rename the Reporting page to
Vulnerability Triage to better reflect its purpose.

Backend — ivantiFindings.js:
  - Create ivanti_counts_history table (appended on every sync, never
    overwritten — Option B from design discussion)
  - INSERT snapshot after each successful syncClosedCount() call
  - GET /api/ivanti/findings/counts/history endpoint — returns last
    snapshot per calendar day using ROW_NUMBER window function, so
    multiple daily syncs collapse to the end-of-day value

Frontend:
  - New IvantiCountsChart component: collapsible dual-line chart
    (open vs closed) with dark tooltip, delta label showing change
    since previous day, and graceful no-data states
  - Chart placed between the donut metrics panel and the findings table
    on the Vulnerability Triage page
  - Renamed page: 'reporting' → 'triage' (page ID, nav label, component
    export, all cross-file references)
  - ComplianceDetailPanel "View in Reporting" link updated to "View in
    Triage" and navigates to the correct page ID

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 10:12:04 -06:00
b111273e5a feat(compliance): add time-based trend charts to Compliance page
Add 6 Recharts charts in a collapsible Historical Trends panel on the
Compliance page, covering all Tier-1 recommendations from the reporting
design doc.

Backend — 5 new API endpoints:
  - GET /api/compliance/trends        — active totals + per-team counts per upload
  - GET /api/compliance/mttr          — mean days to resolution per team
  - GET /api/compliance/top-recurring — most persistent active findings by seen_count
  - GET /api/compliance/category-trend — category breakdown per upload (future use)
  - GET /api/archer-tickets/status-trend — ticket pipeline by creation date + status

Frontend — new ComplianceChartsPanel component:
  - Active Findings Over Time (multi-line: total + per-team dashed)
  - Change per Report Cycle (stacked bar: new/recurring + resolved)
  - Team Compliance Health (multi-line per team)
  - Mean Time to Resolution (horizontal bar per team)
  - Most Persistent Findings (horizontal bar top-10 by seen_count)
  - Archer Exception Pipeline (stacked bar by date + status)

All charts degrade gracefully to a no-data placeholder until uploads
accumulate. Panel is collapsible to stay out of the way when not needed.
Adds recharts dependency to frontend.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 09:49:32 -06:00
a7c74f625f docs: clarify Python deps use apt packages not pip/venv
Dev server uses apt-managed python3-pandas and python3-openpyxl.
Production fix is the same. Updates README install step and rewrites
python-venv-setup.md to reflect the real setup with venv as fallback.
2026-04-01 13:07:27 -06:00
8aef51b59a fix(compliance): use PYTHON_BIN env var for venv support
Modern Debian/Ubuntu enforces PEP 668 which blocks system-wide pip
installs. The backend now reads PYTHON_BIN from the environment
(defaulting to 'python3') so each server can point to a venv.
Updates README with venv setup instructions.
2026-04-01 12:47:50 -06:00
d0087ba9b7 docs: remove all weekly reports references
Weekly report feature was removed previously. Cleans up all remaining
references from README, architecture diagram, and deletes
WEEKLY_REPORT_FEATURE.md entirely.
2026-04-01 12:42:56 -06:00
3d6062f3fa docs: refresh README and add security posture workflow diagrams
- Rename project to STEAM Security Dashboard throughout README
- Document Ivanti Queue feature (FP/Archer/CARD staging, per-user persistence)
- Document AEO Compliance page (upload flow, metric health cards, device
  table, detail panel, View in Reporting link for 2.3.x metrics)
- Add all missing migrations to install instructions (queue, CARD,
  ip_address, compliance tables)
- Add Ivanti Queue and Compliance endpoint tables to API reference
- Update architecture file tree with new routes, migrations, scripts,
  and frontend components
- Add compliance DB tables to schema section
- Document parse_compliance_xlsx.py in scripts section
- Add security-posture-workflow-diagrams.md (Mermaid, VSCode/GitHub)
- Add security-posture-workflow-lucidchart.md (Lucidchart import format)
2026-04-01 10:46:39 -06:00