n8n-nodes-nessus
Version:
n8n community node for Tenable Nessus vulnerability scanner integration
268 lines • 11.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NessusApi = void 0;
const n8n_workflow_1 = require("n8n-workflow");
class NessusApi {
constructor(executeFunctions) {
this.executeFunctions = executeFunctions;
}
async makeRequest(options) {
const { method, endpoint, body, params } = options;
const credentials = await this.executeFunctions.getCredentials('nessusApi');
const url = credentials.url;
const accessKey = credentials.accessKey;
const secretKey = credentials.secretKey;
const allowUnauthorizedCerts = credentials.allowUnauthorizedCerts;
const requestOptions = {
headers: {
'X-ApiKeys': `accessKey=${accessKey}; secretKey=${secretKey}`,
'Content-Type': 'application/json',
},
method,
uri: `${url}${endpoint}`,
json: true,
rejectUnauthorized: !allowUnauthorizedCerts,
};
if (body) {
requestOptions.body = body;
}
if (params) {
requestOptions.qs = params;
}
try {
return await this.executeFunctions.helpers.request(requestOptions);
}
catch (error) {
const errorMessage = this.parseNessusError(error);
throw new n8n_workflow_1.NodeApiError(this.executeFunctions.getNode(), {
message: errorMessage,
originalError: error,
httpCode: error.statusCode,
});
}
}
parseNessusError(error) {
var _a, _b;
if ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.error) {
return `Nessus API Error: ${error.response.body.error}`;
}
switch (error.statusCode) {
case 400:
return 'Bad Request: Invalid parameters provided';
case 401:
return 'Unauthorized: Invalid API keys or session expired';
case 403:
return 'Forbidden: Insufficient permissions';
case 404:
return 'Not Found: The requested resource does not exist';
case 409:
return 'Conflict: Resource already exists or is in use';
case 429:
return 'Rate Limited: Too many requests, please try again later';
case 500:
return 'Internal Server Error: Nessus server error';
case 503:
return 'Service Unavailable: Nessus server is temporarily unavailable';
default:
return error.message || 'Unknown error occurred';
}
}
buildPaginationParams(options) {
const params = {};
if (options === null || options === void 0 ? void 0 : options.limit) {
params.limit = options.limit;
}
if (options === null || options === void 0 ? void 0 : options.offset) {
params.offset = options.offset;
}
if (options === null || options === void 0 ? void 0 : options.sort) {
params.sort = options.sort;
}
if (options === null || options === void 0 ? void 0 : options.order) {
params.order = options.order;
}
return params;
}
async listScans(paginationOptions) {
const params = this.buildPaginationParams(paginationOptions);
return await this.makeRequest({ method: 'GET', endpoint: '/scans', params });
}
async getScanDetails(scanId) {
this.validateId(scanId, 'Scan ID');
return await this.makeRequest({ method: 'GET', endpoint: `/scans/${scanId}` });
}
async createScan(scanData) {
this.validateScanData(scanData);
return await this.makeRequest({ method: 'POST', endpoint: '/scans', body: scanData });
}
async launchScan(scanId, altTargets) {
this.validateId(scanId, 'Scan ID');
const body = altTargets ? { alt_targets: altTargets } : {};
return await this.makeRequest({ method: 'POST', endpoint: `/scans/${scanId}/launch`, body });
}
async stopScan(scanId) {
this.validateId(scanId, 'Scan ID');
return await this.makeRequest({ method: 'POST', endpoint: `/scans/${scanId}/stop` });
}
async pauseScan(scanId) {
this.validateId(scanId, 'Scan ID');
return await this.makeRequest({ method: 'POST', endpoint: `/scans/${scanId}/pause` });
}
async resumeScan(scanId) {
this.validateId(scanId, 'Scan ID');
return await this.makeRequest({ method: 'POST', endpoint: `/scans/${scanId}/resume` });
}
async deleteScan(scanId) {
this.validateId(scanId, 'Scan ID');
return await this.makeRequest({ method: 'DELETE', endpoint: `/scans/${scanId}` });
}
async exportScan(scanId, format, historyId) {
this.validateId(scanId, 'Scan ID');
this.validateExportFormat(format);
const body = { format };
if (historyId) {
body.history_id = historyId;
}
return await this.makeRequest({ method: 'POST', endpoint: `/scans/${scanId}/export`, body });
}
async getScanExportStatus(scanId, fileId) {
this.validateId(scanId, 'Scan ID');
this.validateId(fileId, 'File ID');
return await this.makeRequest({ method: 'GET', endpoint: `/scans/${scanId}/export/${fileId}/status` });
}
async downloadScanExport(scanId, fileId) {
this.validateId(scanId, 'Scan ID');
this.validateId(fileId, 'File ID');
return await this.makeRequest({ method: 'GET', endpoint: `/scans/${scanId}/export/${fileId}/download` });
}
async copyScan(scanId, folderId, name) {
this.validateId(scanId, 'Scan ID');
const body = {};
if (folderId)
body.folder_id = folderId;
if (name)
body.name = name;
return await this.makeRequest({ method: 'POST', endpoint: `/scans/${scanId}/copy`, body });
}
async listPolicies(paginationOptions) {
const params = this.buildPaginationParams(paginationOptions);
const response = await this.makeRequest({ method: 'GET', endpoint: '/policies', params });
return response.policies;
}
async getPolicyDetails(policyId) {
this.validateId(policyId, 'Policy ID');
return await this.makeRequest({ method: 'GET', endpoint: `/policies/${policyId}` });
}
async createPolicy(policyData) {
this.validatePolicyData(policyData);
return await this.makeRequest({ method: 'POST', endpoint: '/policies', body: policyData });
}
async updatePolicy(policyId, policyData) {
this.validateId(policyId, 'Policy ID');
this.validatePolicyData(policyData);
return await this.makeRequest({ method: 'PUT', endpoint: `/policies/${policyId}`, body: policyData });
}
async deletePolicy(policyId) {
this.validateId(policyId, 'Policy ID');
return await this.makeRequest({ method: 'DELETE', endpoint: `/policies/${policyId}` });
}
async copyPolicy(policyId) {
this.validateId(policyId, 'Policy ID');
return await this.makeRequest({ method: 'POST', endpoint: `/policies/${policyId}/copy` });
}
async listFolders() {
const response = await this.makeRequest({ method: 'GET', endpoint: '/folders' });
return response.folders;
}
async createFolder(name) {
this.validateFolderName(name);
return await this.makeRequest({ method: 'POST', endpoint: '/folders', body: { name } });
}
async deleteFolder(folderId) {
this.validateId(folderId, 'Folder ID');
return await this.makeRequest({ method: 'DELETE', endpoint: `/folders/${folderId}` });
}
async listPluginFamilies(paginationOptions) {
const params = this.buildPaginationParams(paginationOptions);
const response = await this.makeRequest({ method: 'GET', endpoint: '/plugins/families', params });
return response.families;
}
async listPluginsInFamily(familyId, paginationOptions) {
this.validateId(familyId, 'Family ID');
const params = this.buildPaginationParams(paginationOptions);
const response = await this.makeRequest({ method: 'GET', endpoint: `/plugins/families/${familyId}`, params });
return response.plugins;
}
async getPluginDetails(pluginId) {
this.validateId(pluginId, 'Plugin ID');
return await this.makeRequest({ method: 'GET', endpoint: `/plugins/plugin/${pluginId}` });
}
async getSessionDetails() {
return await this.makeRequest({ method: 'GET', endpoint: '/session' });
}
async editSession(sessionData) {
return await this.makeRequest({ method: 'PUT', endpoint: '/session', body: sessionData });
}
async listScanTemplates() {
return await this.makeRequest({ method: 'GET', endpoint: '/editor/scan/templates' });
}
async listPolicyTemplates() {
return await this.makeRequest({ method: 'GET', endpoint: '/editor/policy/templates' });
}
validateId(id, fieldName) {
if (!id || id <= 0) {
throw new Error(`${fieldName} must be a positive integer`);
}
}
validateScanData(scanData) {
if (!scanData.uuid) {
throw new Error('Policy UUID is required for scan creation');
}
if (!scanData.settings) {
throw new Error('Scan settings are required');
}
const settings = scanData.settings;
if (!settings.name) {
throw new Error('Scan name is required');
}
if (!settings.text_targets) {
throw new Error('Target list is required');
}
}
validatePolicyData(policyData) {
if (!policyData.uuid) {
const settings = policyData.settings;
if (!(settings === null || settings === void 0 ? void 0 : settings.name)) {
throw new Error('Policy UUID or name is required');
}
}
}
validateFolderName(name) {
if (!name || name.trim().length === 0) {
throw new Error('Folder name cannot be empty');
}
if (name.length > 255) {
throw new Error('Folder name cannot exceed 255 characters');
}
}
validateExportFormat(format) {
const validFormats = ['nessus', 'pdf', 'html', 'csv', 'db'];
if (!validFormats.includes(format.toLowerCase())) {
throw new Error(`Invalid export format. Valid formats: ${validFormats.join(', ')}`);
}
}
async deleteManyScans(scanIds) {
if (!scanIds || scanIds.length === 0) {
throw new Error('Scan IDs array cannot be empty');
}
return await this.makeRequest({ method: 'DELETE', endpoint: '/scans', body: { ids: scanIds } });
}
async deleteManyPolicies(policyIds) {
if (!policyIds || policyIds.length === 0) {
throw new Error('Policy IDs array cannot be empty');
}
return await this.makeRequest({ method: 'DELETE', endpoint: '/policies', body: { ids: policyIds } });
}
}
exports.NessusApi = NessusApi;
//# sourceMappingURL=NessusApi.js.map