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
This commit is contained in:
jramos
2026-04-08 09:38:39 -06:00
parent 382bc81a7e
commit 3d04cd393f
2 changed files with 60 additions and 25 deletions

View File

@@ -124,7 +124,41 @@ const fpUpload = multer({
function createIvantiFpWorkflowRouter(db, requireAuth) { function createIvantiFpWorkflowRouter(db, requireAuth) {
const router = express.Router(); const router = express.Router();
// POST /api/ivanti/fp-workflow /**
* POST /api/ivanti/fp-workflow
*
* Creates a False Positive workflow batch in the Ivanti/RiskSense API,
* optionally uploads file attachments, records the submission locally,
* and marks the associated queue items as complete.
*
* Content-Type: multipart/form-data
*
* @param {string} req.body.name - Workflow name (required, max 255 chars)
* @param {string} req.body.reason - Reason for the FP determination (required)
* @param {string} [req.body.description] - Additional description (optional, max 2000 chars)
* @param {string} req.body.expirationDate - ISO date string, must be a future date (required)
* @param {string} [req.body.scopeOverride] - "Authorized" (default) or "None"
* @param {string} req.body.findingIds - JSON-encoded array of Ivanti finding IDs
* @param {string} req.body.queueItemIds - JSON-encoded array of local queue item IDs
* @param {File[]} [req.files] - Up to 10 file attachments (max 10 MB each);
* allowed extensions: .pdf .png .jpg .jpeg .gif
* .doc .docx .xlsx .csv .txt .zip
*
* @returns {object} 200 - Success
* { success: true, workflowBatchId: number, generatedId: string,
* attachmentResults: Array<{ filename: string, success: boolean, error?: string }>,
* queueItemsUpdated: number, status: 'success' | 'partial' }
* @returns {object} 400 - Validation error
* { error: string } or { success: false, errors: { [field]: string } }
* @returns {object} 403 - Queue item ownership violation
* { error: string }
* @returns {object} 429 - Ivanti rate limit
* { success: false, error: string, step: 'create_workflow' }
* @returns {object} 500 - Server configuration error
* { success: false, error: string, step: 'create_workflow' }
* @returns {object} 502 - Ivanti API error
* { success: false, error: string, step: 'create_workflow', details?: string }
*/
router.post('/', requireAuth(db), requireGroup('Admin', 'Standard_User'), (req, res) => { router.post('/', requireAuth(db), requireGroup('Admin', 'Standard_User'), (req, res) => {
fpUpload(req, res, (multerErr) => { fpUpload(req, res, (multerErr) => {
if (multerErr) { if (multerErr) {
@@ -283,7 +317,7 @@ function createIvantiFpWorkflowRouter(db, requireAuth) {
const failedAttachments = attachmentResults.filter(r => !r.success); const failedAttachments = attachmentResults.filter(r => !r.success);
let status = 'success'; let status = 'success';
if (files.length > 0 && failedAttachments.length > 0) { if (files.length > 0 && failedAttachments.length > 0) {
status = failedAttachments.length === files.length ? 'partial' : 'partial'; status = 'partial';
} }
// 5. Insert submission record // 5. Insert submission record

View File

@@ -1493,26 +1493,29 @@ function QueuePanel({ open, items, onClose, onUpdate, onDelete, onDeleteMany, on
display: 'flex', gap: '0.5rem', display: 'flex', gap: '0.5rem',
}}> }}>
{/* Create FP Workflow — visible for editor/admin only */} {/* Create FP Workflow — visible for editor/admin only */}
{canWrite && ( {canWrite && (() => {
const fpEnabled = isCreateFpButtonEnabled(items, selectedIds);
return (
<button <button
onClick={() => onCreateFpWorkflow([...selectedIds])} onClick={() => onCreateFpWorkflow([...selectedIds])}
disabled={!isCreateFpButtonEnabled(items, selectedIds)} disabled={!fpEnabled}
title={!isCreateFpButtonEnabled(items, selectedIds) ? 'Select pending FP items to create a workflow' : ''} title={!fpEnabled ? 'Select pending FP items to create a workflow' : ''}
style={{ style={{
flex: 1, padding: '0.45rem', flex: 1, padding: '0.45rem',
background: isCreateFpButtonEnabled(items, selectedIds) ? 'rgba(245,158,11,0.12)' : 'transparent', background: fpEnabled ? 'rgba(245,158,11,0.12)' : 'transparent',
border: `1px solid ${isCreateFpButtonEnabled(items, selectedIds) ? 'rgba(245,158,11,0.35)' : 'rgba(255,255,255,0.05)'}`, border: `1px solid ${fpEnabled ? 'rgba(245,158,11,0.35)' : 'rgba(255,255,255,0.05)'}`,
borderRadius: '0.375rem', borderRadius: '0.375rem',
color: isCreateFpButtonEnabled(items, selectedIds) ? '#F59E0B' : '#334155', color: fpEnabled ? '#F59E0B' : '#334155',
fontFamily: 'monospace', fontSize: '0.72rem', fontWeight: '600', fontFamily: 'monospace', fontSize: '0.72rem', fontWeight: '600',
cursor: isCreateFpButtonEnabled(items, selectedIds) ? 'pointer' : 'not-allowed', cursor: fpEnabled ? 'pointer' : 'not-allowed',
textTransform: 'uppercase', letterSpacing: '0.05em', textTransform: 'uppercase', letterSpacing: '0.05em',
transition: 'all 0.12s', transition: 'all 0.12s',
}} }}
> >
Create FP Workflow Create FP Workflow
</button> </button>
)} );
})()}
{/* Delete selected — only shown when items are selected */} {/* Delete selected — only shown when items are selected */}
{selectedIds.size > 0 && ( {selectedIds.size > 0 && (
<button <button
@@ -1570,9 +1573,7 @@ function filterFpItems(items) {
return items.filter(item => item.workflow_type === 'FP'); return items.filter(item => item.workflow_type === 'FP');
} }
function shouldShowFpButton(role) {
return role === 'editor' || role === 'admin';
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// FpWorkflowModal — submit FP workflows to Ivanti API // FpWorkflowModal — submit FP workflows to Ivanti API