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
This commit is contained in:
jramos
2026-04-07 09:52:26 -06:00
parent d910af847e
commit e9e2c0961d
10 changed files with 154 additions and 64 deletions

View File

@@ -1,5 +1,6 @@
// routes/ivantiTodoQueue.js
const express = require('express');
const { requireGroup } = require('../middleware/auth');
const VALID_WORKFLOW_TYPES = ['FP', 'Archer', 'CARD'];
const VALID_STATUSES = ['pending', 'complete'];
@@ -36,7 +37,7 @@ function createIvantiTodoQueueRouter(db, requireAuth) {
// POST /api/ivanti/todo-queue
// Add a finding to the queue
router.post('/', requireAuth(db), (req, res) => {
router.post('/', requireAuth(db), requireGroup('Admin', 'Standard_User'), (req, res) => {
const { finding_id, finding_title, cves, ip_address, vendor, workflow_type } = req.body;
if (!finding_id || typeof finding_id !== 'string' || finding_id.trim().length === 0) {
@@ -86,7 +87,7 @@ function createIvantiTodoQueueRouter(db, requireAuth) {
// PUT /api/ivanti/todo-queue/:id
// Update vendor, workflow_type, or status — scoped to current user
router.put('/:id', requireAuth(db), (req, res) => {
router.put('/:id', requireAuth(db), requireGroup('Admin', 'Standard_User'), (req, res) => {
const { id } = req.params;
const { vendor, workflow_type, status } = req.body;
@@ -162,7 +163,7 @@ function createIvantiTodoQueueRouter(db, requireAuth) {
// DELETE /api/ivanti/todo-queue/completed
// Bulk-delete all completed items for the current user
// IMPORTANT: This route must be registered BEFORE DELETE /:id
router.delete('/completed', requireAuth(db), (req, res) => {
router.delete('/completed', requireAuth(db), requireGroup('Admin', 'Standard_User'), (req, res) => {
db.run(
"DELETE FROM ivanti_todo_queue WHERE user_id = ? AND status = 'complete'",
[req.user.id],
@@ -178,7 +179,7 @@ function createIvantiTodoQueueRouter(db, requireAuth) {
// DELETE /api/ivanti/todo-queue/:id
// Delete a single item — scoped to current user
router.delete('/:id', requireAuth(db), (req, res) => {
router.delete('/:id', requireAuth(db), requireGroup('Admin', 'Standard_User'), (req, res) => {
const { id } = req.params;
db.get(