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:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user