diff --git a/backend/routes/ivantiFpWorkflow.js b/backend/routes/ivantiFpWorkflow.js index 917051c..7726b65 100644 --- a/backend/routes/ivantiFpWorkflow.js +++ b/backend/routes/ivantiFpWorkflow.js @@ -858,6 +858,10 @@ function createIvantiFpWorkflowRouter(db, requireAuth) { } const mapUrl = `/client/${encodeURIComponent(clientId)}/workflowBatch/falsePositive/${encodeURIComponent(mapUuid)}/map`; + + // Map endpoint likely expects multipart/form-data like the create endpoint. + // Try both: first as JSON POST, fall back to multipart if that fails. + let mapResult; const mapBody = { subject: 'hostFinding', filterRequest: { @@ -870,9 +874,16 @@ function createIvantiFpWorkflowRouter(db, requireAuth) { } }; - let mapResult; try { + // Try JSON first mapResult = await ivantiPost(mapUrl, mapBody, apiKey, skipTls); + + // If JSON returns 500/415, retry as multipart form + if (mapResult.status === 500 || mapResult.status === 415) { + console.log('[mapFindings] JSON POST returned', mapResult.status, '— retrying as multipart form'); + const formFields = [{ name: 'subjectFilterRequest', value: buildSubjectFilterRequest(findingIds) }]; + mapResult = await ivantiFormPost(mapUrl, formFields, [], apiKey, skipTls); + } } catch (networkErr) { logAudit(db, { userId: req.user.id, username: req.user.username, @@ -886,7 +897,7 @@ function createIvantiFpWorkflowRouter(db, requireAuth) { if (mapResult.status !== 200 && mapResult.status !== 201 && mapResult.status !== 202) { console.error('[mapFindings] Ivanti map failed — status:', mapResult.status, 'body:', (mapResult.body || '').substring(0, 500)); console.error('[mapFindings] Request URL:', mapUrl); - console.error('[mapFindings] Request body:', JSON.stringify(mapBody)); + console.error('[mapFindings] Last attempt body/fields — JSON:', JSON.stringify(mapBody).substring(0, 300)); const errorMap = { 401: 'Ivanti API key is invalid or missing. Contact your administrator.', 419: 'API key lacks permissions for this operation.',