fix(TheHive Node): Normalize analyzers when expression returns a string (#32472)

Co-authored-by: Elias Meire <elias@meire.dev>
This commit is contained in:
Hammad Khan
2026-06-30 12:18:32 +05:00
committed by GitHub
parent 476aeaa944
commit efa9c4e334
3 changed files with 62 additions and 8 deletions
@@ -67,6 +67,25 @@ export function splitTags(tags: string): string[] {
return tags.split(',').filter((tag) => tag !== ' ' && tag);
}
// The "Analyzers" field is a multiOptions parameter, so it normally resolves to
// an array of "analyzerId::cortexId" entries. When its value comes from an
// expression wrapped in surrounding text/whitespace, n8n switches to string
// interpolation and the array is coerced to a comma-joined string. Normalize
// both shapes so the operation does not throw "(...).map is not a function".
export function parseAnalyzers(value: string | string[]) {
const entries = Array.isArray(value)
? value
: value
.split(',')
.map((entry) => entry.trim())
.filter((entry) => entry);
return entries.map((analyzer) => {
const [analyzerId, cortexId] = analyzer.split('::');
return { analyzerId, cortexId };
});
}
export function prepareOptional(optionals: IDataObject): IDataObject {
const response: IDataObject = {};
for (const key in optionals) {
@@ -20,6 +20,7 @@ import { taskFields, taskOperations } from './descriptions/TaskDescription';
import {
buildCustomFieldSearch,
mapResource,
parseAnalyzers,
prepareCustomFields,
prepareOptional,
prepareRangeQuery,
@@ -752,14 +753,8 @@ export class TheHive implements INodeType {
if (operation === 'executeAnalyzer') {
const observableId = this.getNodeParameter('id', i);
const analyzers = (this.getNodeParameter('analyzers', i) as string[]).map(
(analyzer) => {
const parts = analyzer.split('::');
return {
analyzerId: parts[0],
cortexId: parts[1],
};
},
const analyzers = parseAnalyzers(
this.getNodeParameter('analyzers', i) as string | string[],
);
let response: any;
let body: IDataObject;
@@ -0,0 +1,40 @@
import { parseAnalyzers } from '../GenericFunctions';
describe('Test TheHive, parseAnalyzers', () => {
it('should map an array of "analyzerId::cortexId" entries', () => {
const result = parseAnalyzers(['analyzer-1::cortex-1', 'analyzer-2::cortex-2']);
expect(result).toEqual([
{ analyzerId: 'analyzer-1', cortexId: 'cortex-1' },
{ analyzerId: 'analyzer-2', cortexId: 'cortex-2' },
]);
});
it('should map a comma-joined string (expression coercion case)', () => {
const result = parseAnalyzers('analyzer-1::cortex-1, analyzer-2::cortex-2');
expect(result).toEqual([
{ analyzerId: 'analyzer-1', cortexId: 'cortex-1' },
{ analyzerId: 'analyzer-2', cortexId: 'cortex-2' },
]);
});
it('should handle a single analyzer provided as a string', () => {
const result = parseAnalyzers('analyzer-1::cortex-1');
expect(result).toEqual([{ analyzerId: 'analyzer-1', cortexId: 'cortex-1' }]);
});
it('should drop empty entries from a comma-joined string', () => {
const result = parseAnalyzers('analyzer-1::cortex-1,, analyzer-2::cortex-2,');
expect(result).toEqual([
{ analyzerId: 'analyzer-1', cortexId: 'cortex-1' },
{ analyzerId: 'analyzer-2', cortexId: 'cortex-2' },
]);
});
it('should return an empty array for an empty string', () => {
expect(parseAnalyzers('')).toEqual([]);
});
});