UNPKG

n8n-nodes-binalyze-air

Version:

Binalyze AIR nodes for automating DFIR with n8n workflows

1,402 lines 59 kB
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TriageRulesOperations = void 0;
exports.extractTriageRuleId = extractTriageRuleId;
exports.isValidTriageRule = isValidTriageRule;
exports.fetchAllTriageRules = fetchAllTriageRules;
exports.buildTriageRuleQueryParams = buildTriageRuleQueryParams;
exports.getTriageRules = getTriageRules;
exports.getTriageRulesOptions = getTriageRulesOptions;
exports.executeTriageRules = executeTriageRules;
const n8n_workflow_1 = require("n8n-workflow");
const helpers_1 = require("../utils/helpers");
const triagerules_1 = require("../api/triagerules/triagerules");
const organizations_1 = require("./organizations");
exports.TriageRulesOperations = [
    {
        displayName: 'Operation',
        name: 'operation',
        type: 'options',
        noDataExpression: true,
        displayOptions: {
            show: {
                resource: ['triagerules'],
            },
        },
        options: [
            {
                name: 'Assign Triage Task',
                value: 'assignTask',
                description: 'Assign a triage task',
                action: 'Assign a triage task',
            },
            {
                name: 'Create Triage Rule',
                value: 'create',
                description: 'Create a new triage rule',
                action: 'Create a triage rule',
            },
            {
                name: 'Delete Triage Rule',
                value: 'delete',
                description: 'Delete a triage rule',
                action: 'Delete a triage rule',
            },
            {
                name: 'Get',
                value: 'get',
                description: 'Retrieve a specific triage rule',
                action: 'Get a triage rule',
            },
            {
                name: 'Get Many',
                value: 'getAll',
                description: 'Retrieve many triage rules',
                action: 'Get many triage rules',
            },
            {
                name: 'Update Triage Rule',
                value: 'update',
                description: 'Update a triage rule',
                action: 'Update a triage rule',
            },
            {
                name: 'Validate Triage Rule',
                value: 'validate',
                description: 'Validate a triage rule',
                action: 'Validate a triage rule',
            },
        ],
        default: 'getAll',
    },
    {
        displayName: 'Triage Rule',
        name: 'triageRuleId',
        type: 'resourceLocator',
        default: { mode: 'list', value: '' },
        placeholder: 'Select a triage rule...',
        displayOptions: {
            show: {
                resource: ['triagerules'],
                operation: ['get', 'update', 'delete'],
            },
        },
        modes: [
            {
                displayName: 'From List',
                name: 'list',
                type: 'list',
                placeholder: 'Select a triage rule...',
                typeOptions: {
                    searchListMethod: 'getTriageRules',
                    searchable: true,
                },
            },
            {
                displayName: 'By ID',
                name: 'id',
                type: 'string',
                validation: [
                    {
                        type: 'regex',
                        properties: {
                            regex: '^[a-zA-Z0-9-_]+$',
                            errorMessage: 'Not a valid triage rule ID (must contain only letters, numbers, hyphens, and underscores)',
                        },
                    },
                ],
                placeholder: 'Enter triage rule ID',
            },
        ],
        required: true,
        description: 'The triage rule to operate on',
    },
    {
        displayName: 'Rule Engine',
        name: 'engine',
        type: 'options',
        default: 'yara',
        displayOptions: {
            show: {
                resource: ['triagerules'],
                operation: ['create', 'update', 'validate'],
            },
        },
        options: [
            {
                name: 'YARA',
                value: 'yara',
            },
            {
                name: 'Sigma',
                value: 'sigma',
            },
            {
                name: 'Osquery',
                value: 'osquery',
            },
        ],
        required: true,
        description: 'The engine type for the triage rule',
    },
    {
        displayName: 'Rule Description',
        name: 'description',
        type: 'string',
        default: '',
        placeholder: 'Enter triage rule description',
        displayOptions: {
            show: {
                resource: ['triagerules'],
                operation: ['create', 'update'],
            },
        },
        required: true,
        description: 'Description of the triage rule (you must use spaces, hyphens, underscores, at sign or alphanumeric characters)',
        typeOptions: {
            validation: [
                {
                    type: 'regex',
                    properties: {
                        regex: '^[a-zA-Z0-9 _@-]+$',
                        errorMessage: 'Description must contain only alphanumeric characters, spaces, hyphens, underscores, and at sign (@)',
                    },
                },
            ],
        },
    },
    {
        displayName: 'Rule Content',
        name: 'rule',
        type: 'string',
        default: '',
        placeholder: 'Enter the rule content (YARA, Sigma, or osquery)',
        displayOptions: {
            show: {
                resource: ['triagerules'],
                operation: ['create', 'update', 'validate'],
            },
        },
        typeOptions: {
            rows: 10,
        },
        required: true,
        description: 'The rule content based on the selected engine (YARA, Sigma, or osquery)',
    },
    {
        displayName: 'Search In',
        name: 'searchIn',
        type: 'options',
        default: 'both',
        displayOptions: {
            show: {
                resource: ['triagerules'],
                operation: ['create', 'update'],
                engine: ['yara'],
            },
        },
        options: [
            {
                name: 'File System',
                value: 'filesystem',
            },
            {
                name: 'Memory',
                value: 'memory',
            },
            {
                name: 'File System & Memory',
                value: 'both',
            }
        ],
        required: true,
        description: 'Where to search when running the triage rule',
    },
    {
        displayName: 'Case ID',
        name: 'caseId',
        type: 'string',
        default: '',
        placeholder: 'Enter case ID',
        displayOptions: {
            show: {
                resource: ['triagerules'],
                operation: ['assignTask'],
            },
        },
        required: true,
        description: 'ID of the case to assign the triage task to',
    },
    {
        displayName: 'Triage Rule IDs',
        name: 'triageRuleIds',
        type: 'string',
        default: '',
        placeholder: 'Enter triage rule IDs (comma-separated)',
        displayOptions: {
            show: {
                resource: ['triagerules'],
                operation: ['assignTask'],
            },
        },
        required: true,
        description: 'Comma-separated list of triage rule IDs to assign',
    },
    {
        displayName: 'Task Choice',
        name: 'taskChoice',
        type: 'options',
        default: 'auto',
        displayOptions: {
            show: {
                resource: ['triagerules'],
                operation: ['assignTask'],
            },
        },
        options: [
            {
                name: 'Auto',
                value: 'auto',
            },
            {
                name: 'Manual',
                value: 'manual',
            },
        ],
        required: true,
        description: 'Task configuration choice',
    },
    {
        displayName: 'Enable MITRE ATT&CK',
        name: 'mitreAttackEnabled',
        type: 'boolean',
        default: false,
        displayOptions: {
            show: {
                resource: ['triagerules'],
                operation: ['assignTask'],
            },
        },
        description: 'Whether to enable MITRE ATT&CK framework',
    },
    {
        displayName: 'Additional Fields',
        name: 'additionalFields',
        type: 'collection',
        placeholder: 'Add Field',
        default: {},
        displayOptions: {
            show: {
                resource: ['triagerules'],
                operation: ['create'],
            },
        },
        options: [
            {
                displayName: 'Organization',
                name: 'organizationId',
                type: 'resourceLocator',
                default: { mode: 'id', value: '0' },
                placeholder: 'Select an organization...',
                description: 'Organization for this triage rule. Use "0" for all organizations.',
                modes: [
                    {
                        displayName: 'From List',
                        name: 'list',
                        type: 'list',
                        placeholder: 'Select an organization...',
                        typeOptions: {
                            searchListMethod: 'getOrganizations',
                            searchable: true,
                        },
                    },
                    {
                        displayName: 'By ID',
                        name: 'id',
                        type: 'string',
                        validation: [
                            {
                                type: 'regex',
                                properties: {
                                    regex: '^[0-9]+$',
                                    errorMessage: 'Not a valid organization ID (must be a positive number or 0 for default organization)',
                                },
                            },
                        ],
                        placeholder: 'Enter Organization ID (0 for default organization)',
                    },
                    {
                        displayName: 'By Name',
                        name: 'name',
                        type: 'string',
                        placeholder: 'Enter organization name',
                    },
                ],
            },
            {
                displayName: 'Rule Tag IDs',
                name: 'tagIds',
                type: 'string',
                default: '',
                placeholder: 'Enter tag IDs (comma-separated)',
                description: 'Optional comma-separated list of tag IDs to associate with this triage rule',
            },
        ],
    },
    {
        displayName: 'Additional Fields',
        name: 'additionalFields',
        type: 'collection',
        placeholder: 'Add Field',
        default: {},
        displayOptions: {
            show: {
                resource: ['triagerules'],
                operation: ['getAll'],
            },
        },
        options: [
            {
                displayName: 'Filter By Description',
                name: 'description',
                type: 'string',
                default: '',
                description: 'Filter triage rules by description',
            },
            {
                displayName: 'Filter By Engines',
                name: 'engines',
                type: 'multiOptions',
                default: [],
                description: 'Filter by engine types',
                options: [
                    {
                        name: 'YARA',
                        value: 'yara',
                    },
                    {
                        name: 'Sigma',
                        value: 'sigma',
                    },
                    {
                        name: 'Osquery',
                        value: 'osquery',
                    },
                ],
            },
            {
                displayName: 'Filter By Search Term',
                name: 'searchTerm',
                type: 'string',
                default: '',
                description: 'Search term to filter triage rules',
            },
            {
                displayName: 'Organization',
                name: 'organizationId',
                type: 'resourceLocator',
                default: { mode: 'id', value: '0' },
                placeholder: 'Select an organization...',
                description: 'Organization to filter triage rules by. Use "0" to retrieve rules that are visible to all organizations.',
                modes: [
                    {
                        displayName: 'From List',
                        name: 'list',
                        type: 'list',
                        placeholder: 'Select an organization...',
                        typeOptions: {
                            searchListMethod: 'getOrganizations',
                            searchable: true,
                        },
                    },
                    {
                        displayName: 'By ID',
                        name: 'id',
                        type: 'string',
                        validation: [
                            {
                                type: 'regex',
                                properties: {
                                    regex: '^[0-9]+$',
                                    errorMessage: 'Not a valid organization ID (must be a positive number or 0 for default organization)',
                                },
                            },
                        ],
                        placeholder: 'Enter Organization ID (0 for default organization)',
                    },
                    {
                        displayName: 'By Name',
                        name: 'name',
                        type: 'string',
                        placeholder: 'Enter organization name',
                    },
                ],
            },
            {
                displayName: 'Page Number',
                name: 'pageNumber',
                type: 'number',
                default: 1,
                description: 'Which page of results to return',
                typeOptions: {
                    minValue: 1,
                },
            },
            {
                displayName: 'Page Size',
                name: 'pageSize',
                type: 'number',
                default: 100,
                description: 'How many results to return per page',
                typeOptions: {
                    minValue: 1,
                },
            },
        ],
    },
    {
        displayName: 'Additional Fields',
        name: 'additionalFields',
        type: 'collection',
        placeholder: 'Add Field',
        default: {},
        displayOptions: {
            show: {
                resource: ['triagerules'],
                operation: ['get'],
            },
        },
        options: [
            {
                displayName: 'Organization',
                name: 'organizationId',
                type: 'resourceLocator',
                default: { mode: 'id', value: '0' },
                placeholder: 'Select an organization...',
                description: 'Organization to filter triage rules by when using "From List" selection. Use "0" to retrieve rules that are visible to all organizations.',
                modes: [
                    {
                        displayName: 'From List',
                        name: 'list',
                        type: 'list',
                        placeholder: 'Select an organization...',
                        typeOptions: {
                            searchListMethod: 'getOrganizations',
                            searchable: true,
                        },
                    },
                    {
                        displayName: 'By ID',
                        name: 'id',
                        type: 'string',
                        validation: [
                            {
                                type: 'regex',
                                properties: {
                                    regex: '^[0-9]+$',
                                    errorMessage: 'Not a valid organization ID (must be a positive number or 0 for default organization)',
                                },
                            },
                        ],
                        placeholder: 'Enter Organization ID (0 for default organization)',
                    },
                    {
                        displayName: 'By Name',
                        name: 'name',
                        type: 'string',
                        placeholder: 'Enter organization name',
                    },
                ],
            },
        ],
    },
    {
        displayName: 'Additional Fields',
        name: 'additionalFields',
        type: 'collection',
        placeholder: 'Add Field',
        default: {},
        displayOptions: {
            show: {
                resource: ['triagerules'],
                operation: ['update'],
            },
        },
        options: [
            {
                displayName: 'Organization',
                name: 'organizationId',
                type: 'resourceLocator',
                default: { mode: 'id', value: '0' },
                placeholder: 'Select an organization...',
                description: 'Organization for this triage rule. Use "0" for all organizations.',
                modes: [
                    {
                        displayName: 'From List',
                        name: 'list',
                        type: 'list',
                        placeholder: 'Select an organization...',
                        typeOptions: {
                            searchListMethod: 'getOrganizations',
                            searchable: true,
                        },
                    },
                    {
                        displayName: 'By ID',
                        name: 'id',
                        type: 'string',
                        validation: [
                            {
                                type: 'regex',
                                properties: {
                                    regex: '^[0-9]+$',
                                    errorMessage: 'Not a valid organization ID (must be a positive number or 0 for default organization)',
                                },
                            },
                        ],
                        placeholder: 'Enter Organization ID (0 for default organization)',
                    },
                    {
                        displayName: 'By Name',
                        name: 'name',
                        type: 'string',
                        placeholder: 'Enter organization name',
                    },
                ],
            },
        ],
    },
    {
        displayName: 'Additional Fields',
        name: 'additionalFields',
        type: 'collection',
        placeholder: 'Add Field',
        default: {},
        displayOptions: {
            show: {
                resource: ['triagerules'],
                operation: ['assignTask'],
            },
        },
        options: [
            {
                displayName: 'Excluded Endpoint IDs',
                name: 'excludedEndpointIds',
                type: 'string',
                default: '',
                placeholder: 'Enter endpoint IDs (comma-separated)',
                description: 'Exclude specific endpoint IDs',
            },
            {
                displayName: 'Filter By Group Full Path',
                name: 'groupFullPath',
                type: 'string',
                default: '',
            },
            {
                displayName: 'Filter By Group ID',
                name: 'groupId',
                type: 'string',
                default: '',
            },
            {
                displayName: 'Filter By IP Address',
                name: 'ipAddress',
                type: 'string',
                default: '',
            },
            {
                displayName: 'Filter By Isolation Status',
                name: 'isolationStatus',
                type: 'multiOptions',
                default: [],
                options: [
                    { name: 'Isolated', value: 'isolated' },
                    { name: 'Not Isolated', value: 'not_isolated' },
                ],
            },
            {
                displayName: 'Filter By Issue',
                name: 'issue',
                type: 'string',
                default: '',
            },
            {
                displayName: 'Filter By Managed Status',
                name: 'managedStatus',
                type: 'multiOptions',
                default: [],
                options: [
                    { name: 'Managed', value: 'managed' },
                    { name: 'Unmanaged', value: 'unmanaged' },
                ],
            },
            {
                displayName: 'Filter By Name',
                name: 'name',
                type: 'string',
                default: '',
                description: 'Filter by endpoint name',
            },
            {
                displayName: 'Filter By Online Status',
                name: 'onlineStatus',
                type: 'multiOptions',
                default: [],
                options: [
                    { name: 'Online', value: 'online' },
                    { name: 'Offline', value: 'offline' },
                ],
            },
            {
                displayName: 'Filter By Organization',
                name: 'organizationId',
                type: 'resourceLocator',
                default: { mode: 'id', value: '0' },
                placeholder: 'Select an organization...',
                modes: [
                    {
                        displayName: 'From List',
                        name: 'list',
                        type: 'list',
                        placeholder: 'Select an organization...',
                        typeOptions: {
                            searchListMethod: 'getOrganizations',
                            searchable: true,
                        },
                    },
                    {
                        displayName: 'By ID',
                        name: 'id',
                        type: 'string',
                        validation: [
                            {
                                type: 'regex',
                                properties: {
                                    regex: '^[0-9]+$',
                                    errorMessage: 'Not a valid organization ID (must be a positive number or 0 for default organization)',
                                },
                            },
                        ],
                        placeholder: 'Enter Organization ID (0 for default organization)',
                    },
                    {
                        displayName: 'By Name',
                        name: 'name',
                        type: 'string',
                        placeholder: 'Enter organization name',
                    },
                ],
            },
            {
                displayName: 'Filter By Platform',
                name: 'platform',
                type: 'multiOptions',
                default: [],
                options: [
                    { name: 'Windows', value: 'windows' },
                    { name: 'Linux', value: 'linux' },
                    { name: 'MacOS', value: 'macos' },
                ],
            },
            {
                displayName: 'Filter By Policy',
                name: 'policy',
                type: 'string',
                default: '',
            },
            {
                displayName: 'Filter By Tags',
                name: 'tags',
                type: 'string',
                default: '',
                placeholder: 'Enter tags (comma-separated)',
            },
            {
                displayName: 'Filter By Version',
                name: 'version',
                type: 'string',
                default: '',
            },
            {
                displayName: 'Included Endpoint IDs',
                name: 'includedEndpointIds',
                type: 'string',
                default: '',
                placeholder: 'Enter endpoint IDs (comma-separated)',
                description: 'Include specific endpoint IDs',
            },
            {
                displayName: 'Search Term',
                name: 'searchTerm',
                type: 'string',
                default: '',
                description: 'Search term to filter endpoints',
            },
        ],
    },
];
function extractTriageRuleId(triageRule) {
    return (0, helpers_1.extractEntityId)(triageRule, '_id');
}
function isValidTriageRule(triageRule) {
    return (0, helpers_1.isValidEntity)(triageRule, ['_id']);
}
async function fetchAllTriageRules(context, credentials, organizationIds = '0', searchFilter, pageSize = 100) {
    var _a;
    try {
        const queryParams = {
            'filter[organizationIds]': organizationIds
        };
        if (searchFilter) {
            queryParams['filter[searchTerm]'] = searchFilter;
        }
        if (pageSize) {
            queryParams['pageSize'] = pageSize;
        }
        const response = await triagerules_1.api.getTriageRules(context, credentials, organizationIds, queryParams);
        return ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entities) || [];
    }
    catch (error) {
        throw (0, helpers_1.catchAndFormatError)(error, 'Failed to fetch triage rules');
    }
}
function buildTriageRuleQueryParams(organizationIds, additionalFields) {
    const queryParams = {
        'filter[organizationIds]': organizationIds,
    };
    if (additionalFields.description) {
        queryParams['filter[description]'] = additionalFields.description;
    }
    if (additionalFields.searchTerm) {
        queryParams['filter[searchTerm]'] = additionalFields.searchTerm;
    }
    if (additionalFields.searchIn && additionalFields.searchIn.length > 0) {
        queryParams['filter[searchIn]'] = additionalFields.searchIn.join(',');
    }
    if (additionalFields.engines && additionalFields.engines.length > 0) {
        queryParams['filter[engines]'] = additionalFields.engines.join(',');
    }
    if (additionalFields.pageNumber) {
        queryParams['pageNumber'] = additionalFields.pageNumber;
    }
    if (additionalFields.pageSize) {
        queryParams['pageSize'] = additionalFields.pageSize;
    }
    return queryParams;
}
async function getTriageRules(searchTerm) {
    var _a;
    try {
        const credentials = await (0, helpers_1.getAirCredentials)(this);
        let organizationId = '0';
        try {
            const currentNodeParameters = this.getCurrentNodeParameters();
            const additionalFields = currentNodeParameters === null || currentNodeParameters === void 0 ? void 0 : currentNodeParameters.additionalFields;
            if (additionalFields === null || additionalFields === void 0 ? void 0 : additionalFields.organizationId) {
                const organizationResource = additionalFields.organizationId;
                let orgIdString;
                if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
                    orgIdString = organizationResource.value;
                }
                else {
                    orgIdString = '0';
                }
                organizationId = (0, helpers_1.normalizeAndValidateId)(orgIdString, 'Organization ID');
            }
        }
        catch (error) {
            organizationId = '0';
        }
        const queryParams = {
            'filter[organizationIds]': organizationId
        };
        if (searchTerm) {
            queryParams['filter[searchTerm]'] = searchTerm;
        }
        const response = await triagerules_1.api.getTriageRules(this, credentials, organizationId, queryParams);
        const triageRules = ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entities) || [];
        return (0, helpers_1.createListSearchResults)(triageRules, isValidTriageRule, (rule) => ({
            name: rule.description || rule._id || 'Unknown Rule',
            value: extractTriageRuleId(rule),
            url: rule.url || '',
        }), searchTerm);
    }
    catch (error) {
        throw (0, helpers_1.catchAndFormatError)(error, 'Failed to load triage rules for selection');
    }
}
async function getTriageRulesOptions() {
    var _a;
    try {
        const credentials = await (0, helpers_1.getAirCredentials)(this);
        const queryParams = {
            'filter[organizationIds]': '0'
        };
        const response = await triagerules_1.api.getTriageRules(this, credentials, '0', queryParams);
        const triageRules = ((_a = response.result) === null || _a === void 0 ? void 0 : _a.entities) || [];
        return (0, helpers_1.createLoadOptions)(triageRules, isValidTriageRule, (rule) => {
            const ruleId = extractTriageRuleId(rule);
            const name = rule.description || rule._id || `Rule ${ruleId || 'Unknown'}`;
            return {
                name,
                value: ruleId,
            };
        });
    }
    catch (error) {
        throw (0, helpers_1.catchAndFormatError)(error, 'Failed to load triage rules options');
    }
}
async function executeTriageRules() {
    var _a, _b, _c, _d;
    const items = this.getInputData();
    const returnData = [];
    const credentials = await (0, helpers_1.getAirCredentials)(this);
    for (let i = 0; i < items.length; i++) {
        try {
            const operation = this.getNodeParameter('operation', i);
            switch (operation) {
                case 'getAll': {
                    const additionalFields = this.getNodeParameter('additionalFields', i);
                    let organizationId = '0';
                    if (additionalFields.organizationId) {
                        const organizationResource = additionalFields.organizationId;
                        let orgIdString;
                        if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
                            orgIdString = organizationResource.value;
                        }
                        else if (organizationResource.mode === 'name') {
                            try {
                                orgIdString = await (0, organizations_1.findOrganizationByName)(this, credentials, organizationResource.value);
                            }
                            catch (error) {
                                throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, { itemIndex: i });
                            }
                        }
                        else {
                            throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid organization selection mode', {
                                itemIndex: i,
                            });
                        }
                        try {
                            organizationId = (0, helpers_1.normalizeAndValidateId)(orgIdString, 'Organization ID');
                        }
                        catch (error) {
                            throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
                                itemIndex: i,
                            });
                        }
                    }
                    const queryParams = buildTriageRuleQueryParams(organizationId, additionalFields);
                    const responseData = await triagerules_1.api.getTriageRules(this, credentials, organizationId, queryParams);
                    const entities = ((_a = responseData.result) === null || _a === void 0 ? void 0 : _a.entities) || [];
                    const paginationInfo = (0, helpers_1.extractPaginationInfo)(responseData.result);
                    (0, helpers_1.processApiResponseEntities)(entities, returnData, i, {
                        includePagination: true,
                        paginationData: paginationInfo,
                        excludeFields: ['sortables', 'filters'],
                    });
                    break;
                }
                case 'get': {
                    const triageRuleResource = this.getNodeParameter('triageRuleId', i);
                    let triageRuleId;
                    if (triageRuleResource.mode === 'list' || triageRuleResource.mode === 'id') {
                        triageRuleId = triageRuleResource.value;
                    }
                    else {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid triage rule selection mode', {
                            itemIndex: i,
                        });
                    }
                    try {
                        triageRuleId = (0, helpers_1.normalizeAndValidateId)(triageRuleId, 'Triage Rule ID');
                    }
                    catch (error) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
                            itemIndex: i,
                        });
                    }
                    const responseData = await triagerules_1.api.getTriageRuleById(this, credentials, triageRuleId);
                    returnData.push({
                        json: responseData.result,
                        pairedItem: i,
                    });
                    break;
                }
                case 'create': {
                    const description = this.getNodeParameter('description', i);
                    const rule = this.getNodeParameter('rule', i);
                    const engine = this.getNodeParameter('engine', i);
                    const additionalFields = this.getNodeParameter('additionalFields', i);
                    let tagIds;
                    try {
                        const tagIdsString = additionalFields.tagIds;
                        if (tagIdsString && tagIdsString.trim()) {
                            tagIds = tagIdsString.split(',').map(id => id.trim()).filter(id => id.length > 0);
                        }
                    }
                    catch (error) {
                        tagIds = undefined;
                    }
                    let searchIn;
                    if (engine === 'yara') {
                        searchIn = this.getNodeParameter('searchIn', i);
                    }
                    else if (engine === 'osquery') {
                        searchIn = 'system';
                    }
                    else if (engine === 'sigma') {
                        searchIn = 'event-records';
                    }
                    else {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid triage engine ${engine}`, {
                            itemIndex: i,
                        });
                    }
                    const trimmedDescription = description.trim();
                    if (!trimmedDescription) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Description cannot be empty or whitespace', {
                            itemIndex: i,
                        });
                    }
                    const trimmedRule = rule.trim();
                    if (!trimmedRule) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Rule content cannot be empty or whitespace', {
                            itemIndex: i,
                        });
                    }
                    let organizationId = '0';
                    if (additionalFields.organizationId) {
                        const organizationResource = additionalFields.organizationId;
                        let orgIdString;
                        if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
                            orgIdString = organizationResource.value;
                        }
                        else if (organizationResource.mode === 'name') {
                            try {
                                orgIdString = await (0, organizations_1.findOrganizationByName)(this, credentials, organizationResource.value);
                            }
                            catch (error) {
                                throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, { itemIndex: i });
                            }
                        }
                        else {
                            throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid organization selection mode', {
                                itemIndex: i,
                            });
                        }
                        try {
                            organizationId = (0, helpers_1.normalizeAndValidateId)(orgIdString, 'Organization ID');
                        }
                        catch (error) {
                            throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
                                itemIndex: i,
                            });
                        }
                    }
                    const organizationIds = [parseInt(organizationId, 10)];
                    const requestData = {
                        description: trimmedDescription,
                        rule: trimmedRule,
                        engine,
                        organizationIds,
                        searchIn,
                    };
                    if (tagIds && tagIds.length > 0) {
                        requestData.tagIds = tagIds;
                    }
                    try {
                        const responseData = await triagerules_1.api.createTriageRule(this, credentials, requestData);
                        if (responseData.success) {
                            returnData.push({
                                json: responseData.result,
                                pairedItem: i,
                            });
                        }
                        else {
                            returnData.push({
                                json: {
                                    success: false,
                                    error: true,
                                    message: 'Failed to create triage rule',
                                    errors: responseData.errors || [],
                                    statusCode: responseData.statusCode || 400,
                                    result: responseData.result || null
                                },
                                pairedItem: i,
                            });
                        }
                    }
                    catch (error) {
                        if ((_b = error.response) === null || _b === void 0 ? void 0 : _b.data) {
                            const errorData = error.response.data;
                            returnData.push({
                                json: {
                                    success: false,
                                    error: true,
                                    message: errorData.message || 'Failed to create triage rule',
                                    errors: errorData.errors || [error.message || 'Unknown validation error'],
                                    statusCode: errorData.statusCode || error.response.status,
                                    result: errorData.result || null
                                },
                                pairedItem: i,
                            });
                        }
                        else {
                            returnData.push({
                                json: {
                                    success: false,
                                    error: true,
                                    message: 'Failed to create triage rule',
                                    errors: [error.message || 'Unknown error occurred during rule creation'],
                                    statusCode: error.statusCode || 500,
                                    result: null
                                },
                                pairedItem: i,
                            });
                        }
                    }
                    break;
                }
                case 'update': {
                    const triageRuleResource = this.getNodeParameter('triageRuleId', i);
                    const description = this.getNodeParameter('description', i);
                    const rule = this.getNodeParameter('rule', i);
                    const engine = this.getNodeParameter('engine', i);
                    const additionalFields = this.getNodeParameter('additionalFields', i);
                    let searchIn;
                    if (engine === 'yara') {
                        searchIn = this.getNodeParameter('searchIn', i);
                    }
                    else if (engine === 'osquery') {
                        searchIn = 'system';
                    }
                    else if (engine === 'sigma') {
                        searchIn = 'event-records';
                    }
                    else {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid triage engine ${engine}`, {
                            itemIndex: i,
                        });
                    }
                    let triageRuleId;
                    if (triageRuleResource.mode === 'list' || triageRuleResource.mode === 'id') {
                        triageRuleId = triageRuleResource.value;
                    }
                    else {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid triage rule selection mode', {
                            itemIndex: i,
                        });
                    }
                    try {
                        triageRuleId = (0, helpers_1.normalizeAndValidateId)(triageRuleId, 'Triage Rule ID');
                    }
                    catch (error) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
                            itemIndex: i,
                        });
                    }
                    const trimmedDescription = description.trim();
                    if (!trimmedDescription) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Description cannot be empty or whitespace', {
                            itemIndex: i,
                        });
                    }
                    const trimmedRule = rule.trim();
                    if (!trimmedRule) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Rule content cannot be empty or whitespace', {
                            itemIndex: i,
                        });
                    }
                    let organizationId = '0';
                    if (additionalFields.organizationId) {
                        const organizationResource = additionalFields.organizationId;
                        let orgIdString;
                        if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
                            orgIdString = organizationResource.value;
                        }
                        else if (organizationResource.mode === 'name') {
                            try {
                                orgIdString = await (0, organizations_1.findOrganizationByName)(this, credentials, organizationResource.value);
                            }
                            catch (error) {
                                throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, { itemIndex: i });
                            }
                        }
                        else {
                            throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid organization selection mode', {
                                itemIndex: i,
                            });
                        }
                        try {
                            organizationId = (0, helpers_1.normalizeAndValidateId)(orgIdString, 'Organization ID');
                        }
                        catch (error) {
                            throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
                                itemIndex: i,
                            });
                        }
                    }
                    const organizationIds = [parseInt(organizationId, 10)];
                    const requestData = {
                        description: trimmedDescription,
                        rule: trimmedRule,
                        organizationIds,
                        searchIn,
                    };
                    try {
                        const responseData = await triagerules_1.api.updateTriageRule(this, credentials, triageRuleId, requestData);
                        if (responseData.success) {
                            returnData.push({
                                json: responseData.result,
                                pairedItem: i,
                            });
                        }
                        else {
                            returnData.push({
                                json: {
                                    success: false,
                                    error: true,
                                    message: 'Failed to update triage rule',
                                    errors: responseData.errors || [],
                                    statusCode: responseData.statusCode || 400,
                                    result: responseData.result || null
                                },
                                pairedItem: i,
                            });
                        }
                    }
                    catch (error) {
                        if ((_c = error.response) === null || _c === void 0 ? void 0 : _c.data) {
                            const errorData = error.response.data;
                            returnData.push({
                                json: {
                                    success: false,
                                    error: true,
                                    message: errorData.message || 'Failed to update triage rule',
                                    errors: errorData.errors || [error.message || 'Unknown validation error'],
                                    statusCode: errorData.statusCode || error.response.status,
                                    result: errorData.result || null
                                },
                                pairedItem: i,
                            });
                        }
                        else {
                            returnData.push({
                                json: {
                                    success: false,
                                    error: true,
                                    message: 'Failed to update triage rule',
                                    errors: [error.message || 'Unknown error occurred during rule update'],
                                    statusCode: error.statusCode || 500,
                                    result: null
                                },
                                pairedItem: i,
                            });
                        }
                    }
                    break;
                }
                case 'delete': {
                    const triageRuleResource = this.getNodeParameter('triageRuleId', i);
                    let triageRuleId;
                    if (triageRuleResource.mode === 'list' || triageRuleResource.mode === 'id') {
                        triageRuleId = triageRuleResource.value;
                    }
                    else {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid triage rule selection mode', {
                            itemIndex: i,
                        });
                    }
                    try {
                        triageRuleId = (0, helpers_1.normalizeAndValidateId)(triageRuleId, 'Triage Rule ID');
                    }
                    catch (error) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
                            itemIndex: i,
                        });
                    }
                    await triagerules_1.api.deleteTriageRule(this, credentials, triageRuleId);
                    returnData.push({
                        json: {
                            success: true,
                            deleted: true,
                            id: triageRuleId,
                            message: 'Triage rule deleted successfully'
                        },
                        pairedItem: i,
                    });
                    break;
                }
                case 'validate': {
                    const rule = this.getNodeParameter('rule', i);
                    const engine = this.getNodeParameter('engine', i);
                    const trimmedRule = rule.trim();
                    if (!trimmedRule) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Rule content cannot be empty or whitespace', {
                            itemIndex: i,
                        });
                    }
                    const requestData = {
                        rule: trimmedRule,
                        engine,
                    };
                    try {
                        const responseData = await triagerules_1.api.validateTriageRule(this, credentials, requestData);
                        returnData.push({
                            json: {
                                valid: responseData.success,
                                errors: responseData.errors || [],
                                message: responseData.success ? 'Rule is valid' : 'Rule validation failed',
                                statusCode: responseData.statusCode,
                                result: responseData.result
                            },
                            pairedItem: i,
                        });
                    }
                    catch (error) {
                        if ((_d = error.response) === null || _d === void 0 ? void 0 : _d.data) {
                            const errorData = error.response.data;
                            returnData.push({
                                json: {
                                    valid: false,
                                    errors: errorData.errors || [error.message || 'Unknown validation error'],
                                    message: 'Rule validation failed',
                                    statusCode: errorData.statusCode || error.response.status,
                                    result: errorData.result || null
                                },
                                pairedItem: i,
                            });
                        }
                        else {
                            returnData.push({
                                json: {
                                    valid: false,
                                    errors: [error.message || 'Unknown error occurred during validation'],
                                    message: 'Rule validation failed',
                                    statusCode: error.statusCode || 500,
                                    result: null
                                },
                                pairedItem: i,
                            });
                        }
                    }
                    break;
                }
                case 'assignTask': {
                    const caseId = this.getNodeParameter('caseId', i);
                    const triageRuleIds = this.getNodeParameter('triageRuleIds', i);
                    const taskChoice = this.getNodeParameter('taskChoice', i);
                    const mitreAttackEnabled = this.getNodeParameter('mitreAttackEnabled', i);
                    const additionalFields = this.getNodeParameter('additionalFields', i);
                    if (!caseId.trim()) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Case ID cannot be empty', {
                            itemIndex: i,
                        });
                    }
                    if (!triageRuleIds.trim()) {
                        throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Triage rule IDs cannot be empty', {
                            itemIndex: i,
                        });
                    }
                    const ruleIds = triageRuleIds.split(',').map(id => id.trim()).filter(id => id.length > 0);
                    const filter = {};
                    if (additionalFields.searchTerm)
                        filter.searchTerm = additionalFields.searchTerm;
                    if (additionalFields.name)
                        filter.name = additionalFields.name;
                    if (additionalFields.ipAddress)
                        filter.ipAddress = additionalFields.ipAddress;
                    if (additionalFields.groupId)
                        filter.groupId = additionalFields.groupId;
                    if (additionalFields.groupFullPath)
                        filter.groupFullPath = additionalFields.groupFullPath;
                    if (additionalFields.managedStatus && additionalFields.managedStatus.length > 0) {
                        filter.managedStatus = additionalFields.managedStatus;
                    }
                    if (additionalFields.isolationStatus && additionalFields.isolationStatus.length > 0) {
                        filter.isolationStatus = additionalFields.isolationStatus;
                    }
                    if (additionalFields.platform && additionalFields.platform.length > 0) {
                        filter.platform = additionalFields.platform;
                    }
                    if (additionalFields.issue)
                        filter.issue = additionalFields.issue;
                    if (additionalFields.onlineStatus && additionalFields.onlineStatus.length > 0) {
                        filter.onlineStatus = additionalFields.onlineStatus;
                    }
                    if (additionalFields.tags) {
                        filter.tags = additionalFields.tags.split(',').map((tag) => tag.trim()).filter((tag) => tag.length > 0);
                    }
                    if (additionalFields.version)
                        filter.version = additionalFields.version;
                    if (additionalFields.policy)
                        filter.policy = additionalFields.policy;
                    if (additionalFields.includedEndpointIds) {
                        filter.includedEndpointIds = additionalFields.includedEndpointIds.split(',').map((id) => id.trim()).filter((id) => id.length > 0);
                    }
                    if (additionalFields.excludedEndpointIds) {
                        filter.excludedEndpointIds = additionalFields.excludedEndpointIds.split(',').map((id) => id.trim()).filter((id) => id.length > 0);
                    }
                    if (additionalFields.organizationId) {
                        const organizationResource = additionalFields.organizationId;
                        let orgIdString;
                        if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
                            orgIdString = organizationResource.value;
                        }
                        else if (organizationResource.mode === 'name') {
                            try {
                                orgIdString = await (0, organizations_1.findOrganizationByName)(this, credentials, organizationResource.value);
                            }
                            catch (error) {
                                throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, { itemIndex: i });
                            }
                        }
                        else {
                            throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid organization selection mode', {
                                itemIndex: i,
                            });
                        }
                        try {
                            const validatedOrgId = (0, helpers_1.normalizeAndValidateId)(orgIdString, 'Organization ID');
                            filter.organizationIds = [parseInt(validatedOrgId, 10)];
                        }
                        catch (error) {
                            throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
                                itemIndex: i,
                            });
                        }
                    }
                    const requestData = {
                        caseId: caseId.trim(),
                        triageRuleIds: ruleIds,
                        taskConfig: {
                            choice: taskChoice,
                        },
                        mitreAttack: {
                            enabled: mitreAttackEnabled,
                        },
                        filter,
                    };
                    const responseData = await triagerules_1.api.assignTriageTask(this, credentials, requestData);
                    returnData.push({
                        json: responseData.result,
                        pairedItem: i,
                    });
                    break;
                }
                default:
                    throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unsupported operation: ${operation}`, {
                        itemIndex: i,
                    });
            }
        }
        catch (error) {
            (0, helpers_1.handleExecuteError)(this, error, i, returnData);
        }
    }
    return [returnData];
}
//# sourceMappingURL=triagerules.js.map