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,6 +1,7 @@
import React, { useState, useCallback } from 'react';
import * as XLSX from 'xlsx';
import { Download, Loader, AlertCircle, BarChart2, FileText, Shield, Tag, CheckCircle, X } from 'lucide-react';
import { useAuth } from '../../contexts/AuthContext';
const API_BASE = process.env.REACT_APP_API_BASE || 'http://localhost:3001/api';
const EXC_PATTERN = /EXC-\d+/i;
@@ -217,6 +218,7 @@ function Toggle({ label, checked, onChange, color, colorRgb }) {
// Main page
// ---------------------------------------------------------------------------
export default function ExportsPage() {
const { canExport } = useAuth();
const [loading, setLoading] = useState(null);
const [error, setError] = useState(null);
const [cveStatus, setCveStatus] = useState('');
@@ -333,6 +335,15 @@ export default function ExportsPage() {
// ---- Render ----
if (!canExport()) {
return (
<div style={{ textAlign: 'center', padding: '4rem 1rem', color: '#94A3B8' }}>
<Shield style={{ width: '48px', height: '48px', margin: '0 auto 1rem', opacity: 0.5 }} />
<p style={{ fontFamily: 'monospace', fontSize: '0.9rem' }}>You do not have permission to export data.</p>
</div>
);
}
return (
<div style={{ padding: '1.5rem', display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>