n8n-nodes-binalyze-air
Version:
Binalyze AIR nodes for automating DFIR with n8n workflows
412 lines • 15.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAirCredentials = getAirCredentials;
exports.buildRequestOptions = buildRequestOptions;
exports.validateApiResponse = validateApiResponse;
exports.makeApiRequestWithErrorHandling = makeApiRequestWithErrorHandling;
exports.buildRequestOptionsWithErrorHandling = buildRequestOptionsWithErrorHandling;
exports.extractEntityId = extractEntityId;
exports.normalizeAndValidateId = normalizeAndValidateId;
exports.isValidEntity = isValidEntity;
exports.validateAndExtractOrganizationId = validateAndExtractOrganizationId;
exports.createListSearchResults = createListSearchResults;
exports.createLoadOptions = createLoadOptions;
exports.handleExecuteError = handleExecuteError;
exports.extractEntitiesFromResponse = extractEntitiesFromResponse;
exports.hasResponsePagination = hasResponsePagination;
exports.extractPaginationInfo = extractPaginationInfo;
exports.processApiResponseEntities = processApiResponseEntities;
exports.catchAndFormatError = catchAndFormatError;
const n8n_workflow_1 = require("n8n-workflow");
async function getAirCredentials(context) {
const credentials = await context.getCredentials('airApi');
if (!credentials) {
throw new Error('No credentials provided for Binalyze AIR');
}
const instanceUrl = credentials.instanceUrl;
const token = credentials.token;
if (!instanceUrl || !token) {
throw new Error('Missing instanceUrl or token in Binalyze AIR credentials');
}
const normalizedInstanceUrl = instanceUrl.replace(/\/+$/, '');
return {
instanceUrl: normalizedInstanceUrl,
token,
};
}
function buildRequestOptions(credentials, method, endpoint, queryParams) {
const options = {
method,
url: `${credentials.instanceUrl}${endpoint}`,
headers: {
'Authorization': `Bearer ${credentials.token}`,
'Accept': 'application/json',
'Content-Type': 'application/json',
},
json: true,
};
if (queryParams && Object.keys(queryParams).length > 0) {
options.qs = queryParams;
}
return options;
}
function validateApiResponse(responseData, context) {
var _a;
if (!responseData.success) {
const errorMessage = ((_a = responseData.errors) === null || _a === void 0 ? void 0 : _a.join(', ')) || 'API request failed';
const fullMessage = context ? `${context}: ${errorMessage}` : errorMessage;
throw new Error(fullMessage);
}
}
function handleApiError(context, error, operation, itemIndex) {
var _a;
let errorMessage = 'Unknown error occurred';
let statusCode = 500;
let errors = [];
let httpDetails = [];
if ((_a = error.response) === null || _a === void 0 ? void 0 : _a.data) {
const responseData = error.response.data;
statusCode = error.response.status || statusCode;
httpDetails.push(`HTTP Status: ${statusCode}`);
if (error.response.statusText) {
httpDetails.push(`Status Text: ${error.response.statusText}`);
}
if (responseData.message) {
if (Array.isArray(responseData.message)) {
errors = responseData.message;
errorMessage = errors.join(', ');
}
else {
errorMessage = responseData.message;
errors = [errorMessage];
}
}
else if (responseData.errors && Array.isArray(responseData.errors)) {
errors = responseData.errors;
errorMessage = errors.join(', ');
}
else if (responseData.error) {
errorMessage = responseData.error;
errors = [errorMessage];
if (responseData.error !== errorMessage) {
httpDetails.push(`Error Type: ${responseData.error}`);
}
}
else {
errorMessage = `API request failed with status ${statusCode}`;
errors = [errorMessage];
}
if (responseData.statusCode) {
httpDetails.push(`API Status Code: ${responseData.statusCode}`);
}
httpDetails.push(`Response Body: ${JSON.stringify(responseData, null, 2)}`);
}
else if (error.message) {
errorMessage = error.message;
errors = [errorMessage];
httpDetails.push(`Network/Connection Error: ${error.message}`);
}
const fullMessage = `Failed to ${operation}: ${errorMessage}`;
const allDetails = [...errors];
if (httpDetails.length > 0) {
allDetails.push('', 'HTTP Response Details:', ...httpDetails);
}
if (context && 'getNode' in context && itemIndex !== undefined) {
throw new n8n_workflow_1.NodeOperationError(context.getNode(), fullMessage, {
itemIndex,
description: allDetails.join('\n'),
});
}
else if (context && 'getNode' in context) {
throw new n8n_workflow_1.NodeOperationError(context.getNode(), fullMessage, {
description: allDetails.join('\n'),
});
}
else {
const detailedError = new Error(fullMessage);
detailedError.details = allDetails.join('\n');
throw detailedError;
}
}
async function makeApiRequestWithErrorHandling(context, requestOptions, operation, itemIndex) {
try {
const response = await context.helpers.httpRequest(requestOptions);
if (response && typeof response === 'object' && response.statusCode && response.statusCode >= 400) {
const httpError = {
response: {
status: response.statusCode,
statusText: response.error || 'HTTP Error',
data: response
}
};
handleApiError(context, httpError, operation, itemIndex);
}
if (response && typeof response === 'object' && 'success' in response) {
if (!response.success) {
const errors = response.errors || ['API request failed'];
const errorMessage = errors.join(', ');
const fullMessage = `Failed to ${operation}: ${errorMessage}`;
const responseDetails = [
'',
'API Response Details:',
`Success: ${response.success}`,
`Response Body: ${JSON.stringify(response, null, 2)}`
];
if (context && 'getNode' in context && itemIndex !== undefined) {
throw new n8n_workflow_1.NodeOperationError(context.getNode(), fullMessage, {
itemIndex,
description: [...errors, ...responseDetails].join('\n'),
});
}
else if (context && 'getNode' in context) {
throw new n8n_workflow_1.NodeOperationError(context.getNode(), fullMessage, {
description: [...errors, ...responseDetails].join('\n'),
});
}
else {
throw new Error(fullMessage);
}
}
}
else if (!response) {
const errorMessage = `Failed to ${operation}: No response data received`;
if (context && 'getNode' in context && itemIndex !== undefined) {
throw new n8n_workflow_1.NodeOperationError(context.getNode(), errorMessage, { itemIndex });
}
else if (context && 'getNode' in context) {
throw new n8n_workflow_1.NodeOperationError(context.getNode(), errorMessage);
}
else {
throw new Error(errorMessage);
}
}
return response;
}
catch (error) {
if (error instanceof n8n_workflow_1.NodeOperationError) {
throw error;
}
handleApiError(context, error, operation, itemIndex);
}
}
function buildRequestOptionsWithErrorHandling(credentials, method, endpoint, queryParams) {
const options = {
method,
url: `${credentials.instanceUrl}${endpoint}`,
headers: {
'Authorization': `Bearer ${credentials.token}`,
'Accept': 'application/json',
'Content-Type': 'application/json',
},
json: true,
ignoreHttpStatusErrors: true,
};
if (queryParams && Object.keys(queryParams).length > 0) {
options.qs = queryParams;
}
return options;
}
function extractEntityId(entity, entityType = 'entity') {
const entityId = entity._id || entity.id;
if (entityId === undefined || entityId === null || entityId === '') {
throw new Error(`${entityType.charAt(0).toUpperCase() + entityType.slice(1)} has no valid _id. ID value: ${entityId}, ID type: ${typeof entityId}. ` +
`Available fields: ${Object.keys(entity).join(', ')}`);
}
return String(entityId);
}
function normalizeId(id) {
if (id === null || id === undefined) {
return null;
}
const stringId = String(id).trim();
if (stringId === '') {
return null;
}
const numericId = Number(stringId);
if (!isNaN(numericId)) {
return stringId;
}
const guidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
if (guidPattern.test(stringId)) {
return stringId;
}
const alphanumericPattern = /^[a-zA-Z0-9-_]+$/;
if (alphanumericPattern.test(stringId)) {
return stringId;
}
return null;
}
function normalizeAndValidateId(id, fieldName = 'ID') {
const normalizedId = normalizeId(id);
if (normalizedId === null) {
throw new Error(`${fieldName} cannot be empty or invalid. Received: ${id} (type: ${typeof id})`);
}
return normalizedId;
}
function isValidEntity(entity, requiredFields = ['name']) {
if (!entity)
return false;
try {
extractEntityId(entity);
return requiredFields.every(field => !!entity[field]);
}
catch {
return false;
}
}
async function validateAndExtractOrganizationId(context, credentials, organizationResource, itemIndex, findOrganizationByNameFn) {
let organizationId;
if (organizationResource.mode === 'list' || organizationResource.mode === 'id') {
organizationId = organizationResource.value;
if (!organizationId || String(organizationId).trim() === '' || organizationId === '__search_hint__') {
throw new n8n_workflow_1.NodeOperationError(context.getNode(), 'Please select a valid organization from the list or enter a valid organization ID', {
itemIndex,
});
}
}
else if (organizationResource.mode === 'name') {
const organizationName = organizationResource.value;
if (!organizationName || String(organizationName).trim() === '') {
throw new n8n_workflow_1.NodeOperationError(context.getNode(), 'Please enter a valid organization name', {
itemIndex,
});
}
try {
organizationId = await findOrganizationByNameFn(context, credentials, organizationName);
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(context.getNode(), error.message, { itemIndex });
}
}
else {
throw new n8n_workflow_1.NodeOperationError(context.getNode(), 'Invalid organization selection mode', {
itemIndex,
});
}
try {
organizationId = normalizeAndValidateId(organizationId, 'Organization ID');
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(context.getNode(), error.message, {
itemIndex,
});
}
return organizationId;
}
function createListSearchResults(entities, validationFn, mapFn, filter) {
const results = entities
.filter(validationFn)
.map(mapFn)
.filter((item) => !filter ||
item.name.toLowerCase().includes(filter.toLowerCase()) ||
item.value === filter)
.sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()));
return { results };
}
function createLoadOptions(entities, validationFn, mapFn) {
return entities
.filter(validationFn)
.map(mapFn);
}
function handleExecuteError(context, error, itemIndex, returnData) {
if (context.continueOnFail()) {
let errorMessage = 'Unknown error occurred';
let errorDetails = undefined;
if (error) {
if (error instanceof Error) {
errorMessage = error.message;
if (error instanceof n8n_workflow_1.NodeOperationError) {
errorDetails = {
type: 'NodeOperationError',
cause: error.cause,
};
}
}
else if (typeof error === 'string') {
errorMessage = error;
}
else if (typeof error === 'object') {
errorMessage = error.message || error.error || JSON.stringify(error);
}
}
returnData.push({
json: {
error: errorMessage,
errorDetails: errorDetails,
},
pairedItem: itemIndex,
});
}
else {
if (!error) {
throw new n8n_workflow_1.NodeOperationError(context.getNode(), 'An unknown error occurred', {
itemIndex,
});
}
throw error instanceof n8n_workflow_1.NodeOperationError ? error : new n8n_workflow_1.NodeOperationError(context.getNode(), error, {
itemIndex,
});
}
}
function extractEntitiesFromResponse(responseData) {
if (!responseData.result) {
return [];
}
if (Array.isArray(responseData.result)) {
return responseData.result;
}
if (responseData.result.entities && Array.isArray(responseData.result.entities)) {
return responseData.result.entities;
}
return [];
}
function hasResponsePagination(responseData) {
if (!responseData.result || Array.isArray(responseData.result)) {
return false;
}
return responseData.result.totalEntityCount !== undefined;
}
function extractPaginationInfo(source) {
let result;
if (source && typeof source === 'object' && 'success' in source) {
result = source.result;
}
else {
result = source;
}
if (!result || Array.isArray(result)) {
return null;
}
if (result.totalEntityCount !== undefined) {
return {
totalEntityCount: result.totalEntityCount,
pageSize: result.pageSize,
currentPage: result.currentPage,
totalPageCount: result.totalPageCount,
};
}
return null;
}
function processApiResponseEntities(entities, returnData, itemIndex, options) {
entities.forEach((entity) => {
const jsonData = { ...entity };
if ((options === null || options === void 0 ? void 0 : options.includePagination) && options.paginationData) {
let paginationToInclude = { ...options.paginationData };
if (options.excludeFields) {
options.excludeFields.forEach(field => {
delete paginationToInclude[field];
});
}
jsonData._pagination = paginationToInclude;
}
returnData.push({
json: jsonData,
pairedItem: itemIndex,
});
});
}
function catchAndFormatError(error, operation) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
return new Error(`Failed to ${operation}: ${errorMessage}`);
}
//# sourceMappingURL=helpers.js.map