n8n-nodes-binalyze-air
Version:
Binalyze AIR nodes for automating DFIR with n8n workflows
1,777 lines • 73.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AssetsOperations = void 0;
exports.extractAssetId = extractAssetId;
exports.isValidAsset = isValidAsset;
exports.fetchAllAssets = fetchAllAssets;
exports.buildAssetQueryParams = buildAssetQueryParams;
exports.buildAssetFilter = buildAssetFilter;
exports.getAssets = getAssets;
exports.getAssetsByOrganizationForDeviceActions = getAssetsByOrganizationForDeviceActions;
exports.getAssetsOptions = getAssetsOptions;
exports.executeAssets = executeAssets;
const n8n_workflow_1 = require("n8n-workflow");
const helpers_1 = require("../utils/helpers");
const assets_1 = require("../api/assets/assets");
const organizations_1 = require("./organizations");
async function checkExistingTask(context, credentials, assetId, taskType) {
try {
const queryParams = {
'filter[type]': taskType,
'filter[status]': 'assigned'
};
const tasksResponse = await assets_1.api.getAssetTasks(context, credentials, assetId, queryParams);
if (tasksResponse.result && tasksResponse.result.entities && tasksResponse.result.entities.length > 0) {
return tasksResponse.result.entities[0];
}
return null;
}
catch (error) {
console.error(`Error checking existing tasks: ${error.message}`);
return null;
}
}
exports.AssetsOperations = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['assets'],
},
},
options: [
{
name: 'Add Tags',
value: 'addTags',
description: 'Add tags to assets by filter',
action: 'Add tags to assets',
},
{
name: 'Assign Isolation Task',
value: 'setIsolation',
description: 'Assign isolation task to an asset',
action: 'Assign isolation task to an asset',
},
{
name: 'Assign Reboot Task',
value: 'reboot',
description: 'Assign reboot task to an asset',
action: 'Assign reboot task to assets',
},
{
name: 'Assign Shutdown Task',
value: 'shutdown',
description: 'Assign shutdown task to an asset',
action: 'Assign shutdown task to asset',
},
{
name: 'Get',
value: 'get',
description: 'Retrieve a specific asset',
action: 'Get an asset',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Retrieve many assets',
action: 'Get many assets',
},
{
name: 'Get Tasks',
value: 'getAssetTasks',
description: 'Get tasks for a specific asset',
action: 'Get asset tasks',
},
{
name: 'Remove Tags',
value: 'removeTags',
description: 'Remove tags from assets by filter',
action: 'Remove tags from assets',
},
],
default: 'getAll',
},
{
displayName: 'Organization',
name: 'organizationId',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select an organization...',
displayOptions: {
show: {
resource: ['assets'],
operation: ['getAll'],
},
},
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 number)',
},
},
],
placeholder: 'Enter organization ID',
},
{
displayName: 'By Name',
name: 'name',
type: 'string',
placeholder: 'Enter organization name',
},
],
required: true,
description: 'The organization to get assets from',
},
{
displayName: 'Asset',
name: 'assetId',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select an asset...',
displayOptions: {
show: {
resource: ['assets'],
operation: ['get', 'getAssetTasks'],
},
},
modes: [
{
displayName: 'From List',
name: 'list',
type: 'list',
placeholder: 'Select an asset...',
typeOptions: {
searchListMethod: 'getAssets',
searchable: true,
},
},
{
displayName: 'By ID',
name: 'id',
type: 'string',
validation: [
{
type: 'regex',
properties: {
regex: '^[a-zA-Z0-9-_]+$',
errorMessage: 'Not a valid asset ID (must contain only letters, numbers, hyphens, and underscores)',
},
},
],
placeholder: 'Enter asset ID',
},
],
required: true,
description: 'The asset to operate on',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['assets'],
operation: ['getAll'],
},
},
options: [
{
displayName: 'Filter By Asset Name',
name: 'name',
type: 'string',
default: '',
placeholder: 'Enter asset name',
},
{
displayName: 'Filter By IP Address',
name: 'ipAddress',
type: 'string',
default: '',
placeholder: 'Enter IP address',
},
{
displayName: 'Filter By Isolation Status',
name: 'isolationStatus',
type: 'multiOptions',
default: [],
options: [
{
name: 'Isolated',
value: 'isolated',
},
{
name: 'Not Isolated',
value: 'not_isolated',
},
],
},
{
displayName: 'Filter By Label',
name: 'label',
type: 'string',
default: '',
placeholder: 'Enter label',
},
{
displayName: 'Filter By Managed Status',
name: 'managedStatus',
type: 'multiOptions',
default: [],
options: [
{
name: 'Managed',
value: 'managed',
},
{
name: 'Unmanaged',
value: 'unmanaged',
},
],
},
{
displayName: 'Filter By Online Status',
name: 'onlineStatus',
type: 'multiOptions',
default: [],
options: [
{
name: 'Online',
value: 'online',
},
{
name: 'Offline',
value: 'offline',
},
],
},
{
displayName: 'Filter By Platform',
name: 'platform',
type: 'multiOptions',
default: [],
options: [
{
name: 'Windows',
value: 'windows',
},
{
name: 'macOS',
value: 'darwin',
},
{
name: 'Linux',
value: 'linux',
},
],
},
{
displayName: 'Filter By Search Term',
name: 'searchTerm',
type: 'string',
default: '',
placeholder: 'Enter search term',
},
{
displayName: 'Filter By Tags',
name: 'tags',
type: 'string',
default: '',
placeholder: 'tag1,tag2,tag3',
},
{
displayName: 'Page',
name: 'page',
type: 'number',
default: 1,
typeOptions: {
minValue: 1,
},
description: 'Page number to retrieve',
},
{
displayName: 'Page Size',
name: 'pageSize',
type: 'number',
default: 100,
typeOptions: {
minValue: 1,
maxValue: 1000,
},
description: 'Number of assets to return per page',
},
],
},
{
displayName: 'Tags',
name: 'tags',
type: 'string',
default: '',
placeholder: 'tag1,tag2,tag3',
displayOptions: {
show: {
resource: ['assets'],
operation: ['addTags', 'removeTags'],
},
},
required: true,
description: 'Tags to add or remove (comma-separated). Tags must contain only lowercase letters, numbers, hyphens, underscores, dots, backslashes, spaces, @, &, and colons.',
},
{
displayName: 'Organization',
name: 'organizationId',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select an organization...',
displayOptions: {
show: {
resource: ['assets'],
operation: ['addTags'],
},
},
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 number)',
},
},
],
placeholder: 'Enter organization ID',
},
{
displayName: 'By Name',
name: 'name',
type: 'string',
placeholder: 'Enter organization name',
},
],
required: true,
description: 'The organization to add tags for assets in (required for Add Tags operation)',
},
{
displayName: 'Organization',
name: 'organizationId',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select an organization...',
displayOptions: {
show: {
resource: ['assets'],
operation: ['removeTags'],
},
},
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 number)',
},
},
],
placeholder: 'Enter organization ID',
},
{
displayName: 'By Name',
name: 'name',
type: 'string',
placeholder: 'Enter organization name',
},
],
required: true,
description: 'The organization to remove tags from assets in (required for Remove Tags operation)',
},
{
displayName: 'Filter Options',
name: 'filterOptions',
type: 'collection',
placeholder: 'Add Filter',
default: {},
displayOptions: {
show: {
resource: ['assets'],
operation: ['addTags', 'removeTags'],
},
},
options: [
{
displayName: 'Excluded Asset IDs',
name: 'excludedEndpointIds',
type: 'string',
default: '',
placeholder: 'asset1,asset2,asset3',
description: 'Specific asset IDs to exclude (comma-separated)',
},
{
displayName: 'Filter By Asset Name',
name: 'name',
type: 'string',
default: '',
placeholder: 'Enter asset name',
},
{
displayName: 'Filter By IP Address',
name: 'ipAddress',
type: 'string',
default: '',
placeholder: 'Enter IP address',
},
{
displayName: 'Filter By Isolation Status',
name: 'isolationStatus',
type: 'multiOptions',
default: [],
options: [
{
name: 'Isolated',
value: 'isolated',
},
{
name: 'Not Isolated',
value: 'not_isolated',
},
],
},
{
displayName: 'Filter By Label',
name: 'label',
type: 'string',
default: '',
placeholder: 'Enter label',
},
{
displayName: 'Filter By Managed Status',
name: 'managedStatus',
type: 'multiOptions',
default: [],
options: [
{
name: 'Managed',
value: 'managed',
},
{
name: 'Unmanaged',
value: 'unmanaged',
},
],
},
{
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: 'list', value: '' },
placeholder: 'Select an organization...',
displayOptions: {
show: {
'/operation': ['removeTags'],
},
},
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 number)',
},
},
],
placeholder: 'Enter organization ID',
},
{
displayName: 'By Name',
name: 'name',
type: 'string',
placeholder: 'Enter organization name',
},
],
description: 'For Add Tags operation, use the organization field above instead',
},
{
displayName: 'Filter By Platform',
name: 'platform',
type: 'multiOptions',
default: [],
options: [
{
name: 'Windows',
value: 'windows',
},
{
name: 'macOS',
value: 'darwin',
},
{
name: 'Linux',
value: 'linux',
},
],
},
{
displayName: 'Filter By Search Term',
name: 'searchTerm',
type: 'string',
default: '',
placeholder: 'Enter search term',
},
{
displayName: 'Filter By Tags',
name: 'tags',
type: 'string',
default: '',
placeholder: 'tag1,tag2,tag3',
},
{
displayName: 'Included Asset IDs',
name: 'includedEndpointIds',
type: 'string',
default: '',
placeholder: 'asset1,asset2,asset3',
description: 'Specific asset IDs to include (comma-separated)',
},
],
},
{
displayName: 'Organization',
name: 'organizationId',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select an organization...',
displayOptions: {
show: {
resource: ['assets'],
operation: ['reboot'],
},
},
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 number)',
},
},
],
placeholder: 'Enter organization ID',
},
{
displayName: 'By Name',
name: 'name',
type: 'string',
placeholder: 'Enter organization name',
},
],
required: true,
description: 'The organization that contains the asset',
},
{
displayName: 'Asset',
name: 'assetId',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select an asset...',
displayOptions: {
show: {
resource: ['assets'],
operation: ['reboot'],
},
},
modes: [
{
displayName: 'From List',
name: 'list',
type: 'list',
placeholder: 'Select an asset...',
typeOptions: {
searchListMethod: 'getAssetsByOrganizationForDeviceActions',
searchable: true,
},
},
{
displayName: 'By ID',
name: 'id',
type: 'string',
validation: [
{
type: 'regex',
properties: {
regex: '^[a-zA-Z0-9-_]+$',
errorMessage: 'Not a valid asset ID (must contain only letters, numbers, hyphens, and underscores)',
},
},
],
placeholder: 'Enter asset ID',
},
],
required: true,
description: 'The asset to reboot',
},
{
displayName: 'Organization',
name: 'organizationId',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select an organization...',
displayOptions: {
show: {
resource: ['assets'],
operation: ['shutdown'],
},
},
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 number)',
},
},
],
placeholder: 'Enter organization ID',
},
{
displayName: 'By Name',
name: 'name',
type: 'string',
placeholder: 'Enter organization name',
},
],
required: true,
description: 'The organization that contains the asset',
},
{
displayName: 'Asset',
name: 'assetId',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select an asset...',
displayOptions: {
show: {
resource: ['assets'],
operation: ['shutdown'],
},
},
modes: [
{
displayName: 'From List',
name: 'list',
type: 'list',
placeholder: 'Select an asset...',
typeOptions: {
searchListMethod: 'getAssetsByOrganizationForDeviceActions',
searchable: true,
},
},
{
displayName: 'By ID',
name: 'id',
type: 'string',
validation: [
{
type: 'regex',
properties: {
regex: '^[a-zA-Z0-9-_]+$',
errorMessage: 'Not a valid asset ID (must contain only letters, numbers, hyphens, and underscores)',
},
},
],
placeholder: 'Enter asset ID',
},
],
required: true,
description: 'The asset to shutdown',
},
{
displayName: 'Organization',
name: 'organizationId',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select an organization...',
displayOptions: {
show: {
resource: ['assets'],
operation: ['setIsolation'],
},
},
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 number)',
},
},
],
placeholder: 'Enter organization ID',
},
{
displayName: 'By Name',
name: 'name',
type: 'string',
placeholder: 'Enter organization name',
},
],
required: true,
description: 'The organization that contains the asset',
},
{
displayName: 'Asset',
name: 'assetId',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select an asset...',
displayOptions: {
show: {
resource: ['assets'],
operation: ['setIsolation'],
},
},
modes: [
{
displayName: 'From List',
name: 'list',
type: 'list',
placeholder: 'Select an asset...',
typeOptions: {
searchListMethod: 'getAssetsByOrganizationForDeviceActions',
searchable: true,
},
},
{
displayName: 'By ID',
name: 'id',
type: 'string',
validation: [
{
type: 'regex',
properties: {
regex: '^[a-zA-Z0-9-_]+$',
errorMessage: 'Not a valid asset ID (must contain only letters, numbers, hyphens, and underscores)',
},
},
],
placeholder: 'Enter asset ID',
},
],
required: true,
description: 'The asset to assign isolation task to',
},
{
displayName: 'Isolation Enabled',
name: 'isolationEnabled',
type: 'boolean',
default: true,
displayOptions: {
show: {
resource: ['assets'],
operation: ['setIsolation'],
},
},
required: true,
description: 'Whether to enable or disable isolation on the selected assets',
},
];
function extractAssetId(asset) {
return (0, helpers_1.extractEntityId)(asset, 'asset');
}
function isValidAsset(asset) {
return (0, helpers_1.isValidEntity)(asset, ['name', 'ipAddress']);
}
async function fetchAllAssets(context, credentials, organizationId = '0', searchFilter, pageSize = 100) {
var _a;
try {
const queryParams = {
'pageSize': pageSize,
};
if (searchFilter) {
queryParams['filter[searchTerm]'] = searchFilter;
}
const responseData = await assets_1.api.getAssets(context, credentials, organizationId, queryParams);
return ((_a = responseData.result) === null || _a === void 0 ? void 0 : _a.entities) || [];
}
catch (error) {
throw (0, helpers_1.catchAndFormatError)(error, 'fetching assets');
}
}
function buildAssetQueryParams(organizationIds, additionalFields) {
const queryParams = {
'filter[organizationIds]': organizationIds,
};
if (additionalFields.searchTerm) {
queryParams['filter[searchTerm]'] = additionalFields.searchTerm;
}
if (additionalFields.name) {
queryParams['filter[name]'] = additionalFields.name;
}
if (additionalFields.ipAddress) {
queryParams['filter[ipAddress]'] = additionalFields.ipAddress;
}
if (additionalFields.label) {
queryParams['filter[label]'] = additionalFields.label;
}
if (additionalFields.platform && additionalFields.platform.length > 0) {
queryParams['filter[platform]'] = Array.isArray(additionalFields.platform)
? additionalFields.platform.join(',')
: additionalFields.platform;
}
if (additionalFields.onlineStatus && additionalFields.onlineStatus.length > 0) {
queryParams['filter[onlineStatus]'] = Array.isArray(additionalFields.onlineStatus)
? additionalFields.onlineStatus.join(',')
: additionalFields.onlineStatus;
}
if (additionalFields.managedStatus && additionalFields.managedStatus.length > 0) {
queryParams['filter[managedStatus]'] = Array.isArray(additionalFields.managedStatus)
? additionalFields.managedStatus.join(',')
: additionalFields.managedStatus;
}
if (additionalFields.isolationStatus && additionalFields.isolationStatus.length > 0) {
queryParams['filter[isolationStatus]'] = Array.isArray(additionalFields.isolationStatus)
? additionalFields.isolationStatus.join(',')
: additionalFields.isolationStatus;
}
if (additionalFields.tags) {
queryParams['filter[tags]'] = additionalFields.tags;
}
if (additionalFields.pageSize) {
queryParams['pageSize'] = additionalFields.pageSize;
}
if (additionalFields.page) {
queryParams['page'] = additionalFields.page;
}
return queryParams;
}
function buildAssetFilter(filterOptions) {
const filter = {};
if (filterOptions.searchTerm) {
filter.searchTerm = filterOptions.searchTerm;
}
if (filterOptions.name) {
filter.name = filterOptions.name;
}
if (filterOptions.ipAddress) {
filter.ipAddress = filterOptions.ipAddress;
}
if (filterOptions.label) {
filter.label = filterOptions.label;
}
if (filterOptions.platform && filterOptions.platform.length > 0) {
filter.platform = filterOptions.platform;
}
if (filterOptions.onlineStatus && filterOptions.onlineStatus.length > 0) {
filter.onlineStatus = filterOptions.onlineStatus;
}
if (filterOptions.managedStatus && filterOptions.managedStatus.length > 0) {
filter.managedStatus = filterOptions.managedStatus;
}
if (filterOptions.isolationStatus && filterOptions.isolationStatus.length > 0) {
filter.isolationStatus = filterOptions.isolationStatus;
}
if (filterOptions.tags) {
filter.tags = filterOptions.tags.split(',').map((tag) => tag.trim()).filter((tag) => tag.length > 0);
}
if (filterOptions.includedEndpointIds) {
filter.includedEndpointIds = filterOptions.includedEndpointIds.split(',').map((id) => id.trim()).filter((id) => id.length > 0);
}
if (filterOptions.excludedEndpointIds) {
filter.excludedEndpointIds = filterOptions.excludedEndpointIds.split(',').map((id) => id.trim()).filter((id) => id.length > 0);
}
if (filterOptions.organizationId) {
const organizationResource = filterOptions.organizationId;
if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
const orgIdNumber = parseInt(organizationResource.value, 10);
if (!isNaN(orgIdNumber)) {
filter.organizationIds = [orgIdNumber];
}
}
else if (organizationResource.mode === 'name') {
filter.organizationName = organizationResource.value;
}
}
return filter;
}
function validateTags(tags) {
const tagRegex = /^[a-z\d\-_.\\\s@&:]+$/i;
const invalidTags = tags.filter(tag => !tagRegex.test(tag));
return {
valid: invalidTags.length === 0,
invalidTags
};
}
async function getAssets(searchTerm) {
try {
const credentials = await (0, helpers_1.getAirCredentials)(this);
const assets = await fetchAllAssets(this, credentials, '0', searchTerm);
return (0, helpers_1.createListSearchResults)(assets, isValidAsset, (asset) => ({
name: `${asset.name} (${asset.ipAddress})`,
value: extractAssetId(asset),
}), searchTerm);
}
catch (error) {
throw (0, helpers_1.catchAndFormatError)(error, 'loading assets');
}
}
async function getAssetsByOrganizationForDeviceActions(searchTerm) {
try {
const credentials = await (0, helpers_1.getAirCredentials)(this);
let organizationId = '0';
try {
const currentParams = this.getCurrentNodeParameters();
if (currentParams && currentParams.organizationId) {
const orgResource = currentParams.organizationId;
if (typeof orgResource === 'object') {
if (orgResource.mode === 'id' || orgResource.mode === 'list') {
organizationId = orgResource.value || '0';
}
}
else if (typeof orgResource === 'string') {
organizationId = orgResource;
}
}
}
catch (error) {
}
const assets = await fetchAllAssets(this, credentials, organizationId, searchTerm);
return (0, helpers_1.createListSearchResults)(assets, isValidAsset, (asset) => ({
name: `${asset.name} (${asset.ipAddress})`,
value: extractAssetId(asset),
}), searchTerm);
}
catch (error) {
throw (0, helpers_1.catchAndFormatError)(error, 'loading assets');
}
}
async function getAssetsOptions() {
try {
const credentials = await (0, helpers_1.getAirCredentials)(this);
const assets = await fetchAllAssets(this, credentials);
return (0, helpers_1.createLoadOptions)(assets, isValidAsset, (asset) => ({
name: `${asset.name} (${asset.ipAddress})`,
value: extractAssetId(asset),
}));
}
catch (error) {
throw (0, helpers_1.catchAndFormatError)(error, 'loading assets');
}
}
async function executeAssets() {
var _a, _b;
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);
const organizationResource = this.getNodeParameter('organizationId', i);
let organizationId;
if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
organizationId = organizationResource.value;
}
else if (organizationResource.mode === 'name') {
try {
organizationId = 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)(organizationId, 'Organization ID');
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
itemIndex: i,
});
}
const queryParams = buildAssetQueryParams(organizationId, additionalFields);
const responseData = await assets_1.api.getAssets(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 assetResource = this.getNodeParameter('assetId', i);
let assetId;
if (assetResource.mode === 'list' || assetResource.mode === 'id') {
assetId = assetResource.value;
}
else {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid asset selection mode', {
itemIndex: i,
});
}
try {
assetId = (0, helpers_1.normalizeAndValidateId)(assetId, 'Asset ID');
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
itemIndex: i,
});
}
const responseData = await assets_1.api.getAssetById(this, credentials, assetId);
returnData.push({
json: responseData.result,
pairedItem: i,
});
break;
}
case 'getAssetTasks': {
const assetResource = this.getNodeParameter('assetId', i);
let assetId;
if (assetResource.mode === 'list' || assetResource.mode === 'id') {
assetId = assetResource.value;
}
else {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid asset selection mode', {
itemIndex: i,
});
}
try {
assetId = (0, helpers_1.normalizeAndValidateId)(assetId, 'Asset ID');
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
itemIndex: i,
});
}
const responseData = await assets_1.api.getAssetTasks(this, credentials, assetId);
const entities = ((_b = responseData.result) === null || _b === void 0 ? void 0 : _b.entities) || [];
if (entities.length > 0) {
entities.forEach((task) => {
returnData.push({
json: task,
pairedItem: i,
});
});
}
else {
returnData.push({
json: {},
pairedItem: i,
});
}
break;
}
case 'addTags': {
const tagsString = this.getNodeParameter('tags', i);
const organizationResource = this.getNodeParameter('organizationId', i);
const filterOptions = this.getNodeParameter('filterOptions', i);
const tags = tagsString.split(',').map((tag) => tag.trim()).filter((tag) => tag.length > 0);
if (tags.length === 0) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'At least one tag must be provided', {
itemIndex: i,
});
}
const validation = validateTags(tags);
if (!validation.valid) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid tag format for: ${validation.invalidTags.join(', ')}. Tags must contain only lowercase letters, numbers, hyphens, underscores, dots, backslashes, spaces, @, &, and colons.`, { itemIndex: i });
}
let organizationId;
if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
organizationId = organizationResource.value;
}
else if (organizationResource.mode === 'name') {
try {
organizationId = 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)(organizationId, 'Organization ID');
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, { itemIndex: i });
}
const orgIdNumber = parseInt(organizationId, 10);
if (isNaN(orgIdNumber)) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Organization ID must be a valid number', {
itemIndex: i,
});
}
const filter = buildAssetFilter(filterOptions);
if (filter.organizationName) {
try {
const orgId = await (0, organizations_1.findOrganizationByName)(this, credentials, filter.organizationName);
const resolvedOrgIdNumber = parseInt(orgId, 10);
if (!isNaN(resolvedOrgIdNumber)) {
filter.organizationIds = [resolvedOrgIdNumber];
}
delete filter.organizationName;
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, { itemIndex: i });
}
}
filter.organizationIds = [orgIdNumber];
const requestData = {
tags,
filter,
};
const responseData = await assets_1.api.addTagsToAssets(this, credentials, requestData);
returnData.push({
json: responseData,
pairedItem: i,
});
break;
}
case 'removeTags': {
const tagsString = this.getNodeParameter('tags', i);
const organizationResource = this.getNodeParameter('organizationId', i);
const filterOptions = this.getNodeParameter('filterOptions', i);
const tags = tagsString.split(',').map((tag) => tag.trim()).filter((tag) => tag.length > 0);
if (tags.length === 0) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'At least one tag must be provided', {
itemIndex: i,
});
}
const validation = validateTags(tags);
if (!validation.valid) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid tag format for: ${validation.invalidTags.join(', ')}. Tags must contain only lowercase letters, numbers, hyphens, underscores, dots, backslashes, spaces, @, &, and colons.`, { itemIndex: i });
}
let organizationId;
if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
organizationId = organizationResource.value;
}
else if (organizationResource.mode === 'name') {
try {
organizationId = 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)(organizationId, 'Organization ID');
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, { itemIndex: i });
}
const orgIdNumber = parseInt(organizationId, 10);
if (isNaN(orgIdNumber)) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Organization ID must be a valid number', {
itemIndex: i,
});
}
const filter = buildAssetFilter(filterOptions);
if (filter.organizationName) {
try {
const orgId = await (0, organizations_1.findOrganizationByName)(this, credentials, filter.organizationName);
const resolvedOrgIdNumber = parseInt(orgId, 10);
if (!isNaN(resolvedOrgIdNumber)) {
filter.organizationIds = [resolvedOrgIdNumber];
}
delete filter.organizationName;
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, { itemIndex: i });
}
}
filter.organizationIds = [orgIdNumber];
const requestData = {
tags,
filter,
};
const responseData = await assets_1.api.removeTagsFromAssets(this, credentials, requestData);
returnData.push({
json: responseData,
pairedItem: i,
});
break;
}
case 'reboot': {
const organizationResource = this.getNodeParameter('organizationId', i);
const assetResource = this.getNodeParameter('assetId', i);
let organizationId;
if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
organizationId = organizationResource.value;
}
else if (organizationResource.mode === 'name') {
try {
organizationId = 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)(organizationId, 'Organization ID');
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, { itemIndex: i });
}
const orgIdNumber = parseInt(organizationId, 10);
if (isNaN(orgIdNumber)) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Organization ID must be a valid number', {
itemIndex: i,
});
}
let assetId;
if (assetResource.mode === 'list' || assetResource.mode === 'id') {
assetId = assetResource.value;
}
else {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid asset selection mode', {
itemIndex: i,
});
}
try {
assetId = (0, helpers_1.normalizeAndValidateId)(assetId, 'Asset ID');
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
itemIndex: i,
});
}
let asset = null;
let assetFetchError = null;
try {
const assetResponse = await assets_1.api.getAssetById(this, credentials, assetId);
if (assetResponse.result) {
asset = assetResponse.result;
}
}
catch (error) {
assetFetchError = error.message || 'Failed to fetch asset details';
console.error(`Error fetching asset details: ${assetFetchError}`);
}
const existingTask = await checkExistingTask(this, credentials, assetId, 'reboot');
if (existingTask) {
returnData.push({
json: {
success: true,
message: 'Reboot task already assigned and waiting to be processed',
asset: asset,
task: existingTask,
error: assetFetchError,
},
pairedItem: i,
});
}
else {
const filter = {
organizationIds: [orgIdNumber],
includedEndpointIds: [assetId],
};
const requestData = {
filter,
};
try {
const responseData = await assets_1.api.rebootAssets(this, credentials, requestData);
if (responseData.result && responseData.result.length > 0) {
const newTask = responseData.result[0];
returnData.push({
json: {
success: true,
message: 'Reboot task created successfully',
asset: asset,
task: newTask,
error: assetFetchError,
},
pairedItem: i,
});
}
else {
returnData.push({
json: {
success: false,
message: 'Failed to create reboot task',
asset: asset,
task: null,
error: assetFetchError || 'No tasks were created by the server',
},
pairedItem: i,
});
}
}
catch (error) {
returnData.push({
json: {
success: false,
message: 'Failed to create reboot task',
asset: asset,
task: null,
error: error.message || 'Unknown error occurred',
},
pairedItem: i,
});
}
}
break;
}
case 'shutdown': {
const organizationResource = this.getNodeParameter('organizationId', i);
const assetResource = this.getNodeParameter('assetId', i);
let organizationId;
if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
organizationId = organizationResource.value;
}
else if (organizationResource.mode === 'name') {
try {
organizationId = 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)(organizationId, 'Organization ID');
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, { itemIndex: i });
}
const orgIdNumber = parseInt(organizationId, 10);
if (isNaN(orgIdNumber)) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Organization ID must be a valid number', {
itemIndex: i,
});
}
let assetId;
if (assetResource.mode === 'list' || assetResource.mode === 'id') {
assetId = assetResource.value;
}
else {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid asset selection mode', {
itemIndex: i,
});
}
try {
assetId = (0, helpers_1.normalizeAndValidateId)(assetId, 'Asset ID');
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
itemIndex: i,
});
}
let asset = null;
let assetFetchError = null;
try {
const assetResponse = await assets_1.api.getAssetById(this, credentials, assetId);
if (assetResponse.result) {
asset = assetResponse.result;
}
}
catch (error) {
assetFetchError = error.message || 'Failed to fetch asset details';
console.error(`Error fetching asset details: ${assetFetchError}`);
}
const existingTask = await checkExistingTask(this, credentials, assetId, 'shutdown');
if (existingTask) {
returnData.push({
json: {
success: true,
message: 'Shutdown task already assigned and waiting to be processed',
asset: asset,
task: existingTask,
error: assetFetchError,
},
pairedItem: i,
});
}
else {
const filter = {
organizationIds: [orgIdNumber],
includedEndpointIds: [assetId],
};
const requestData = {
filter,
};
try {
const responseData = await assets_1.api.shutdownAssets(this, credentials, requestData);
if (responseData.result && responseData.result.length > 0) {
const newTask = responseData.result[0];
returnData.push({
json: {
success: true,
message: 'Shutdown task created successfully',
asset: asset,
task: newTask,
error: assetFetchError,
},
pairedItem: i,
});
}
else {
returnData.push({
json: {
success: false,
message: 'Failed to create shutdown task',
asset: asset,
task: null,
error: assetFetchError || 'No tasks were created by the server',
},
pairedItem: i,
});
}
}
catch (error) {
returnData.push({
json: {
success: false,
message: 'Failed to create shutdown task',
asset: asset,
task: null,
error: error.message || 'Unknown error occurred',
},
pairedItem: i,
});
}
}
break;
}
case 'setIsolation': {
const organizationResource = this.getNodeParameter('organizationId', i);
const assetResource = this.getNodeParameter('assetId', i);
const isolationEnabled = this.getNodeParameter('isolationEnabled', i);
let organizationId;
if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
organizationId = organizationResource.value;
}
else if (organizationResource.mode === 'name') {
try {
organizationId = 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)(organizationId, 'Organization ID');
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, { itemIndex: i });
}
const orgIdNumber = parseInt(organizationId, 10);
if (isNaN(orgIdNumber)) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Organization ID must be a valid number', {
itemIndex: i,
});
}
let assetId;
if (assetResource.mode === 'list' || assetResource.mode === 'id') {
assetId = assetResource.value;
}
else {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid asset selection mode', {
itemIndex: i,
});
}
try {
assetId = (0, helpers_1.normalizeAndValidateId)(assetId, 'Asset ID');
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, {
itemIndex: i,
});
}
let asset = null;
let assetFetchError = null;
try {
const assetResponse = await assets_1.api.getAssetById(this, credentials, assetId);
if (assetResponse.result) {
asset = assetResponse.result;
}
}
catch (error) {
assetFetchError = error.message || 'Failed to fetch asset details';
console.error(`Error fetching asset details: ${assetFetchError}`);
}
const existingTask = await checkExistingTask(this, credentials, assetId, 'isolation');
if (existingTask) {
returnData.push({
json: {
success: true,
message: `Isolation task already assigned and waiting to be processed`,
asset: asset,
task: existingTask,
error: assetFetchError,
},
pairedItem: i,
});
}
else if (asset) {
const currentlyIsolated = asset.isolationStatus === 'isolated';
if (currentlyIsolated === isolationEnabled) {
returnData.push({
json: {
success: true,
message: `Asset is already ${isolationEnabled ? 'isolated' : 'unisolated'}`,
asset: asset,
task: null,
error: null,
},
pairedItem: i,
});
}
else {
const filter = {
organizationIds: [orgIdNumber],
includedEndpointIds: [assetId],
};
const requestData = {
enabled: isolationEnabled,
filter,
};
try {
const responseData = await assets_1.api.setIsolationOnAssets(this, credentials, requestData);
if (responseData.result && responseData.result.length > 0) {
const newTask = responseData.result[0];
returnData.push({
json: {
success: true,
message: `Isolation task created to ${isolationEnabled ? 'isolate' : 'unisolate'} the asset`,
asset: asset,
task: newTask,
error: null,
},
pairedItem: i,
});
}
else {
returnData.push({
json: {
success: false,
message: 'Failed to create isolation task',
asset: asset,
task: null,
error: 'No tasks were created by the server',
},
pairedItem: i,
});
}
}
catch (error) {
returnData.push({
json: {
success: false,
message: 'Failed to create isolation task',
asset: asset,
task: null,
error: error.message || 'Unknown error occurred',
},
pairedItem: i,
});
}
}
}
else {
const filter = {
organizationIds: [orgIdNumber],
includedEndpointIds: [assetId],
};
const requestData = {
enabled: isolationEnabled,
filter,
};
try {
const responseData = await assets_1.api.setIsolationOnAssets(this, credentials, requestData);
if (responseData.result && responseData.result.length > 0) {
const newTask = responseData.result[0];
returnData.push({
json: {
success: true,
message: `Isolation task created to ${isolationEnabled ? 'isolate' : 'unisolate'} the asset`,
asset: null,
task: newTask,
error: assetFetchError,
},
pairedItem: i,
});
}
else {
returnData.push({
json: {
success: false,
message: 'Failed to create isolation task',
asset: null,
task: null,
error: assetFetchError || 'No tasks were created by the server',
},
pairedItem: i,
});
}
}
catch (error) {
returnData.push({
json: {
success: false,
message: 'Failed to create isolation task',
asset: null,
task: null,
error: error.message || 'Unknown error occurred',
},
pairedItem: i,
});
}
}
break;
}
default:
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The operation "${operation}" is not supported`, {
itemIndex: i,
});
}
}
catch (error) {
(0, helpers_1.handleExecuteError)(this, error, i, returnData);
}
}
return [returnData];
}
//# sourceMappingURL=assets.js.map