n8n-nodes-tenable-community
Version:
n8n node for the Tenable One platform
814 lines (813 loc) • 37.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TenableVMClient = void 0;
/**
* @file Client for interacting with the Tenable Vulnerability Management API.
* This file contains the TenableVMClient class, which is responsible for making all
* API requests to the Tenable Vulnerability Management (formerly Tenable.io) platform.
* It handles authentication, request signing, and provides well-defined methods
* for each API resource.
*/
const n8n_workflow_1 = require("n8n-workflow");
/**
* @class TenableVMClient
* @description Implements a robust client for the Tenable Vulnerability Management API.
* The methods are organized by API resource for clarity and maintainability.
*/
class TenableVMClient {
/**
* Creates an instance of the TenableVMClient.
* @param {ITriggerFunctions | IExecuteFunctions} context The n8n context object, used for accessing credentials and helpers.
*/
constructor(context) {
this.context = context;
}
/**
* A private helper method to send authenticated requests to the Tenable API.
* It automatically attaches API keys and handles base URL construction and error parsing.
* @private
* @param {IHttpRequestOptions} options - The request options, including method, URL, body, and query string.
* @returns {Promise<unknown>} A promise that resolves to the JSON response from the API.
* @throws {NodeApiError} When the API returns an error, it is wrapped in a standard n8n error for consistent handling.
*/
async sendRequest(options) {
var _a, _b, _c;
const credentials = await this.context.getCredentials('tenableOneApi');
const requestOptions = Object.assign(Object.assign({}, options), { headers: Object.assign(Object.assign({}, options.headers), { 'X-ApiKeys': `accessKey=${credentials.accessKey};secretKey=${credentials.secretKey}` }), json: true, url: `https://cloud.tenable.com/${options.url}`, timeout: 60000 });
try {
return await this.context.helpers.httpRequest(requestOptions);
}
catch (error) {
if (error instanceof n8n_workflow_1.NodeApiError) {
const errorDetails = error.cause ? (_a = error.cause.response) === null || _a === void 0 ? void 0 : _a.body : { message: error.message };
const errorMessage = ((_c = (_b = errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.errors) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.message) || (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.message) || 'No additional error details provided.';
throw new n8n_workflow_1.NodeApiError(this.context.getNode(), { message: `Tenable API Error: ${errorMessage}` });
}
throw new n8n_workflow_1.NodeApiError(this.context.getNode(), { message: error.message });
}
}
/**
* A generic handler for long-running export jobs (e.g., vulnerabilities, assets).
* This method encapsulates the standard "start, poll, download" logic for any
* export-style operation, making the client much more maintainable and scalable.
* @private
* @param {object} params Parameters for the export job.
* @param {string} params.startEndpoint The API endpoint to initiate the export.
* @param {string} params.statusEndpoint The base endpoint to check the status of the export.
* @param {string} params.downloadEndpoint The base endpoint to download the result chunks.
* @param {IDataObject} params.startBody The body of the request to initiate the export.
* @returns {Promise<IDataObject[]>} A promise that resolves to the combined list of items from all chunks.
* @throws {NodeOperationError} If the export job fails or times out.
*/
async handleLongRunningExport(params) {
const delay = (ms) => new Promise(res => setTimeout(res, ms));
const TIMEOUT_MS = 15 * 60 * 1000; // 15 minutes timeout
const startTime = Date.now();
const exportJob = await this.sendRequest({ method: 'POST', url: params.startEndpoint, body: params.startBody });
const exportUuid = exportJob.export_uuid;
if (!exportUuid) {
throw new n8n_workflow_1.NodeOperationError(this.context.getNode(), 'Tenable API did not return an export UUID to track.');
}
let statusResponse;
while (true) {
if (Date.now() - startTime > TIMEOUT_MS) {
throw new n8n_workflow_1.NodeOperationError(this.context.getNode(), `Tenable export job timed out after 15 minutes.`);
}
statusResponse = await this.sendRequest({ method: 'GET', url: `${params.statusEndpoint}/${exportUuid}/status` });
if (statusResponse.status === 'finished' || statusResponse.status === 'FINISHED') {
break;
}
if (statusResponse.status === 'error' || statusResponse.status === 'ERROR') {
throw new n8n_workflow_1.NodeOperationError(this.context.getNode(), `Tenable export job failed with status: ${statusResponse.status}.`);
}
await delay(5000);
}
const allItems = [];
if (statusResponse.chunks_available) {
for (const chunkId of statusResponse.chunks_available) {
const chunkData = await this.sendRequest({ method: 'GET', url: `${params.downloadEndpoint}/${exportUuid}/chunks/${chunkId}` });
if (Array.isArray(chunkData)) {
allItems.push(...chunkData);
}
}
}
return allItems;
}
// =================================================================
// ASSETS
// =================================================================
/**
* Retrieves a list of assets.
* @param {object} qs Query string parameters, e.g., for pagination.
* @returns {Promise<{ assets: ITenableAsset[], total: number }>} The list of assets.
*/
async listAssets(qs = {}) {
return this.sendRequest({ method: 'GET', url: 'assets', qs });
}
/**
* Retrieves details for a specific asset.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the asset.
* @returns {Promise<ITenableAsset>} The asset details.
*/
async getAssetDetails(params) {
return this.sendRequest({ method: 'GET', url: `assets/${params.id}` });
}
/**
* Retrieves information about a specific asset.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the asset.
* @returns {Promise<IDataObject>} The asset information.
*/
async getAssetInfo(params) {
return this.sendRequest({ method: 'GET', url: `assets/${params.id}/info` });
}
/**
* Retrieves tags for a specific asset.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the asset.
* @returns {Promise<IDataObject>} The asset tags.
*/
async getAssetTags(params) {
return this.sendRequest({ method: 'GET', url: `assets/${params.id}/tags` });
}
/**
* Imports assets into Tenable.
* @param {IDataObject} body The request body containing asset data.
* @returns {Promise<IDataObject>} The result of the import operation.
*/
async importAssets(body) {
return this.sendRequest({ method: 'POST', url: 'assets/import', body });
}
/**
* Retrieves the status of an asset import job.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the import job.
* @returns {Promise<IDataObject>} The import job status.
*/
async getImportJobStatus(params) {
return this.sendRequest({ method: 'GET', url: `assets/import/${params.id}/status` });
}
/**
* Performs a bulk deletion of assets.
* @param {IDataObject} body The request body containing the deletion query.
* @returns {Promise<IDataObject>} The result of the bulk delete operation.
*/
async bulkDeleteAssets(body) {
return this.sendRequest({ method: 'POST', url: 'assets/bulk-delete', body });
}
// =================================================================
// VULNERABILITIES & EXPORTS
// =================================================================
/**
* Initiates and manages a long-running vulnerability export job.
* @param {IDataObject} body The request body containing export filters.
* @returns {Promise<ITenableVulnerability[]>} A promise resolving to an array of all vulnerabilities.
*/
async exportVulnerabilities(body) {
return this.handleLongRunningExport({
startEndpoint: 'vulns/export',
statusEndpoint: 'vulns/export',
downloadEndpoint: 'vulns/export',
startBody: body,
});
}
/**
* Initiates and manages a long-running asset export job (v1 API).
* @param {IDataObject} body The request body containing export filters.
* @returns {Promise<ITenableAsset[]>} A promise resolving to an array of all assets.
*/
async exportAssetsV1(body) {
return this.handleLongRunningExport({
startEndpoint: 'assets/export',
statusEndpoint: 'assets/export',
downloadEndpoint: 'assets/export',
startBody: body,
});
}
/**
* Retrieves the status of an asset export job.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the export job.
* @returns {Promise<IDataObject>} The export job status.
*/
async getAssetsExportStatus(params) {
return this.sendRequest({ method: 'GET', url: `assets/export/${params.id}/status` });
}
/**
* Downloads a specific chunk of an asset export job.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the export job.
* @param {string} params.chunkId The ID of the chunk to download.
* @returns {Promise<ITenableAsset[]>} The data for the specified chunk.
*/
async downloadAssetsChunk(params) {
return this.sendRequest({ method: 'GET', url: `assets/export/${params.id}/chunks/${params.chunkId}` });
}
/**
* Cancels an in-progress asset export job.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the export job to cancel.
* @returns {Promise<IDataObject>} The cancellation status.
*/
async cancelAssetExport(params) {
return this.sendRequest({ method: 'POST', url: `assets/export/${params.id}/cancel` });
}
// =================================================================
// SCANS
// =================================================================
/**
* Retrieves a list of scans.
* @param {object} qs Query string parameters for filtering and pagination.
* @returns {Promise<ITenableScan[]>} The list of scans.
*/
async listScans(qs = {}) {
return this.sendRequest({ method: 'GET', url: 'scans', qs });
}
/**
* Creates a new scan configuration.
* @param {IDataObject} body The request body defining the new scan.
* @returns {Promise<ITenableScan>} The newly created scan object.
*/
async createScan(body) {
return this.sendRequest({ method: 'POST', url: 'scans', body });
}
/**
* Retrieves details for a specific scan.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the scan.
* @returns {Promise<ITenableScan>} The scan details.
*/
async getScanDetails(params) {
return this.sendRequest({ method: 'GET', url: `scans/${params.id}` });
}
/**
* Updates an existing scan configuration.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the scan to update.
* @param {IDataObject} params.body The data to update.
* @returns {Promise<IDataObject>} The updated scan object.
*/
async updateScan(params) {
return this.sendRequest({ method: 'PUT', url: `scans/${params.id}`, body: params.body });
}
/**
* Deletes a scan configuration.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the scan to delete.
* @returns {Promise<IDataObject>} An empty object on success.
*/
async deleteScan(params) {
return this.sendRequest({ method: 'DELETE', url: `scans/${params.id}` });
}
/**
* Launches a scan.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the scan to launch.
* @param {string[]} [params.alt_targets] An optional array of alternate targets to scan.
* @returns {Promise<ITenableScan>} The launch confirmation details.
*/
async launchScan(params) {
const body = params.alt_targets ? { alt_targets: params.alt_targets } : {};
return this.sendRequest({ method: 'POST', url: `scans/${params.id}/launch`, body });
}
/**
* Pauses a running scan.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the scan to pause.
* @returns {Promise<IDataObject>} An empty object on success.
*/
async pauseScan(params) {
return this.sendRequest({ method: 'POST', url: `scans/${params.id}/pause` });
}
/**
* Resumes a paused scan.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the scan to resume.
* @returns {Promise<IDataObject>} An empty object on success.
*/
async resumeScan(params) {
return this.sendRequest({ method: 'POST', url: `scans/${params.id}/resume` });
}
/**
* Stops a running scan.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the scan to stop.
* @returns {Promise<IDataObject>} An empty object on success.
*/
async stopScan(params) {
return this.sendRequest({ method: 'POST', url: `scans/${params.id}/stop` });
}
/**
* Force stops a scan that is stuck in a stopping or publishing state.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the scan to force-stop.
* @returns {Promise<IDataObject>} An empty object on success.
*/
async forceStopScan(params) {
return this.sendRequest({ method: 'POST', url: `scans/${params.id}/force-stop` });
}
/**
* Creates a copy of a scan configuration.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the scan to copy.
* @returns {Promise<ITenableScan>} The new, copied scan object.
*/
async copyScan(params) {
return this.sendRequest({ method: 'POST', url: `scans/${params.id}/copy` });
}
/**
* Imports a scan from an uploaded file.
* @param {IDataObject} body The request body containing the file reference.
* @returns {Promise<IDataObject>} The result of the import operation.
*/
async importScan(body) {
return this.sendRequest({ method: 'POST', url: 'scans/import', body });
}
/**
* Enables or disables the schedule for a scan.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the scan.
* @param {IDataObject} params.body The request body, e.g., `{ "enabled": true }`.
* @returns {Promise<IDataObject>} The updated schedule information.
*/
async toggleScanSchedule(params) {
return this.sendRequest({ method: 'PUT', url: `scans/${params.id}/schedule`, body: params.body });
}
/**
* Retrieves the latest status of a scan.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the scan.
* @returns {Promise<ITenableScan>} The latest scan status.
*/
async getLatestScanStatus(params) {
return this.sendRequest({ method: 'GET', url: `scans/${params.id}/latest-status` });
}
/**
* Retrieves the progress of a running scan.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the scan.
* @returns {Promise<IDataObject>} The scan progress percentage.
*/
async getScanProgress(params) {
return this.sendRequest({ method: 'GET', url: `scans/${params.id}/progress` });
}
/**
* Updates the read status of a scan (marks it as read/unread).
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the scan.
* @param {IDataObject} params.body The request body, e.g., `{ "read": true }`.
* @returns {Promise<IDataObject>} An empty object on success.
*/
async updateScanReadStatus(params) {
return this.sendRequest({ method: 'PUT', url: `scans/${params.id}/status`, body: params.body });
}
/**
* Retrieves the list of valid timezones for scheduling scans.
* @returns {Promise<IDataObject>} The list of timezones.
*/
async listTimezones() {
return this.sendRequest({ method: 'GET', url: 'scans/timezones' });
}
// =================================================================
// SCAN HISTORY
// =================================================================
/**
* Retrieves the historical runs for a specific scan.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the scan.
* @returns {Promise<ITenableScan[]>} The scan history.
*/
async getScanHistory(params) {
return this.sendRequest({ method: 'GET', url: `scans/${params.id}/history` });
}
/**
* Retrieves details for a specific historical scan run.
* @param {object} params The parameters for the request.
* @param {string} params.scan_id The UUID of the parent scan.
* @param {string} params.history_id The ID of the historical run.
* @returns {Promise<IDataObject>} The details of the historical scan run.
*/
async getScanHistoryDetails(params) {
return this.sendRequest({ method: 'GET', url: `scans/${params.scan_id}/history/${params.history_id}` });
}
/**
* Deletes a specific historical scan run.
* @param {object} params The parameters for the request.
* @param {string} params.scan_id The UUID of the parent scan.
* @param {string} params.history_id The ID of the historical run to delete.
* @returns {Promise<IDataObject>} An empty object on success.
*/
async deleteScanHistory(params) {
return this.sendRequest({ method: 'DELETE', url: `scans/${params.scan_id}/history/${params.history_id}` });
}
// =================================================================
// SCAN EXPORTS
// =================================================================
/**
* Initiates an export for a completed scan.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the scan to export.
* @param {IDataObject} params.body The export options (format, chapters, etc.).
* @returns {Promise<IDataObject>} The export job details.
*/
async requestScanExport(params) {
return this.sendRequest({ method: 'POST', url: `scans/${params.id}/export`, body: params.body });
}
/**
* Checks the status of a pending scan export.
* @param {object} params The parameters for the request.
* @param {string} params.scan_id The UUID of the parent scan.
* @param {string} params.file_id The ID of the export file.
* @returns {Promise<IDataObject>} The export status.
*/
async getScanExportStatus(params) {
return this.sendRequest({ method: 'GET', url: `scans/${params.scan_id}/export/${params.file_id}/status` });
}
/**
* Downloads a completed scan export file.
* @param {object} params The parameters for the request.
* @param {string} params.scan_id The UUID of the parent scan.
* @param {string} params.file_id The ID of the export file.
* @returns {Promise<unknown>} The file stream.
*/
async downloadScanExport(params) {
const requestOptions = {
method: 'GET',
url: `scans/${params.scan_id}/export/${params.file_id}/download`,
encoding: 'stream', // Important for handling file downloads
};
return this.sendRequest(requestOptions);
}
// =================================================================
// SCAN RESULTS
// =================================================================
/**
* Retrieves details for a specific host within a scan.
* @param {object} params The parameters for the request.
* @param {string} params.scan_id The UUID of the scan.
* @param {string} params.host_id The ID of the host.
* @returns {Promise<IDataObject>} The host details.
*/
async getHostDetails(params) {
return this.sendRequest({ method: 'GET', url: `scans/${params.scan_id}/hosts/${params.host_id}` });
}
/**
* Gets the full plugin output for a vulnerability on a host.
* @param {object} params The parameters for the request.
* @param {string} params.scan_id The UUID of the scan.
* @param {string} params.host_id The ID of the host.
* @param {string} params.plugin_id The ID of the plugin.
* @returns {Promise<IDataObject>} The plugin output details.
*/
async getPluginOutput(params) {
return this.sendRequest({ method: 'GET', url: `scans/${params.scan_id}/hosts/${params.host_id}/plugins/${params.plugin_id}` });
}
/**
* Downloads an attachment from a scan result.
* @param {object} params The parameters for the request.
* @param {string} params.scan_id The UUID of the scan.
* @param {string} params.attachment_id The ID of the attachment.
* @returns {Promise<unknown>} The file stream.
*/
async getScanAttachment(params) {
const requestOptions = {
method: 'GET',
url: `scans/${params.scan_id}/attachments/${params.attachment_id}`,
encoding: 'stream',
};
return this.sendRequest(requestOptions);
}
// =================================================================
// POLICIES
// =================================================================
/**
* Retrieves a list of scan policies.
* @param {object} qs Query string parameters for pagination.
* @returns {Promise<IDataObject>} The list of policies.
*/
async listPolicies(qs = {}) {
return this.sendRequest({ method: 'GET', url: 'policies', qs });
}
/**
* Creates a new scan policy.
* @param {IDataObject} body The request body defining the new policy.
* @returns {Promise<IDataObject>} The newly created policy object.
*/
async createPolicy(body) {
return this.sendRequest({ method: 'POST', url: 'policies', body });
}
/**
* Retrieves details for a specific policy.
* @param {object} params The parameters for the request.
* @param {string} params.id The ID of the policy.
* @returns {Promise<IDataObject>} The policy details.
*/
async getPolicyDetails(params) {
return this.sendRequest({ method: 'GET', url: `policies/${params.id}` });
}
/**
* Updates an existing scan policy.
* @param {object} params The parameters for the request.
* @param {string} params.id The ID of the policy to update.
* @param {IDataObject} params.body The data to update.
* @returns {Promise<IDataObject>} The updated policy object.
*/
async updatePolicy(params) {
return this.sendRequest({ method: 'PUT', url: `policies/${params.id}`, body: params.body });
}
/**
* Deletes a scan policy.
* @param {object} params The parameters for the request.
* @param {string} params.id The ID of the policy to delete.
* @returns {Promise<IDataObject>} An empty object on success.
*/
async deletePolicy(params) {
return this.sendRequest({ method: 'DELETE', url: `policies/${params.id}` });
}
/**
* Creates a copy of a scan policy.
* @param {object} params The parameters for the request.
* @param {string} params.id The ID of the policy to copy.
* @returns {Promise<IDataObject>} The new, copied policy object.
*/
async copyPolicy(params) {
return this.sendRequest({ method: 'POST', url: `policies/${params.id}/copy` });
}
/**
* Imports a policy from an uploaded file.
* @param {IDataObject} body The request body containing the file reference.
* @returns {Promise<IDataObject>} The result of the import operation.
*/
async importPolicy(body) {
return this.sendRequest({ method: 'POST', url: 'policies/import', body });
}
/**
* Exports a policy to a file.
* @param {object} params The parameters for the request.
* @param {string} params.id The ID of the policy to export.
* @returns {Promise<unknown>} The file stream.
*/
async exportPolicy(params) {
const requestOptions = {
method: 'GET',
url: `policies/${params.id}/export`,
encoding: 'stream',
};
return this.sendRequest(requestOptions);
}
// =================================================================
// ASSET ATTRIBUTES
// =================================================================
/**
* Creates a new custom asset attribute definition.
* @param {IDataObject} body The attribute definition.
* @returns {Promise<IDataObject>} The created attribute object.
*/
async createAttribute(body) {
return this.sendRequest({ method: 'POST', url: 'api/v3/assets/attributes', body });
}
/**
* Retrieves a list of all custom asset attribute definitions.
* @returns {Promise<IDataObject>} The list of attributes.
*/
async listAttributes() {
return this.sendRequest({ method: 'GET', url: 'api/v3/assets/attributes' });
}
/**
* Updates a custom asset attribute definition.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the attribute to update.
* @param {IDataObject} params.body The data to update.
* @returns {Promise<IDataObject>} The updated attribute object.
*/
async updateAttribute(params) {
return this.sendRequest({ method: 'PUT', url: `api/v3/assets/attributes/${params.id}`, body: params.body });
}
/**
* Deletes a custom asset attribute definition.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the attribute to delete.
* @returns {Promise<IDataObject>} An empty object on success.
*/
async deleteAttribute(params) {
return this.sendRequest({ method: 'DELETE', url: `api/v3/assets/attributes/${params.id}` });
}
/**
* Assigns custom attribute values to a specific asset.
* @param {object} params The parameters for the request.
* @param {string} params.asset_id The UUID of the asset.
* @param {IDataObject} params.body The attributes to assign.
* @returns {Promise<IDataObject>} An empty object on success.
*/
async assignAttributesToAsset(params) {
return this.sendRequest({ method: 'PUT', url: `api/v3/assets/${params.asset_id}/attributes`, body: params.body });
}
/**
* Retrieves the custom attributes assigned to a specific asset.
* @param {object} params The parameters for the request.
* @param {string} params.asset_id The UUID of the asset.
* @returns {Promise<IDataObject>} The list of assigned attributes.
*/
async listAssetAttributes(params) {
return this.sendRequest({ method: 'GET', url: `api/v3/assets/${params.asset_id}/attributes` });
}
/**
* Deletes all custom attribute assignments from a specific asset.
* @param {object} params The parameters for the request.
* @param {string} params.asset_id The UUID of the asset.
* @returns {Promise<IDataObject>} An empty object on success.
*/
async deleteAssetAttributes(params) {
return this.sendRequest({ method: 'DELETE', url: `api/v3/assets/${params.asset_id}/attributes` });
}
// =================================================================
// REPORTS
// =================================================================
/**
* Creates a new report.
* @param {IDataObject} body The report definition and filters.
* @returns {Promise<IDataObject>} The report job details.
*/
async createReport(body) {
return this.sendRequest({ method: 'POST', url: 'reports/export', body });
}
/**
* Retrieves the status of a report generation job.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the report job.
* @returns {Promise<IDataObject>} The report job status.
*/
async getReportStatus(params) {
return this.sendRequest({ method: 'GET', url: `reports/export/${params.id}/status` });
}
/**
* Downloads a completed report file.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the report job.
* @returns {Promise<unknown>} The file stream.
*/
async downloadReport(params) {
const requestOptions = {
method: 'GET',
url: `reports/export/${params.id}/download`,
encoding: 'stream',
};
return this.sendRequest(requestOptions);
}
// =================================================================
// FILTERS
// =================================================================
/**
* Retrieves the available filters for agent records.
* @returns {Promise<IDataObject>} The list of agent filters.
*/
async listAgentFilters() {
return this.sendRequest({ method: 'GET', url: 'filters/scans/agents' });
}
/**
* Retrieves the available filters for asset records.
* @returns {Promise<IDataObject>} The list of asset filters.
*/
async listAssetFilters() {
return this.sendRequest({ method: 'GET', url: 'filters/workbenches/assets' });
}
/**
* Retrieves the available filters for credential records.
* @returns {Promise<IDataObject>} The list of credential filters.
*/
async listCredentialFilters() {
return this.sendRequest({ method: 'GET', url: 'filters/credentials' });
}
/**
* Retrieves the available filters for report exports.
* @returns {Promise<IDataObject>} The list of report filters.
*/
async listReportFilters() {
return this.sendRequest({ method: 'GET', url: 'filters/reports/export' });
}
/**
* Retrieves the available filters for vulnerability records.
* @returns {Promise<IDataObject>} The list of vulnerability filters.
*/
async listVulnerabilityFilters() {
return this.sendRequest({ method: 'GET', url: 'filters/workbenches/vulnerabilities' });
}
// =================================================================
// VULNERABILITIES (IMPORT)
// =================================================================
/**
* Imports vulnerability data into Tenable.
* @param {IDataObject} body The vulnerability data to import.
* @returns {Promise<IDataObject>} The result of the import operation.
*/
async importVulnerabilities(body) {
return this.sendRequest({ method: 'POST', url: 'api/v2/vulnerabilities', body });
}
// =================================================================
// SHARED COLLECTIONS
// =================================================================
/**
* Creates a new shared collection.
* @param {IDataObject} body The definition of the new collection.
* @returns {Promise<IDataObject>} The created shared collection object.
*/
async createSharedCollection(body) {
return this.sendRequest({ method: 'POST', url: 'shared-collections', body });
}
/**
* Retrieves a list of shared collections.
* @returns {Promise<IDataObject>} The list of shared collections.
*/
async listSharedCollections() {
return this.sendRequest({ method: 'GET', url: 'shared-collections' });
}
/**
* Retrieves details for a specific shared collection.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the collection.
* @returns {Promise<IDataObject>} The collection details.
*/
async getSharedCollection(params) {
return this.sendRequest({ method: 'GET', url: `shared-collections/${params.id}` });
}
/**
* Updates a shared collection.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the collection to update.
* @param {IDataObject} params.body The data to update.
* @returns {Promise<IDataObject>} The updated collection object.
*/
async updateSharedCollection(params) {
return this.sendRequest({ method: 'PUT', url: `shared-collections/${params.id}`, body: params.body });
}
/**
* Deletes a shared collection.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the collection to delete.
* @returns {Promise<IDataObject>} An empty object on success.
*/
async deleteSharedCollection(params) {
return this.sendRequest({ method: 'DELETE', url: `shared-collections/${params.id}` });
}
/**
* Adds scan configurations to a shared collection.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the collection.
* @param {IDataObject} params.body The scan configs to add.
* @returns {Promise<IDataObject>} An empty object on success.
*/
async addScanToSharedCollection(params) {
return this.sendRequest({ method: 'POST', url: `shared-collections/${params.id}/scan-configs`, body: params.body });
}
/**
* Retrieves the scan configurations within a shared collection.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the collection.
* @returns {Promise<IDataObject>} A list of scan configurations.
*/
async listScansInSharedCollection(params) {
return this.sendRequest({ method: 'GET', url: `shared-collections/${params.id}/scan-configs` });
}
/**
* Removes scan configurations from a shared collection.
* @param {object} params The parameters for the request.
* @param {string} params.id The UUID of the collection.
* @param {IDataObject} params.body The scan configs to remove.
* @returns {Promise<IDataObject>} An empty object on success.
*/
async removeScanFromSharedCollection(params) {
return this.sendRequest({ method: 'DELETE', url: `shared-collections/${params.id}/scan-configs`, body: params.body });
}
// =================================================================
// USERS & PERMISSIONS
// =================================================================
/**
* Retrieves a list of users.
* @param {object} qs Query string parameters for pagination.
* @returns {Promise<IDataObject>} The list of users.
*/
async listUsers(qs = {}) {
return this.sendRequest({ method: 'GET', url: 'users', qs });
}
/**
* Deletes a user.
* @param {object} params The parameters for the request.
* @param {string} params.id The ID of the user to delete.
* @returns {Promise<IDataObject>} An empty object on success.
*/
async deleteUser(params) {
return this.sendRequest({ method: 'DELETE', url: `users/${params.id}` });
}
// =================================================================
// TAGS
// =================================================================
/**
* Retrieves all tag values.
* @returns {Promise<IDataObject>} The list of tag values.
*/
async listTagValues() {
return this.sendRequest({ method: 'GET', url: 'tags/values' });
}
}
exports.TenableVMClient = TenableVMClient;