mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
✨ Add TheHive & Cortex nodes (#952)
* ✨ TheHive & Cortex nodes * 🔨 Make changes mentioned in #887 * ⚡ Improvements * ⚡ Improvements * ⚡ Improvements * ⚡ Add descriptions * ⚡ Improvements * ⚡ Improvements Co-authored-by: MedAliMarz <servfrdali@yahoo.fr>
This commit is contained in:
parent
ea79e80c17
commit
ea9f61089b
26
packages/nodes-base/credentials/CortexApi.credentials.ts
Normal file
26
packages/nodes-base/credentials/CortexApi.credentials.ts
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import {
|
||||||
|
ICredentialType,
|
||||||
|
NodePropertyTypes,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
|
||||||
|
export class CortexApi implements ICredentialType {
|
||||||
|
name = 'cortexApi';
|
||||||
|
displayName = 'Cortex API';
|
||||||
|
properties = [
|
||||||
|
{
|
||||||
|
displayName: 'API Key',
|
||||||
|
name: 'cortexApiKey',
|
||||||
|
type: 'string' as NodePropertyTypes,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Cortex Instance',
|
||||||
|
name: 'host',
|
||||||
|
type: 'string' as NodePropertyTypes,
|
||||||
|
description: 'The URL of the Cortex instance',
|
||||||
|
default: '',
|
||||||
|
placeholder:'https://localhost:9001'
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
44
packages/nodes-base/credentials/TheHiveApi.credentials.ts
Normal file
44
packages/nodes-base/credentials/TheHiveApi.credentials.ts
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import {
|
||||||
|
ICredentialType,
|
||||||
|
NodePropertyTypes,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
export class TheHiveApi implements ICredentialType {
|
||||||
|
name = 'theHiveApi';
|
||||||
|
displayName = 'The Hive API';
|
||||||
|
properties = [
|
||||||
|
{
|
||||||
|
displayName: 'API Key',
|
||||||
|
name: 'ApiKey',
|
||||||
|
type: 'string' as NodePropertyTypes,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'URL',
|
||||||
|
name: 'url',
|
||||||
|
default: '',
|
||||||
|
type: 'string' as NodePropertyTypes,
|
||||||
|
description: 'The URL of TheHive instance',
|
||||||
|
placeholder: 'https://localhost:9000',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'API Version',
|
||||||
|
name: 'apiVersion',
|
||||||
|
default: '',
|
||||||
|
type: 'options' as NodePropertyTypes,
|
||||||
|
description: 'The version of api to be used',
|
||||||
|
options:[
|
||||||
|
{
|
||||||
|
name:'Version 1',
|
||||||
|
value:'v1',
|
||||||
|
description:'API version supported by TheHive 4'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'Version 0',
|
||||||
|
value:'',
|
||||||
|
description:'API version supported by TheHive 3'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
210
packages/nodes-base/nodes/Cortex/AnalyzerDescriptions.ts
Normal file
210
packages/nodes-base/nodes/Cortex/AnalyzerDescriptions.ts
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
import {
|
||||||
|
INodeProperties,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
import {
|
||||||
|
TLP,
|
||||||
|
}from './AnalyzerInterface';
|
||||||
|
|
||||||
|
export const analyzersOperations = [
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
description: 'Choose an operation',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'analyzer',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: 'execute',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Execute',
|
||||||
|
value: 'execute',
|
||||||
|
description: 'Execute Analyzer',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
] as INodeProperties[];
|
||||||
|
|
||||||
|
export const analyzerFields: INodeProperties[] =[
|
||||||
|
{
|
||||||
|
displayName: 'Analyzer Type',
|
||||||
|
name: 'analyzer',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'loadActiveAnalyzers',
|
||||||
|
},
|
||||||
|
displayOptions:{
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'analyzer',
|
||||||
|
],
|
||||||
|
operation:[
|
||||||
|
'execute',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Choose the analyzer',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Observable Type',
|
||||||
|
name: 'observableType',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
displayOptions:{
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'analyzer',
|
||||||
|
],
|
||||||
|
operation:[
|
||||||
|
'execute',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hide:{
|
||||||
|
analyzer:[
|
||||||
|
'',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typeOptions:{
|
||||||
|
loadOptionsMethod: 'loadObservableOptions',
|
||||||
|
loadOptionsDependsOn: [
|
||||||
|
'analyzer',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'Choose the observable type',
|
||||||
|
},
|
||||||
|
|
||||||
|
// Observable type != file
|
||||||
|
{
|
||||||
|
displayName: 'Observable Value',
|
||||||
|
name: 'observableValue',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'analyzer',
|
||||||
|
],
|
||||||
|
operation:[
|
||||||
|
'execute',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hide:{
|
||||||
|
observableType: [
|
||||||
|
'file',
|
||||||
|
],
|
||||||
|
analyzer:[
|
||||||
|
'',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'Enter the observable value',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Binary Property',
|
||||||
|
name: 'binaryPropertyName',
|
||||||
|
type: 'string',
|
||||||
|
default: 'data',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
observableType: [
|
||||||
|
'file',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'analyzer',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'execute',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Name of the binary property to which to<br />write the data of the read file.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'TLP',
|
||||||
|
name: 'tlp',
|
||||||
|
type: 'options',
|
||||||
|
required: false,
|
||||||
|
displayOptions:{
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'analyzer',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'execute',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hide:{
|
||||||
|
observableType: [
|
||||||
|
'',
|
||||||
|
],
|
||||||
|
analyzer: [
|
||||||
|
'',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'White',
|
||||||
|
value: TLP.white,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Green',
|
||||||
|
value: TLP.green,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Amber',
|
||||||
|
value: TLP.amber,
|
||||||
|
},{
|
||||||
|
name: 'Red',
|
||||||
|
value: TLP.red,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
default: 2,
|
||||||
|
description: 'The TLP of the analyzed observable',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Additional Fields',
|
||||||
|
name: 'additionalFields',
|
||||||
|
type: 'collection',
|
||||||
|
placeholder: 'Add Field',
|
||||||
|
default: {},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'analyzer',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'execute',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Force',
|
||||||
|
name: 'force',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'To force bypassing the cache, set this parameter to true',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Timeout (seconds)',
|
||||||
|
name: 'timeout',
|
||||||
|
type: 'number',
|
||||||
|
default: 3,
|
||||||
|
description: 'Timeout to wait for the report in case it is not available at the time the query was made',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
86
packages/nodes-base/nodes/Cortex/AnalyzerInterface.ts
Normal file
86
packages/nodes-base/nodes/Cortex/AnalyzerInterface.ts
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
import {
|
||||||
|
IDataObject,
|
||||||
|
}from 'n8n-workflow';
|
||||||
|
|
||||||
|
export enum JobStatus {
|
||||||
|
WAITING = 'Waiting',
|
||||||
|
INPROGRESS = 'InProgress',
|
||||||
|
SUCCESS = 'Success',
|
||||||
|
FAILURE = 'Failure',
|
||||||
|
DELETED = 'Deleted'
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum TLP {
|
||||||
|
white,
|
||||||
|
green,
|
||||||
|
amber,
|
||||||
|
red
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ObservableDataType {
|
||||||
|
'domain'= 'domain',
|
||||||
|
'file'= 'file',
|
||||||
|
'filename'= 'filename',
|
||||||
|
'fqdn'= 'fqdn',
|
||||||
|
'hash'= 'hash',
|
||||||
|
'ip'= 'ip',
|
||||||
|
'mail'= 'mail',
|
||||||
|
'mail_subject'= 'mail_subject',
|
||||||
|
'other'= 'other',
|
||||||
|
'regexp'= 'regexp',
|
||||||
|
'registry'= 'registry',
|
||||||
|
'uri_path'= 'uri_path',
|
||||||
|
'url'= 'url',
|
||||||
|
'user-agent'= 'user-agent'
|
||||||
|
}
|
||||||
|
export interface IJob{
|
||||||
|
id?: string;
|
||||||
|
organization?: string;
|
||||||
|
analyzerDefinitionId?: string;
|
||||||
|
analyzerId?: string;
|
||||||
|
analyzerName?: string;
|
||||||
|
dataType?: ObservableDataType;
|
||||||
|
status?: JobStatus;
|
||||||
|
data?: string;
|
||||||
|
attachment?: IDataObject;
|
||||||
|
parameters?: IDataObject;
|
||||||
|
message? :string;
|
||||||
|
tlp?: TLP;
|
||||||
|
startDate?: Date;
|
||||||
|
endDate?: Date;
|
||||||
|
createdAt?: Date;
|
||||||
|
createdBy?: string;
|
||||||
|
updatedAt?: Date;
|
||||||
|
updatedBy?: Date;
|
||||||
|
report?: IDataObject | string;
|
||||||
|
}
|
||||||
|
export interface IAnalyzer{
|
||||||
|
id?: string;
|
||||||
|
analyzerDefinitionId?: string;
|
||||||
|
name? :string;
|
||||||
|
version?: string;
|
||||||
|
description?: string;
|
||||||
|
author?: string;
|
||||||
|
url?: string;
|
||||||
|
license?: string;
|
||||||
|
dataTypeList?: ObservableDataType[];
|
||||||
|
baseConfig?: string;
|
||||||
|
jobCache?: number;
|
||||||
|
rate?: number;
|
||||||
|
rateUnit?: string;
|
||||||
|
configuration?: IDataObject;
|
||||||
|
createdBy?: string;
|
||||||
|
updatedAt?: Date;
|
||||||
|
updatedBy?: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IResponder{
|
||||||
|
id?: string;
|
||||||
|
name?: string;
|
||||||
|
version?: string;
|
||||||
|
description?: string;
|
||||||
|
dataTypeList?: string[];
|
||||||
|
maxTlp?: number;
|
||||||
|
maxPap?: number;
|
||||||
|
cortexIds?: string[] | undefined;
|
||||||
|
}
|
469
packages/nodes-base/nodes/Cortex/Cortex.node.ts
Normal file
469
packages/nodes-base/nodes/Cortex/Cortex.node.ts
Normal file
|
@ -0,0 +1,469 @@
|
||||||
|
import {
|
||||||
|
IExecuteFunctions,
|
||||||
|
BINARY_ENCODING,
|
||||||
|
} from 'n8n-core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
cortexApiRequest,
|
||||||
|
getEntityLabel,
|
||||||
|
prepareParameters,
|
||||||
|
splitTags,
|
||||||
|
} from './GenericFunctions';
|
||||||
|
|
||||||
|
import {
|
||||||
|
analyzersOperations,
|
||||||
|
analyzerFields,
|
||||||
|
} from './AnalyzerDescriptions';
|
||||||
|
|
||||||
|
import {
|
||||||
|
INodeExecutionData,
|
||||||
|
INodeType,
|
||||||
|
INodeTypeDescription,
|
||||||
|
INodePropertyOptions,
|
||||||
|
ILoadOptionsFunctions,
|
||||||
|
IDataObject,
|
||||||
|
IBinaryData,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
import {
|
||||||
|
respondersOperations,
|
||||||
|
responderFields,
|
||||||
|
} from './ResponderDescription';
|
||||||
|
|
||||||
|
import {
|
||||||
|
jobFields,
|
||||||
|
jobOperations,
|
||||||
|
} from './JobDescription';
|
||||||
|
|
||||||
|
import {
|
||||||
|
upperFirst,
|
||||||
|
} from 'lodash';
|
||||||
|
|
||||||
|
import {
|
||||||
|
IJob,
|
||||||
|
} from './AnalyzerInterface';
|
||||||
|
|
||||||
|
import {
|
||||||
|
createHash,
|
||||||
|
} from 'crypto';
|
||||||
|
|
||||||
|
import * as changeCase from 'change-case';
|
||||||
|
|
||||||
|
export class Cortex implements INodeType {
|
||||||
|
description: INodeTypeDescription = {
|
||||||
|
displayName: 'Cortex',
|
||||||
|
name: 'cortex',
|
||||||
|
icon: 'file:cortex.png',
|
||||||
|
group: ['transform'],
|
||||||
|
subtitle: '={{$parameter["resource"]+ ": " + $parameter["operation"]}}',
|
||||||
|
version: 1,
|
||||||
|
description: 'Apply the Cortex analyzer/responder on the given entity',
|
||||||
|
defaults: {
|
||||||
|
name: 'Cortex',
|
||||||
|
color: '#54c4c3',
|
||||||
|
},
|
||||||
|
inputs: ['main'],
|
||||||
|
outputs: ['main'],
|
||||||
|
credentials: [
|
||||||
|
{
|
||||||
|
name: 'cortexApi',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
properties: [
|
||||||
|
// Node properties which the user gets displayed and
|
||||||
|
// can change on the node.
|
||||||
|
{
|
||||||
|
displayName:'Resource',
|
||||||
|
name:'resource',
|
||||||
|
type:'options',
|
||||||
|
options:[
|
||||||
|
{
|
||||||
|
name: 'Analyzer',
|
||||||
|
value:'analyzer',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Responder',
|
||||||
|
value:'responder',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Job',
|
||||||
|
value:'job',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'analyzer',
|
||||||
|
description: 'Choose a resource',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
...analyzersOperations,
|
||||||
|
...analyzerFields,
|
||||||
|
...respondersOperations,
|
||||||
|
...responderFields,
|
||||||
|
...jobOperations,
|
||||||
|
...jobFields
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
methods = {
|
||||||
|
loadOptions: {
|
||||||
|
|
||||||
|
async loadActiveAnalyzers(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||||
|
// request the enabled analyzers from instance
|
||||||
|
const requestResult = await cortexApiRequest.call(
|
||||||
|
this,
|
||||||
|
'POST',
|
||||||
|
`/analyzer/_search`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const returnData: INodePropertyOptions[] = [];
|
||||||
|
|
||||||
|
for (const analyzer of requestResult) {
|
||||||
|
returnData.push({
|
||||||
|
name: analyzer.name as string,
|
||||||
|
value: `${analyzer.id as string}::${analyzer.name as string}`,
|
||||||
|
description: analyzer.description as string,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnData;
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadActiveResponders(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||||
|
// request the enabled responders from instance
|
||||||
|
const requestResult = await cortexApiRequest.call(
|
||||||
|
this,
|
||||||
|
'GET',
|
||||||
|
`/responder`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const returnData: INodePropertyOptions[] = [];
|
||||||
|
for (const responder of requestResult) {
|
||||||
|
returnData.push({
|
||||||
|
name: responder.name as string,
|
||||||
|
value: `${responder.id as string}::${responder.name as string}`,
|
||||||
|
description: responder.description as string,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return returnData;
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadObservableOptions(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||||
|
const selectedAnalyzerId = (this.getNodeParameter('analyzer') as string).split('::')[0];
|
||||||
|
// request the analyzers from instance
|
||||||
|
const requestResult = await cortexApiRequest.call(
|
||||||
|
this,
|
||||||
|
'GET',
|
||||||
|
`/analyzer/${selectedAnalyzerId}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// parse supported observable types into options
|
||||||
|
const returnData: INodePropertyOptions[] = [];
|
||||||
|
for (const dataType of requestResult.dataTypeList) {
|
||||||
|
returnData.push(
|
||||||
|
{
|
||||||
|
name: upperFirst(dataType as string),
|
||||||
|
value: dataType as string,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return returnData;
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadDataTypeOptions(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||||
|
const selectedResponderId = (this.getNodeParameter('responder') as string).split('::')[0];
|
||||||
|
// request the responder from instance
|
||||||
|
const requestResult = await cortexApiRequest.call(
|
||||||
|
this,
|
||||||
|
'GET',
|
||||||
|
`/responder/${selectedResponderId}`,
|
||||||
|
);
|
||||||
|
// parse the accepted dataType into options
|
||||||
|
const returnData: INodePropertyOptions[] = [];
|
||||||
|
for (const dataType of requestResult.dataTypeList) {
|
||||||
|
returnData.push(
|
||||||
|
{
|
||||||
|
value: (dataType as string).split(':')[1],
|
||||||
|
name: changeCase.capitalCase((dataType as string).split(':')[1])
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return returnData;
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||||
|
const items = this.getInputData();
|
||||||
|
const returnData: IDataObject[] = [];
|
||||||
|
const length = (items.length as unknown) as number;
|
||||||
|
const qs: IDataObject = {};
|
||||||
|
let responseData;
|
||||||
|
const resource = this.getNodeParameter('resource', 0) as string;
|
||||||
|
const operation = this.getNodeParameter('operation', 0) as string;
|
||||||
|
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
if (resource === 'analyzer') {
|
||||||
|
//https://github.com/TheHive-Project/CortexDocs/blob/master/api/api-guide.md#run
|
||||||
|
if (operation === 'execute') {
|
||||||
|
|
||||||
|
let force = false;
|
||||||
|
|
||||||
|
const analyzer = this.getNodeParameter('analyzer', i) as string;
|
||||||
|
|
||||||
|
const observableType = this.getNodeParameter('observableType', i) as string;
|
||||||
|
|
||||||
|
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
||||||
|
|
||||||
|
const tlp = this.getNodeParameter('tlp', i) as string;
|
||||||
|
|
||||||
|
const body: IDataObject = {
|
||||||
|
dataType: observableType,
|
||||||
|
tlp,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (additionalFields.force === true) {
|
||||||
|
force = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (observableType === 'file') {
|
||||||
|
|
||||||
|
const item = items[i];
|
||||||
|
|
||||||
|
if (item.binary === undefined) {
|
||||||
|
throw new Error('No binary data exists on item!');
|
||||||
|
}
|
||||||
|
|
||||||
|
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string;
|
||||||
|
|
||||||
|
if (item.binary[binaryPropertyName] === undefined) {
|
||||||
|
throw new Error(`No binary data property "${binaryPropertyName}" does not exists on item!`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileBufferData = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING);
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
formData: {
|
||||||
|
data: {
|
||||||
|
value: fileBufferData,
|
||||||
|
options: {
|
||||||
|
contentType: item.binary[binaryPropertyName].mimeType,
|
||||||
|
filename: item.binary[binaryPropertyName].fileName,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_json: JSON.stringify({
|
||||||
|
dataType: observableType,
|
||||||
|
tlp,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
responseData = await cortexApiRequest.call(
|
||||||
|
this,
|
||||||
|
'POST',
|
||||||
|
`/analyzer/${analyzer.split('::')[0]}/run`,
|
||||||
|
{},
|
||||||
|
{ force },
|
||||||
|
'',
|
||||||
|
options,
|
||||||
|
) as IJob;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const observableValue = this.getNodeParameter('observableValue', i) as string;
|
||||||
|
|
||||||
|
body.data = observableValue;
|
||||||
|
|
||||||
|
responseData = await cortexApiRequest.call(
|
||||||
|
this,
|
||||||
|
'POST',
|
||||||
|
`/analyzer/${analyzer.split('::')[0]}/run`,
|
||||||
|
body,
|
||||||
|
{ force },
|
||||||
|
) as IJob;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (additionalFields.timeout) {
|
||||||
|
responseData = await cortexApiRequest.call(
|
||||||
|
this,
|
||||||
|
'GET',
|
||||||
|
`/job/${responseData.id}/waitreport`,
|
||||||
|
{},
|
||||||
|
{ atMost: `${additionalFields.timeout}second` },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resource === 'job') {
|
||||||
|
//https://github.com/TheHive-Project/CortexDocs/blob/master/api/api-guide.md#get-details-1
|
||||||
|
if (operation === 'get') {
|
||||||
|
|
||||||
|
const jobId = this.getNodeParameter('jobId', i) as string;
|
||||||
|
|
||||||
|
responseData = await cortexApiRequest.call(
|
||||||
|
this,
|
||||||
|
'GET',
|
||||||
|
`/job/${jobId}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//https://github.com/TheHive-Project/CortexDocs/blob/master/api/api-guide.md#get-details-and-report
|
||||||
|
if (operation === 'report') {
|
||||||
|
|
||||||
|
const jobId = this.getNodeParameter('jobId', i) as string;
|
||||||
|
|
||||||
|
responseData = await cortexApiRequest.call(
|
||||||
|
this,
|
||||||
|
'GET',
|
||||||
|
`/job/${jobId}/report`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resource === 'responder') {
|
||||||
|
if (operation === 'execute') {
|
||||||
|
const responderId = (this.getNodeParameter('responder', i) as string).split('::')[0];
|
||||||
|
|
||||||
|
const entityType = this.getNodeParameter('entityType', i) as string;
|
||||||
|
|
||||||
|
const isJSON = this.getNodeParameter('jsonObject',i) as boolean;
|
||||||
|
let body:IDataObject;
|
||||||
|
|
||||||
|
|
||||||
|
if(isJSON){
|
||||||
|
|
||||||
|
|
||||||
|
const entityJson = JSON.parse(this.getNodeParameter('objectData', i) as string);
|
||||||
|
|
||||||
|
body = {
|
||||||
|
responderId,
|
||||||
|
label: getEntityLabel(entityJson),
|
||||||
|
dataType: `thehive:${entityType}`,
|
||||||
|
data: entityJson,
|
||||||
|
tlp: entityJson.tlp || 2,
|
||||||
|
pap: entityJson.pap || 2,
|
||||||
|
message: entityJson.message || '',
|
||||||
|
parameters:[],
|
||||||
|
};
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
const values = (this.getNodeParameter('parameters',i) as IDataObject).values as IDataObject;
|
||||||
|
|
||||||
|
body= {
|
||||||
|
responderId,
|
||||||
|
dataType: `thehive:${entityType}`,
|
||||||
|
data: {
|
||||||
|
_type: entityType,
|
||||||
|
...prepareParameters(values)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if( entityType === 'alert'){
|
||||||
|
// deal with alert artifacts
|
||||||
|
const artifacts = (body.data as IDataObject).artifacts as IDataObject;
|
||||||
|
|
||||||
|
if (artifacts) {
|
||||||
|
|
||||||
|
const artifactValues = (artifacts as IDataObject).artifactValues as IDataObject[];
|
||||||
|
|
||||||
|
if (artifactValues) {
|
||||||
|
|
||||||
|
const artifactData = [];
|
||||||
|
|
||||||
|
for (const artifactvalue of artifactValues) {
|
||||||
|
|
||||||
|
const element: IDataObject = {};
|
||||||
|
|
||||||
|
element.message = artifactvalue.message as string;
|
||||||
|
|
||||||
|
element.tags = splitTags(artifactvalue.tags as string) as string[];
|
||||||
|
|
||||||
|
element.dataType = artifactvalue.dataType as string;
|
||||||
|
|
||||||
|
element.data = artifactvalue.data as string;
|
||||||
|
|
||||||
|
if (artifactvalue.dataType === 'file') {
|
||||||
|
|
||||||
|
const item = items[i];
|
||||||
|
|
||||||
|
if (item.binary === undefined) {
|
||||||
|
throw new Error('No binary data exists on item!');
|
||||||
|
}
|
||||||
|
|
||||||
|
const binaryPropertyName = artifactvalue.binaryProperty as string;
|
||||||
|
|
||||||
|
if (item.binary[binaryPropertyName] === undefined) {
|
||||||
|
throw new Error(`No binary data property '${binaryPropertyName}' does not exists on item!`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const binaryData = item.binary[binaryPropertyName] as IBinaryData;
|
||||||
|
|
||||||
|
element.data = `${binaryData.fileName};${binaryData.mimeType};${binaryData.data}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
artifactData.push(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
(body.data as IDataObject).artifacts = artifactData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(entityType ==='case_artifact'){
|
||||||
|
// deal with file observable
|
||||||
|
|
||||||
|
if ((body.data as IDataObject).dataType === 'file') {
|
||||||
|
|
||||||
|
const item = items[i];
|
||||||
|
|
||||||
|
if (item.binary === undefined) {
|
||||||
|
throw new Error('No binary data exists on item!');
|
||||||
|
}
|
||||||
|
|
||||||
|
const binaryPropertyName = (body.data as IDataObject).binaryPropertyName as string;
|
||||||
|
if (item.binary[binaryPropertyName] === undefined) {
|
||||||
|
throw new Error(`No binary data property "${binaryPropertyName}" does not exists on item!`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileBufferData = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING);
|
||||||
|
const sha256 = createHash('sha256').update(fileBufferData).digest('hex');
|
||||||
|
|
||||||
|
(body.data as IDataObject).attachment = {
|
||||||
|
name: item.binary[binaryPropertyName].fileName,
|
||||||
|
hashes: [
|
||||||
|
sha256,
|
||||||
|
createHash('sha1').update(fileBufferData).digest('hex'),
|
||||||
|
createHash('md5').update(fileBufferData).digest('hex')
|
||||||
|
],
|
||||||
|
size:fileBufferData.byteLength,
|
||||||
|
contentType: item.binary[binaryPropertyName].mimeType,
|
||||||
|
id:sha256,
|
||||||
|
};
|
||||||
|
|
||||||
|
delete (body.data as IDataObject).binaryPropertyName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// add the job label after getting all entity attributes
|
||||||
|
body = {
|
||||||
|
label: getEntityLabel(body.data as IDataObject),
|
||||||
|
...body
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
responseData = await cortexApiRequest.call(
|
||||||
|
this,
|
||||||
|
'POST',
|
||||||
|
`/responder/${responderId}/run`,
|
||||||
|
body,
|
||||||
|
) as IJob;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Array.isArray(responseData)) {
|
||||||
|
returnData.push.apply(returnData, responseData as IDataObject[]);
|
||||||
|
} else if (responseData !== undefined) {
|
||||||
|
returnData.push(responseData as IDataObject);
|
||||||
|
}
|
||||||
|
return [this.helpers.returnJsonArray(returnData)];
|
||||||
|
}
|
||||||
|
}
|
109
packages/nodes-base/nodes/Cortex/GenericFunctions.ts
Normal file
109
packages/nodes-base/nodes/Cortex/GenericFunctions.ts
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
import {
|
||||||
|
OptionsWithUri,
|
||||||
|
} from 'request';
|
||||||
|
|
||||||
|
import {
|
||||||
|
IAnalyzer,
|
||||||
|
IJob,
|
||||||
|
IResponder,
|
||||||
|
} from './AnalyzerInterface';
|
||||||
|
|
||||||
|
import {
|
||||||
|
IExecuteFunctions,
|
||||||
|
IHookFunctions,
|
||||||
|
ILoadOptionsFunctions,
|
||||||
|
IExecuteSingleFunctions,
|
||||||
|
} from 'n8n-core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
IDataObject,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
import * as moment from 'moment';
|
||||||
|
|
||||||
|
export async function cortexApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, query: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
|
|
||||||
|
const credentials = this.getCredentials('cortexApi');
|
||||||
|
|
||||||
|
if (credentials === undefined) {
|
||||||
|
throw new Error('No credentials got returned!');
|
||||||
|
}
|
||||||
|
|
||||||
|
const headerWithAuthentication = Object.assign({}, { Authorization: ` Bearer ${credentials.cortexApiKey}`});
|
||||||
|
|
||||||
|
let options: OptionsWithUri = {
|
||||||
|
headers: headerWithAuthentication,
|
||||||
|
method,
|
||||||
|
qs: query,
|
||||||
|
uri: uri || `${credentials.host}/api${resource}`,
|
||||||
|
body,
|
||||||
|
json: true,
|
||||||
|
|
||||||
|
};
|
||||||
|
if (Object.keys(option).length !== 0) {
|
||||||
|
options = Object.assign({},options, option);
|
||||||
|
}
|
||||||
|
if (Object.keys(body).length === 0) {
|
||||||
|
delete options.body;
|
||||||
|
}
|
||||||
|
if (Object.keys(query).length === 0) {
|
||||||
|
delete options.qs;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await this.helpers.request!(options);
|
||||||
|
} catch (error) {
|
||||||
|
if (error.error ) {
|
||||||
|
const errorMessage = `Cortex error response [${error.statusCode}]: ${error.error.message}`;
|
||||||
|
throw new Error(errorMessage);
|
||||||
|
} else throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getEntityLabel(entity: IDataObject): string{
|
||||||
|
let label = '';
|
||||||
|
switch (entity._type) {
|
||||||
|
case 'case':
|
||||||
|
label = `#${entity.caseId} ${entity.title}`;
|
||||||
|
break;
|
||||||
|
case 'case_artifact':
|
||||||
|
//@ts-ignore
|
||||||
|
label = `[${entity.dataType}] ${entity.data?entity.data:(entity.attachment.name)}`;
|
||||||
|
break;
|
||||||
|
case 'alert':
|
||||||
|
label = `[${entity.source}:${entity.sourceRef}] ${entity.title}`;
|
||||||
|
break;
|
||||||
|
case 'case_task_log':
|
||||||
|
label = `${entity.message} from ${entity.createdBy}`;
|
||||||
|
break;
|
||||||
|
case 'case_task':
|
||||||
|
label = `${entity.title} (${entity.status})`;
|
||||||
|
break;
|
||||||
|
case 'job':
|
||||||
|
label = `${entity.analyzerName} (${entity.status})`;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function splitTags(tags: string): string[] {
|
||||||
|
return tags.split(',').filter(tag => tag !== ' ' && tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function prepareParameters(values: IDataObject): IDataObject {
|
||||||
|
const response: IDataObject = {};
|
||||||
|
for (const key in values) {
|
||||||
|
if (values[key]!== undefined && values[key]!==null && values[key]!=='') {
|
||||||
|
if (moment(values[key] as string, moment.ISO_8601).isValid()) {
|
||||||
|
response[key] = Date.parse(values[key] as string);
|
||||||
|
} else if (key === 'tags') {
|
||||||
|
response[key] = splitTags(values[key] as string);
|
||||||
|
} else {
|
||||||
|
response[key] = values[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
55
packages/nodes-base/nodes/Cortex/JobDescription.ts
Normal file
55
packages/nodes-base/nodes/Cortex/JobDescription.ts
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import {
|
||||||
|
INodeProperties,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
export const jobOperations = [
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
description:'Choose an operation',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'job',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Get',
|
||||||
|
value: 'get',
|
||||||
|
description: 'Get job details',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Report',
|
||||||
|
value: 'report',
|
||||||
|
description: 'Get job report',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'get',
|
||||||
|
},
|
||||||
|
] as INodeProperties[];
|
||||||
|
|
||||||
|
export const jobFields: INodeProperties[] =[
|
||||||
|
{
|
||||||
|
displayName: 'Job ID',
|
||||||
|
name: 'jobId',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
displayOptions:{
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'job',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'get',
|
||||||
|
'report',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default:'',
|
||||||
|
description: 'ID of the job',
|
||||||
|
},
|
||||||
|
];
|
892
packages/nodes-base/nodes/Cortex/ResponderDescription.ts
Normal file
892
packages/nodes-base/nodes/Cortex/ResponderDescription.ts
Normal file
|
@ -0,0 +1,892 @@
|
||||||
|
import {
|
||||||
|
INodeProperties,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
import {
|
||||||
|
TLP,
|
||||||
|
} from './AnalyzerInterface';
|
||||||
|
|
||||||
|
export const respondersOperations = [
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
description: 'Choose an operation',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'responder',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Execute',
|
||||||
|
value: 'execute',
|
||||||
|
description: 'Execute Responder'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
default: 'execute'
|
||||||
|
}
|
||||||
|
] as INodeProperties[];
|
||||||
|
|
||||||
|
export const responderFields: INodeProperties[] = [
|
||||||
|
{
|
||||||
|
displayName: 'Responder Type',
|
||||||
|
name: 'responder',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'loadActiveResponders'
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'responder',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Choose the responder'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Entity Type',
|
||||||
|
name: 'entityType',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'responder',
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'loadDataTypeOptions',
|
||||||
|
loadOptionsDependsOn: [
|
||||||
|
'responder',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'Choose the Data type',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'JSON Parameters',
|
||||||
|
name: 'jsonObject',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Choose between providing JSON object or seperated attributes',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'responder',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Entity Object (JSON)',
|
||||||
|
name: 'objectData',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'responder',
|
||||||
|
],
|
||||||
|
jsonObject: [
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Parameters',
|
||||||
|
name: 'parameters',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
placeholder: 'Add Parameter',
|
||||||
|
required: false,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Case Attributes',
|
||||||
|
name: 'values',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Title',
|
||||||
|
name: 'title',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Title of the case',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Description',
|
||||||
|
name: 'description',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Description of the case',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Severity',
|
||||||
|
name: 'severity',
|
||||||
|
type: 'options',
|
||||||
|
default: 2,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Low',
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Medium',
|
||||||
|
value: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'High',
|
||||||
|
value: 3,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Severity of the case. Default=Medium',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Start Date',
|
||||||
|
name: 'startDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
default: '',
|
||||||
|
description: 'Date and time of the begin of the case default=now',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Owner',
|
||||||
|
name: 'owner',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: `User who owns the case. This is automatically set to current user when status is set to InProgress`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Flag',
|
||||||
|
name: 'flag',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Flag of the case default=false',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'TLP',
|
||||||
|
name: 'tlp',
|
||||||
|
type: 'options',
|
||||||
|
default: 2,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'White',
|
||||||
|
value: TLP.white,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Green',
|
||||||
|
value: TLP.green,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Amber',
|
||||||
|
value: TLP.amber,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Red',
|
||||||
|
value: TLP.red,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Traffict Light Protocol (TLP). Default=Amber',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Tags',
|
||||||
|
name: 'tags',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder:'tag1,tag2,...',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
typeOptions:{
|
||||||
|
loadOptionsDependsOn:[
|
||||||
|
'entityType',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'responder',
|
||||||
|
],
|
||||||
|
jsonObject: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
entityType: [
|
||||||
|
'case',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hide: {
|
||||||
|
entityType: [
|
||||||
|
'',
|
||||||
|
'alert',
|
||||||
|
'case_artifact',
|
||||||
|
'case_task',
|
||||||
|
'case_task_log',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Parameters',
|
||||||
|
name: 'parameters',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
placeholder: 'Add Parameter',
|
||||||
|
required: false,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Alert Attributes',
|
||||||
|
name: 'values',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Title',
|
||||||
|
name: 'title',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Title of the alert',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Description',
|
||||||
|
name: 'description',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Description of the alert',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Severity',
|
||||||
|
name: 'severity',
|
||||||
|
type: 'options',
|
||||||
|
default: 2,
|
||||||
|
options:[
|
||||||
|
{
|
||||||
|
name: 'Low',
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Medium',
|
||||||
|
value: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'High',
|
||||||
|
value: 3,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Severity of the case. Default=Medium',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Date',
|
||||||
|
name: 'date',
|
||||||
|
type: 'dateTime',
|
||||||
|
default: '',
|
||||||
|
description: 'Date and time when the alert was raised default=now',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Tags',
|
||||||
|
name: 'tags',
|
||||||
|
type: 'string',
|
||||||
|
placeholder:'tag1,tag2,...',
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'TLP',
|
||||||
|
name: 'tlp',
|
||||||
|
type: 'options',
|
||||||
|
default: 2,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name:'White',
|
||||||
|
value:TLP.white,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'Green',
|
||||||
|
value:TLP.green,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'Amber',
|
||||||
|
value:TLP.amber,
|
||||||
|
},{
|
||||||
|
name:'Red',
|
||||||
|
value:TLP.red,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: 'Traffict Light Protocol (TLP). Default=Amber',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Status',
|
||||||
|
name: 'status',
|
||||||
|
type: 'options',
|
||||||
|
default: 'New',
|
||||||
|
options:[
|
||||||
|
{
|
||||||
|
name: 'New',
|
||||||
|
value: 'New',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Updated',
|
||||||
|
value: 'Updated',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Ignored',
|
||||||
|
value: 'Ignored'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Imported',
|
||||||
|
value: 'Imported',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Status of the alert. Default=New'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Type',
|
||||||
|
name: 'type',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Type of the alert',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Source',
|
||||||
|
name: 'source',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Source of the alert',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'SourceRef',
|
||||||
|
name: 'sourceRef',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Source reference of the alert',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Follow',
|
||||||
|
name: 'follow',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Artifacts',
|
||||||
|
name: 'artifacts',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
placeholder:'Add an artifact',
|
||||||
|
required: false,
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: true,
|
||||||
|
multipleValueButtonText: 'Add an Artifact',
|
||||||
|
},
|
||||||
|
default: [],
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Artifact',
|
||||||
|
name: 'artifactValues',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Data Type',
|
||||||
|
name: 'dataType',
|
||||||
|
type: 'options',
|
||||||
|
default: '',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Domain',
|
||||||
|
value: 'domain',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'File',
|
||||||
|
value: 'file'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Filename',
|
||||||
|
value: 'filename'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Fqdn',
|
||||||
|
value: 'fqdn'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Hash',
|
||||||
|
value: 'hash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'IP',
|
||||||
|
value: 'ip'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Mail',
|
||||||
|
value: 'mail'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Mail Subject',
|
||||||
|
value: 'mail_subject'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Other',
|
||||||
|
value: 'other'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Regexp',
|
||||||
|
value: 'regexp'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Registry',
|
||||||
|
value: 'registry'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Uri Path',
|
||||||
|
value: 'uri_path'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'URL',
|
||||||
|
value: 'url'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'User Agent',
|
||||||
|
value: 'user-agent'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Data',
|
||||||
|
name: 'data',
|
||||||
|
type: 'string',
|
||||||
|
displayOptions: {
|
||||||
|
hide: {
|
||||||
|
dataType: [
|
||||||
|
'file',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Binary Property',
|
||||||
|
name: 'binaryProperty',
|
||||||
|
type: 'string',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
dataType: [
|
||||||
|
'file',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: 'data',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Message',
|
||||||
|
name: 'message',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Tags',
|
||||||
|
name: 'tags',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
typeOptions:{
|
||||||
|
loadOptionsDependsOn:[
|
||||||
|
'entityType',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'responder',
|
||||||
|
],
|
||||||
|
jsonObject: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
entityType: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hide: {
|
||||||
|
responder: [
|
||||||
|
'',
|
||||||
|
],
|
||||||
|
entityType: [
|
||||||
|
'',
|
||||||
|
'case',
|
||||||
|
'case_artifact',
|
||||||
|
'case_task',
|
||||||
|
'case_task_log',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Parameters',
|
||||||
|
name: 'parameters',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
placeholder: 'Add Parameter',
|
||||||
|
required: false,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Observable Attributes',
|
||||||
|
name: 'values',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'DataType',
|
||||||
|
name: 'dataType',
|
||||||
|
type: 'options',
|
||||||
|
default: '',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Domain',
|
||||||
|
value: 'domain',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'File',
|
||||||
|
value: 'file'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Filename',
|
||||||
|
value: 'filename'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Fqdn',
|
||||||
|
value: 'fqdn'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Hash',
|
||||||
|
value: 'hash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'IP',
|
||||||
|
value: 'ip'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Mail',
|
||||||
|
value: 'mail'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Mail Subject',
|
||||||
|
value: 'mail_subject'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Other',
|
||||||
|
value: 'other'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Regexp',
|
||||||
|
value: 'regexp'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Registry',
|
||||||
|
value: 'registry'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Uri Path',
|
||||||
|
value: 'uri_path'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'URL',
|
||||||
|
value: 'url'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'User Agent',
|
||||||
|
value: 'user-agent'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Data',
|
||||||
|
name: 'data',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
displayOptions:{
|
||||||
|
hide:{
|
||||||
|
dataType:[
|
||||||
|
'file',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Binary Property',
|
||||||
|
name: 'binaryPropertyName',
|
||||||
|
type: 'string',
|
||||||
|
default: 'data',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
dataType:[
|
||||||
|
'file',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Name of the binary property which contains the attachement data',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Message',
|
||||||
|
name: 'message',
|
||||||
|
type: 'string',
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Start Date',
|
||||||
|
name: 'startDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
default: '',
|
||||||
|
description: 'Date and time of the begin of the case default=now',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'TLP',
|
||||||
|
name: 'tlp',
|
||||||
|
type: 'options',
|
||||||
|
default: 2,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name:'White',
|
||||||
|
value:TLP.white,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'Green',
|
||||||
|
value:TLP.green,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'Amber',
|
||||||
|
value:TLP.amber,
|
||||||
|
},{
|
||||||
|
name:'Red',
|
||||||
|
value:TLP.red,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: 'Traffict Light Protocol (TLP). Default=Amber',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'IOC',
|
||||||
|
name: 'ioc',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Indicates if the observable is an IOC (Indicator of compromise)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Status',
|
||||||
|
name: 'status',
|
||||||
|
type: 'options',
|
||||||
|
default: '',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Ok',
|
||||||
|
value: 'Ok',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Deleted',
|
||||||
|
value: 'Deleted',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Status of the observable (Ok or Deleted) default=Ok',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
typeOptions:{
|
||||||
|
loadOptionsDependsOn:[
|
||||||
|
'entityType',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'responder',
|
||||||
|
],
|
||||||
|
jsonObject: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
entityType: [
|
||||||
|
'case_artifact',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hide: {
|
||||||
|
responder: [
|
||||||
|
'',
|
||||||
|
],
|
||||||
|
entityType: [
|
||||||
|
'',
|
||||||
|
'case',
|
||||||
|
'alert',
|
||||||
|
'case_task',
|
||||||
|
'case_task_log',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Parameters',
|
||||||
|
name: 'parameters',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
placeholder: 'Add Parameter',
|
||||||
|
required: false,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Task Attributes',
|
||||||
|
name: 'values',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Title',
|
||||||
|
name: 'title',
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
description: 'Title of the task',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Status',
|
||||||
|
name: 'status',
|
||||||
|
type: 'options',
|
||||||
|
default: 'Waiting',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Waiting',
|
||||||
|
value: 'Waiting',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'InProgress',
|
||||||
|
value: 'InProgress',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Completed',
|
||||||
|
value: 'Completed',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Cancel',
|
||||||
|
value: 'Cancel',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Flag',
|
||||||
|
name: 'flag',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
typeOptions:{
|
||||||
|
loadOptionsDependsOn:[
|
||||||
|
'entityType',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'responder',
|
||||||
|
],
|
||||||
|
jsonObject: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
entityType: [
|
||||||
|
'case_task',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hide: {
|
||||||
|
responder: [
|
||||||
|
'',
|
||||||
|
],
|
||||||
|
entityType: [
|
||||||
|
'',
|
||||||
|
'case',
|
||||||
|
'alert',
|
||||||
|
'case_artifact',
|
||||||
|
'case_task_log',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Parameters',
|
||||||
|
name: 'parameters',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
placeholder: 'Add Parameter',
|
||||||
|
required: false,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Log Attributes',
|
||||||
|
name: 'values',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Message',
|
||||||
|
name: 'message',
|
||||||
|
type: 'string',
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Start Date',
|
||||||
|
name: 'startDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
default: '',
|
||||||
|
description: 'Date and time of the begin of the case default=now',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Status',
|
||||||
|
name: 'status',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Ok',
|
||||||
|
value: 'Ok',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Deleted',
|
||||||
|
value: 'Deleted',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
typeOptions:{
|
||||||
|
loadOptionsDependsOn:[
|
||||||
|
'entityType',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'responder',
|
||||||
|
],
|
||||||
|
jsonObject: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
entityType: [
|
||||||
|
'case_task_log',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hide: {
|
||||||
|
responder: [
|
||||||
|
'',
|
||||||
|
],
|
||||||
|
entityType: [
|
||||||
|
'',
|
||||||
|
'case',
|
||||||
|
'alert',
|
||||||
|
'case_artifact',
|
||||||
|
'case_task',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: {},
|
||||||
|
},
|
||||||
|
];
|
BIN
packages/nodes-base/nodes/Cortex/cortex.png
Normal file
BIN
packages/nodes-base/nodes/Cortex/cortex.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
123
packages/nodes-base/nodes/TheHive/GenericFunctions.ts
Normal file
123
packages/nodes-base/nodes/TheHive/GenericFunctions.ts
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
import {
|
||||||
|
OptionsWithUri,
|
||||||
|
} from 'request';
|
||||||
|
|
||||||
|
import {
|
||||||
|
IExecuteFunctions,
|
||||||
|
IHookFunctions,
|
||||||
|
ILoadOptionsFunctions,
|
||||||
|
} from 'n8n-core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
IDataObject,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
import * as moment from 'moment';
|
||||||
|
|
||||||
|
export async function theHiveApiRequest(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, query: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
|
const credentials = this.getCredentials('theHiveApi');
|
||||||
|
|
||||||
|
if (credentials === undefined) {
|
||||||
|
throw new Error('No credentials got returned!');
|
||||||
|
}
|
||||||
|
|
||||||
|
const headerWithAuthentication = Object.assign({}, { Authorization: `Bearer ${credentials.ApiKey}` });
|
||||||
|
|
||||||
|
let options: OptionsWithUri = {
|
||||||
|
headers: headerWithAuthentication,
|
||||||
|
method,
|
||||||
|
qs: query,
|
||||||
|
uri: uri || `${credentials.url}/api${resource}`,
|
||||||
|
body,
|
||||||
|
json: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Object.keys(option).length !== 0) {
|
||||||
|
options = Object.assign({},options, option);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.keys(body).length === 0) {
|
||||||
|
delete options.body;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.keys(query).length === 0) {
|
||||||
|
delete options.qs;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return await this.helpers.request!(options);
|
||||||
|
} catch (error) {
|
||||||
|
if (error.error ) {
|
||||||
|
const errorMessage = `TheHive error response [${error.statusCode}]: ${error.error.message || error.error.type}`;
|
||||||
|
throw new Error(errorMessage);
|
||||||
|
} else throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helpers functions
|
||||||
|
export function mapResource(resource: string): string {
|
||||||
|
switch (resource) {
|
||||||
|
case 'alert':
|
||||||
|
return 'alert';
|
||||||
|
case 'case':
|
||||||
|
return 'case';
|
||||||
|
case 'observable':
|
||||||
|
return 'case_artifact';
|
||||||
|
case 'task':
|
||||||
|
return 'case_task';
|
||||||
|
case 'log':
|
||||||
|
return 'case_task_log';
|
||||||
|
default:
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function splitTags(tags: string): string[] {
|
||||||
|
return tags.split(',').filter(tag => tag !== ' ' && tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function prepareOptional(optionals: IDataObject): IDataObject {
|
||||||
|
const response: IDataObject = {};
|
||||||
|
for (const key in optionals) {
|
||||||
|
if (optionals[key]!== undefined && optionals[key]!==null && optionals[key]!=='') {
|
||||||
|
if (moment(optionals[key] as string, moment.ISO_8601).isValid()) {
|
||||||
|
response[key] = Date.parse(optionals[key] as string);
|
||||||
|
} else if (key === 'artifacts') {
|
||||||
|
response[key] = JSON.parse(optionals[key] as string);
|
||||||
|
} else if (key === 'tags') {
|
||||||
|
response[key] = splitTags(optionals[key] as string);
|
||||||
|
} else {
|
||||||
|
response[key] = optionals[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function prepareSortQuery(sort: string, body: { query: [IDataObject] }) {
|
||||||
|
if (sort) {
|
||||||
|
const field = sort.substring(1);
|
||||||
|
const value = sort.charAt(0) === '+' ? 'asc' : 'desc';
|
||||||
|
const sortOption: IDataObject = {};
|
||||||
|
sortOption[field] = value;
|
||||||
|
body.query.push(
|
||||||
|
{
|
||||||
|
'_name': 'sort',
|
||||||
|
'_fields': [
|
||||||
|
sortOption,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function prepareRangeQuery(range: string, body: { 'query': Array<{}> }) {
|
||||||
|
if (range && range !== 'all') {
|
||||||
|
body['query'].push(
|
||||||
|
{
|
||||||
|
'_name': 'page',
|
||||||
|
'from': parseInt(range.split('-')[0], 10),
|
||||||
|
'to': parseInt(range.split('-')[1], 10)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
82
packages/nodes-base/nodes/TheHive/QueryFunctions.ts
Normal file
82
packages/nodes-base/nodes/TheHive/QueryFunctions.ts
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
// Query types
|
||||||
|
export declare type queryIndexSignature = '_field'|'_gt'|'_value'|'_gte'|'_lt'|'_lte'|'_and'|'_or'|'_not'|'_in'|'_contains'|'_id'|'_between'|'_parent'|'_parent'|'_child'|'_type'|'_string'|'_like'|'_wildcard';
|
||||||
|
export type IQueryObject = {
|
||||||
|
[key in queryIndexSignature]?: IQueryObject|IQueryObject[]|string|number|object
|
||||||
|
};
|
||||||
|
|
||||||
|
// Query Functions
|
||||||
|
export function Eq(field: string, value: any):IQueryObject{
|
||||||
|
return { '_field': field, '_value': value };
|
||||||
|
}
|
||||||
|
export function Gt(field: string, value: any):IQueryObject{
|
||||||
|
return { '_gt': { field: value } };
|
||||||
|
}
|
||||||
|
export function Gte(field: string, value: any):IQueryObject{
|
||||||
|
return { '_gte': { field: value } };
|
||||||
|
}
|
||||||
|
export function Lt(field: string, value: any):IQueryObject{
|
||||||
|
return { '_lt': { field: value } };
|
||||||
|
}
|
||||||
|
export function Lte(field: string, value: any):IQueryObject{
|
||||||
|
return { '_lte': { field: value } };
|
||||||
|
}
|
||||||
|
export function And(...criteria: IQueryObject[]): IQueryObject{
|
||||||
|
return { '_and': criteria };
|
||||||
|
}
|
||||||
|
export function Or(...criteria: IQueryObject[]): IQueryObject{
|
||||||
|
return { '_or': criteria };
|
||||||
|
}
|
||||||
|
export function Not(criteria: IQueryObject[]): IQueryObject{
|
||||||
|
return { '_not': criteria };
|
||||||
|
}
|
||||||
|
export function In(field: string, values: any[]): IQueryObject{
|
||||||
|
return { '_in': { '_field': field, '_values': values } };
|
||||||
|
}
|
||||||
|
export function Contains(field: string): IQueryObject{
|
||||||
|
return { '_contains': field };
|
||||||
|
}
|
||||||
|
export function Id(id: string|number): IQueryObject{
|
||||||
|
return {'_id': id };
|
||||||
|
}
|
||||||
|
export function Between(field:string, from_value: any, to_value: any): IQueryObject{
|
||||||
|
return {'_between': {'_field': field, '_from': from_value, '_to': to_value } };
|
||||||
|
}
|
||||||
|
export function ParentId(tpe:string, id:string):IQueryObject{
|
||||||
|
return { '_parent': {'_type': tpe, '_id': id } };
|
||||||
|
}
|
||||||
|
export function Parent(tpe:string, criterion:IQueryObject):IQueryObject{
|
||||||
|
return { '_parent': {'_type': tpe, '_query': criterion } };
|
||||||
|
}
|
||||||
|
export function Child(tpe:string, criterion:IQueryObject):IQueryObject{
|
||||||
|
return { '_child': {'_type': tpe, '_query': criterion } };
|
||||||
|
}
|
||||||
|
export function Type(tpe:string):IQueryObject{
|
||||||
|
return { '_type': tpe };
|
||||||
|
}
|
||||||
|
export function queryString(query_string:string):IQueryObject{
|
||||||
|
return { '_string': query_string };
|
||||||
|
}
|
||||||
|
export function Like(field:string, value:string):IQueryObject{
|
||||||
|
return { '_like': { '_field': field, '_value': value } };
|
||||||
|
}
|
||||||
|
export function StartsWith(field:string, value:string){
|
||||||
|
if (!value.startsWith('*')){
|
||||||
|
value = value + '*';
|
||||||
|
}
|
||||||
|
return { '_wildcard': { '_field': field, '_value': value } };
|
||||||
|
}
|
||||||
|
export function EndsWith(field:string, value:string){
|
||||||
|
if (!value.endsWith('*')){
|
||||||
|
value = '*' + value;
|
||||||
|
}
|
||||||
|
return { '_wildcard': { '_field': field, '_value': value } };
|
||||||
|
}
|
||||||
|
export function ContainsString(field:string, value:string){
|
||||||
|
if (!value.endsWith('*')){
|
||||||
|
value = value + '*';
|
||||||
|
}
|
||||||
|
if (!value.startsWith('*')){
|
||||||
|
value = '*' + value;
|
||||||
|
}
|
||||||
|
return { '_wildcard': { '_field': field, '_value': value } };
|
||||||
|
}
|
1971
packages/nodes-base/nodes/TheHive/TheHive.node.ts
Normal file
1971
packages/nodes-base/nodes/TheHive/TheHive.node.ts
Normal file
File diff suppressed because it is too large
Load diff
165
packages/nodes-base/nodes/TheHive/TheHiveTrigger.node.ts
Normal file
165
packages/nodes-base/nodes/TheHive/TheHiveTrigger.node.ts
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
import {
|
||||||
|
IWebhookFunctions,
|
||||||
|
} from 'n8n-core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
IDataObject,
|
||||||
|
INodeTypeDescription,
|
||||||
|
INodeType,
|
||||||
|
IWebhookResponseData,
|
||||||
|
IHookFunctions,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
export class TheHiveTrigger implements INodeType {
|
||||||
|
description: INodeTypeDescription = {
|
||||||
|
displayName: 'TheHive Trigger',
|
||||||
|
name: 'theHiveTrigger',
|
||||||
|
icon: 'file:thehive.png',
|
||||||
|
group: ['trigger'],
|
||||||
|
version: 1,
|
||||||
|
description: 'Starts the workflow when a TheHive event occurs.',
|
||||||
|
defaults: {
|
||||||
|
name: 'TheHive Trigger',
|
||||||
|
color: '#f3d02f',
|
||||||
|
},
|
||||||
|
inputs: [],
|
||||||
|
outputs: ['main'],
|
||||||
|
webhooks: [
|
||||||
|
{
|
||||||
|
name: 'default',
|
||||||
|
httpMethod: 'POST',
|
||||||
|
reponseMode: 'onReceived',
|
||||||
|
path: 'webhook',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
properties: [
|
||||||
|
{
|
||||||
|
displayName: 'Events',
|
||||||
|
name: 'events',
|
||||||
|
type: 'multiOptions',
|
||||||
|
default: [],
|
||||||
|
required: true,
|
||||||
|
description: 'Events types',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: '*',
|
||||||
|
value: '*',
|
||||||
|
description: 'Any time any event is triggered (Wildcard Event).',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Alert Created',
|
||||||
|
value: 'alert_create',
|
||||||
|
description: 'Triggered when an alert is created',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Alert Updated',
|
||||||
|
value: 'alert_update',
|
||||||
|
description: 'Triggered when an alert is updated',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Alert Deleted',
|
||||||
|
value: 'alert_delete',
|
||||||
|
description: 'Triggered when an alert is deleted',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Observable Created',
|
||||||
|
value: 'case_artifact_create',
|
||||||
|
description: 'Triggered when an observable is created',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Observable Updated',
|
||||||
|
value: 'case_artifact_update',
|
||||||
|
description: 'Triggered when an observable is updated',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Observable Deleted',
|
||||||
|
value: 'case_artifact_delete',
|
||||||
|
description: 'Triggered when an observable is deleted',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Case Created',
|
||||||
|
value: 'case_create',
|
||||||
|
description: 'Triggered when a case is created',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Case Updated',
|
||||||
|
value: 'case_update',
|
||||||
|
description: 'Triggered when a case is updated',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Case Deleted',
|
||||||
|
value: 'case_delete',
|
||||||
|
description: 'Triggered when a case is deleted',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Task Created',
|
||||||
|
value: 'case_task_create',
|
||||||
|
description: 'Triggered when a task is created',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Task Updated',
|
||||||
|
value: 'case_task_update',
|
||||||
|
description: 'Triggered when a task is updated',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Task Deleted',
|
||||||
|
value: 'case_task_delete',
|
||||||
|
description: 'Triggered when a task is deleted',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Log Created',
|
||||||
|
value: 'case_task_log_create',
|
||||||
|
description: 'Triggered when a task log is created',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
// @ts-ignore (because of request)
|
||||||
|
webhookMethods = {
|
||||||
|
default: {
|
||||||
|
async checkExists(this: IHookFunctions): Promise<boolean> {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
async create(this: IHookFunctions): Promise<boolean> {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
async delete(this: IHookFunctions): Promise<boolean> {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
async webhook(this: IWebhookFunctions): Promise<IWebhookResponseData> {
|
||||||
|
// Get the request body
|
||||||
|
const bodyData = this.getBodyData();
|
||||||
|
const events = this.getNodeParameter('events', []) as string[];
|
||||||
|
if(!bodyData.operation || !bodyData.objectType) {
|
||||||
|
// Don't start the workflow if mandatory fields are not specified
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't start the workflow if the event is not fired
|
||||||
|
const event = `${(bodyData.objectType as string).toLowerCase()}_${(bodyData.operation as string).toLowerCase()}`;
|
||||||
|
if(events.indexOf('*') === -1 && events.indexOf(event) === -1) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// The data to return and so start the workflow with
|
||||||
|
const returnData: IDataObject[] = [];
|
||||||
|
returnData.push(
|
||||||
|
{
|
||||||
|
event,
|
||||||
|
body: this.getBodyData(),
|
||||||
|
headers: this.getHeaderData(),
|
||||||
|
query: this.getQueryData(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
workflowData: [
|
||||||
|
this.helpers.returnJsonArray(returnData)
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,839 @@
|
||||||
|
import {
|
||||||
|
INodeProperties,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
import {
|
||||||
|
TLP,
|
||||||
|
} from '../interfaces/AlertInterface';
|
||||||
|
|
||||||
|
export const alertOperations = [
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'loadAlertOptions',
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: 'create',
|
||||||
|
},
|
||||||
|
] as INodeProperties[];
|
||||||
|
|
||||||
|
export const alertFields = [
|
||||||
|
{
|
||||||
|
displayName: 'Return All',
|
||||||
|
name: 'returnAll',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'If all results should be returned or only up to a given limit.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Limit',
|
||||||
|
name: 'limit',
|
||||||
|
type: 'number',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
returnAll: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typeOptions: {
|
||||||
|
minValue: 1,
|
||||||
|
maxValue: 500,
|
||||||
|
},
|
||||||
|
default: 100,
|
||||||
|
description: 'How many results to return.',
|
||||||
|
},
|
||||||
|
// required attributs
|
||||||
|
{
|
||||||
|
displayName: 'Alert ID',
|
||||||
|
name: 'id',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert'
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'promote',
|
||||||
|
'merge',
|
||||||
|
'update',
|
||||||
|
'executeResponder',
|
||||||
|
'get',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Title of the alert'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Case ID',
|
||||||
|
name: 'caseId',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'merge',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Title',
|
||||||
|
name: 'title',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Title of the alert',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Description',
|
||||||
|
name: 'description',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Description of the alert',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Severity',
|
||||||
|
name: 'severity',
|
||||||
|
type: 'options',
|
||||||
|
options:[
|
||||||
|
{
|
||||||
|
name: 'Low',
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Medium',
|
||||||
|
value: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'High',
|
||||||
|
value: 3,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
required: true,
|
||||||
|
default: 2,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Severity of the alert. Default=Medium',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Date',
|
||||||
|
name: 'date',
|
||||||
|
type: 'dateTime',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Date and time when the alert was raised default=now'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Tags',
|
||||||
|
name: 'tags',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
placeholder:'tag,tag2,tag3...',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Case Tags'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'TLP',
|
||||||
|
name: 'tlp',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
default: 2,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name:'White',
|
||||||
|
value:TLP.white,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'Green',
|
||||||
|
value:TLP.green,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'Amber',
|
||||||
|
value:TLP.amber,
|
||||||
|
},{
|
||||||
|
name:'Red',
|
||||||
|
value:TLP.red,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Traffict Light Protocol (TLP). Default=Amber'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Status',
|
||||||
|
name: 'status',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
options:[
|
||||||
|
{
|
||||||
|
name: 'New',
|
||||||
|
value: 'New',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Updated',
|
||||||
|
value: 'Updated',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Ignored',
|
||||||
|
value: 'Ignored'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Imported',
|
||||||
|
value: 'Imported',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'New',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Status of the alert',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Type',
|
||||||
|
name: 'type',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Type of the alert'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Source',
|
||||||
|
name: 'source',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Source of the alert'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'SourceRef',
|
||||||
|
name: 'sourceRef',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Source reference of the alert'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Follow',
|
||||||
|
name: 'follow',
|
||||||
|
type: 'boolean',
|
||||||
|
required: true,
|
||||||
|
default: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'if true, the alert becomes active when updated default=true',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Artifacts',
|
||||||
|
name: 'artifactUi',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
placeholder: 'Add Artifact',
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: true,
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Artifact',
|
||||||
|
name: 'artifactValues',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Data Type',
|
||||||
|
name: 'dataType',
|
||||||
|
type: 'options',
|
||||||
|
default: '',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'IP',
|
||||||
|
value: 'ip',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Domain',
|
||||||
|
value: 'domain',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'File',
|
||||||
|
value: 'file',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Data',
|
||||||
|
name: 'data',
|
||||||
|
type: 'string',
|
||||||
|
displayOptions: {
|
||||||
|
hide: {
|
||||||
|
dataType: [
|
||||||
|
'file',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Binary Property',
|
||||||
|
name: 'binaryProperty',
|
||||||
|
type: 'string',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
dataType: [
|
||||||
|
'file',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: 'data',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Message',
|
||||||
|
name: 'message',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Case Tags',
|
||||||
|
name: 'tags',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Artifact attributes'
|
||||||
|
},
|
||||||
|
// required for responder execution
|
||||||
|
{
|
||||||
|
displayName: 'Responder ID',
|
||||||
|
name: 'responder',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsDependsOn: [
|
||||||
|
'id',
|
||||||
|
],
|
||||||
|
loadOptionsMethod: 'loadResponders',
|
||||||
|
},
|
||||||
|
displayOptions:{
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'executeResponder',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hide: {
|
||||||
|
id: [
|
||||||
|
'',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// optional attributs (Create, Promote operations)
|
||||||
|
{
|
||||||
|
displayName: 'Additional Fields',
|
||||||
|
name: 'additionalFields',
|
||||||
|
placeholder: 'Add Field',
|
||||||
|
type: 'collection',
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
'promote',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options:[
|
||||||
|
{
|
||||||
|
displayName: 'Case Template',
|
||||||
|
name: 'caseTemplate',
|
||||||
|
type:'string',
|
||||||
|
default: '',
|
||||||
|
description: `Case template to use when a case is created from this alert`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// optional attributs (Update operation)
|
||||||
|
{
|
||||||
|
displayName: 'Update Fields',
|
||||||
|
name: 'updateFields',
|
||||||
|
type: 'collection',
|
||||||
|
placeholder: 'Add Field',
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'update',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Artifacts',
|
||||||
|
name: 'artifactUi',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
placeholder: 'Add Artifact',
|
||||||
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: true,
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Artifact',
|
||||||
|
name: 'artifactValues',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Data Type',
|
||||||
|
name: 'dataType',
|
||||||
|
type: 'options',
|
||||||
|
default: '',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'IP',
|
||||||
|
value: 'ip',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Domain',
|
||||||
|
value: 'domain',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'File',
|
||||||
|
value: 'file',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Data',
|
||||||
|
name: 'data',
|
||||||
|
type: 'string',
|
||||||
|
displayOptions: {
|
||||||
|
hide: {
|
||||||
|
dataType: [
|
||||||
|
'file',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Binary Property',
|
||||||
|
name: 'binaryProperty',
|
||||||
|
type: 'string',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
dataType: [
|
||||||
|
'file',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: 'data',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Message',
|
||||||
|
name: 'message',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Case Tags',
|
||||||
|
name: 'tags',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Case Template',
|
||||||
|
name: 'caseTemplate',
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
description: `Case template to use when a case is created from this alert`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Description',
|
||||||
|
name: 'description',
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
description: 'Description of the alert',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Follow',
|
||||||
|
name: 'follow',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
description: 'if true, the alert becomes active when updated default=true',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Severity',
|
||||||
|
name: ' severity',
|
||||||
|
type: 'options',
|
||||||
|
options:[
|
||||||
|
{
|
||||||
|
name: 'Low',
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Medium',
|
||||||
|
value: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'High',
|
||||||
|
value: 3,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 2,
|
||||||
|
description: 'Severity of the alert. Default=Medium',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Status',
|
||||||
|
name: 'status',
|
||||||
|
type: 'options',
|
||||||
|
options:[
|
||||||
|
{
|
||||||
|
name: 'New',
|
||||||
|
value: 'New',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'Updated',
|
||||||
|
value:'Updated',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Ignored',
|
||||||
|
value:'Ignored',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'Imported',
|
||||||
|
value:'Imported',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'New',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Case Tags',
|
||||||
|
name: 'tags',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder:'tag,tag2,tag3...',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Title',
|
||||||
|
name: 'title',
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
description: 'Title of the alert'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'TLP',
|
||||||
|
name: 'tlp',
|
||||||
|
type: 'options',
|
||||||
|
required: false,
|
||||||
|
default: 2,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'White',
|
||||||
|
value: TLP.white,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Green',
|
||||||
|
value: TLP.green,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Amber',
|
||||||
|
value: TLP.amber,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Red',
|
||||||
|
value: TLP.red,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Traffict Light Protocol (TLP). Default=Amber'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
//Query attributs (Search operation)
|
||||||
|
{
|
||||||
|
displayName: 'Options',
|
||||||
|
name: 'options',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'alert',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: 'collection',
|
||||||
|
placeholder: 'Add Option',
|
||||||
|
default: {},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Sort',
|
||||||
|
name: 'sort',
|
||||||
|
type: 'string',
|
||||||
|
placeholder: '±Attribut, exp +status',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Filters',
|
||||||
|
name: 'filters',
|
||||||
|
placeholder: 'Add Filter',
|
||||||
|
default: {},
|
||||||
|
type: 'collection',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'alert'
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
'count',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options:[
|
||||||
|
{
|
||||||
|
displayName: 'Description',
|
||||||
|
name: 'description',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Description of the alert',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Follow',
|
||||||
|
name: 'follow',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'if true, the alert becomes active when updated default=true',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Severity',
|
||||||
|
name: 'severity',
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Low',
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Medium',
|
||||||
|
value: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'High',
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 2,
|
||||||
|
description: 'Severity of the alert. Default=Medium',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Tags',
|
||||||
|
name: 'tags',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'tag,tag2,tag3...',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Title',
|
||||||
|
name: 'title',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'TLP',
|
||||||
|
name: 'tlp',
|
||||||
|
type: 'options',
|
||||||
|
default: 2,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name:'White',
|
||||||
|
value:TLP.white,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'Green',
|
||||||
|
value:TLP.green,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'Amber',
|
||||||
|
value:TLP.amber,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'Red',
|
||||||
|
value:TLP.red,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
description: 'Traffict Light Protocol (TLP). Default=Amber'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
] as INodeProperties[];
|
|
@ -0,0 +1,757 @@
|
||||||
|
import {
|
||||||
|
INodeProperties,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
import {
|
||||||
|
TLP,
|
||||||
|
} from '../interfaces/AlertInterface';
|
||||||
|
|
||||||
|
export const caseOperations = [
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
default: 'getAll',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'case',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsDependsOn: [
|
||||||
|
'resource',
|
||||||
|
],
|
||||||
|
loadOptionsMethod: 'loadCaseOptions',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] as INodeProperties[];
|
||||||
|
|
||||||
|
export const caseFields = [
|
||||||
|
{
|
||||||
|
displayName: 'Return All',
|
||||||
|
name: 'returnAll',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'case',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'If all results should be returned or only up to a given limit.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Limit',
|
||||||
|
name: 'limit',
|
||||||
|
type: 'number',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'case',
|
||||||
|
],
|
||||||
|
returnAll: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typeOptions: {
|
||||||
|
minValue: 1,
|
||||||
|
maxValue: 500,
|
||||||
|
},
|
||||||
|
default: 100,
|
||||||
|
description: 'How many results to return.',
|
||||||
|
},
|
||||||
|
// Required fields
|
||||||
|
{
|
||||||
|
displayName: 'Case ID',
|
||||||
|
name: 'id',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'case',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'update',
|
||||||
|
'executeResponder',
|
||||||
|
'get',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'ID of the case',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Title',
|
||||||
|
name: 'title',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'case',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Title of the case',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Description',
|
||||||
|
name: 'description',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'case',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Description of the case',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Severity',
|
||||||
|
name: 'severity',
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Low',
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Medium',
|
||||||
|
value: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'High',
|
||||||
|
value: 3,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
required: true,
|
||||||
|
default: 2,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'case',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Severity of the alert. Default=Medium',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Start Date',
|
||||||
|
name: 'startDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'case',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Date and time of the begin of the case default=now',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Owner',
|
||||||
|
name: 'owner',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'case',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Flag',
|
||||||
|
name: 'flag',
|
||||||
|
type: 'boolean',
|
||||||
|
required: true,
|
||||||
|
default: false,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'case',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Flag of the case default=false',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'TLP',
|
||||||
|
name: 'tlp',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
default: 2,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'White',
|
||||||
|
value: TLP.white,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Green',
|
||||||
|
value: TLP.green,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Amber',
|
||||||
|
value: TLP.amber,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Red',
|
||||||
|
value: TLP.red,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'case',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Traffict Light Protocol (TLP). Default=Amber'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Tags',
|
||||||
|
name: 'tags',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'case',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// required for responder execution
|
||||||
|
{
|
||||||
|
displayName: 'Responder ID',
|
||||||
|
name: 'responder',
|
||||||
|
type: 'options',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsDependsOn: [
|
||||||
|
'id',
|
||||||
|
],
|
||||||
|
loadOptionsMethod: 'loadResponders',
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'case',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'executeResponder',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hide: {
|
||||||
|
id: [
|
||||||
|
'',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Optional fields (Create operation)
|
||||||
|
{
|
||||||
|
displayName: 'Options',
|
||||||
|
type: 'collection',
|
||||||
|
name: 'options',
|
||||||
|
placeholder: 'Add options',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'case',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'End Date',
|
||||||
|
name: 'endDate',
|
||||||
|
default: '',
|
||||||
|
type: 'dateTime',
|
||||||
|
description: 'Resolution date',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Summary',
|
||||||
|
name: 'summary',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Summary of the case, to be provided when closing a case',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Metrics (JSON)',
|
||||||
|
name: 'metrics',
|
||||||
|
default: '[]',
|
||||||
|
type: 'json',
|
||||||
|
description: 'List of metrics',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Optional fields (Update operations)
|
||||||
|
{
|
||||||
|
displayName: 'Update Fields',
|
||||||
|
type: 'collection',
|
||||||
|
name: 'updateFields',
|
||||||
|
placeholder: 'Add Field',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'case',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'update',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Description',
|
||||||
|
name: 'description',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Description of the case',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'End Date',
|
||||||
|
name: 'endDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
default: '',
|
||||||
|
description: 'Resolution date',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Flag',
|
||||||
|
name: 'flag',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Flag of the case default=false',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Impact Status',
|
||||||
|
name: 'impactStatus',
|
||||||
|
type: 'options',
|
||||||
|
default: '',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'No Impact',
|
||||||
|
value: 'NoImpact'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'With Impact',
|
||||||
|
value: 'WithImpact'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Not Applicable',
|
||||||
|
value: 'NotApplicable'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Impact status of the case',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Metrics (JSON)',
|
||||||
|
name: 'metrics',
|
||||||
|
type: 'json',
|
||||||
|
default: '[]',
|
||||||
|
description: 'List of metrics',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Owner',
|
||||||
|
name: 'owner',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Resolution Status',
|
||||||
|
name: 'resolutionStatus',
|
||||||
|
type: 'options',
|
||||||
|
default: '',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: 'Indeterminate',
|
||||||
|
name: 'Indeterminate'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'False Positive',
|
||||||
|
name: 'FalsePositive'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'True Positive',
|
||||||
|
name: 'TruePositive'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Other',
|
||||||
|
name: 'Other'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Duplicated',
|
||||||
|
name: 'Duplicated'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Resolution status of the case',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Severity',
|
||||||
|
name: 'severity',
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Low',
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Medium',
|
||||||
|
value: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'High',
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 2,
|
||||||
|
description: 'Severity of the alert. Default=Medium',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Start Date',
|
||||||
|
name: 'startDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
default: '',
|
||||||
|
description: 'Date and time of the begin of the case default=now',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Status',
|
||||||
|
name: 'status',
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Open',
|
||||||
|
value: 'Open',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Resolved',
|
||||||
|
value: 'Resolved',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Deleted',
|
||||||
|
value: 'Deleted',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'Open',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Summary',
|
||||||
|
name: 'summary',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Summary of the case, to be provided when closing a case'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Tags',
|
||||||
|
name: 'tags',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Title',
|
||||||
|
name: 'title',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Title of the case',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'TLP',
|
||||||
|
name: 'tlp',
|
||||||
|
type: 'options',
|
||||||
|
default: 2,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'White',
|
||||||
|
value: TLP.white,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Green',
|
||||||
|
value: TLP.green,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Amber',
|
||||||
|
value: TLP.amber,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Red',
|
||||||
|
value: TLP.red,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Traffict Light Protocol (TLP). Default=Amber'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// query options
|
||||||
|
{
|
||||||
|
displayName: 'Options',
|
||||||
|
name: 'options',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'case',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: 'collection',
|
||||||
|
placeholder: 'Add Option',
|
||||||
|
default: {},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Sort',
|
||||||
|
name: 'sort',
|
||||||
|
type: 'string',
|
||||||
|
placeholder: '±Attribut, exp +status',
|
||||||
|
description: 'Specify the sorting attribut, + for asc, - for desc',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Query filters
|
||||||
|
{
|
||||||
|
displayName: 'Filters',
|
||||||
|
name: 'filters',
|
||||||
|
type: 'collection',
|
||||||
|
required: false,
|
||||||
|
default: {},
|
||||||
|
placeholder: 'Add a Filter',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'case'
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
'count',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Description',
|
||||||
|
name: 'description',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Description of the case',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'End Date',
|
||||||
|
name: 'endDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
default: '',
|
||||||
|
description: 'Resolution date',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Flag',
|
||||||
|
name: 'flag',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Flag of the case default=false',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Impact Status',
|
||||||
|
name: 'impactStatus',
|
||||||
|
type: 'options',
|
||||||
|
default: '',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'No Impact',
|
||||||
|
value: 'NoImpact',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'With Impact',
|
||||||
|
value: 'WithImpact',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Not Applicable',
|
||||||
|
value: 'NotApplicable',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Owner',
|
||||||
|
name: 'owner',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Resolution Status',
|
||||||
|
name: 'resolutionStatus',
|
||||||
|
type: 'options',
|
||||||
|
default: '',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: 'Indeterminate',
|
||||||
|
name: 'Indeterminate',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'False Positive',
|
||||||
|
name: 'FalsePositive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'True Positive',
|
||||||
|
name: 'TruePositive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Other',
|
||||||
|
name: 'Other',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Duplicated',
|
||||||
|
name: 'Duplicated',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Severity',
|
||||||
|
name: 'severity',
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Low',
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Medium',
|
||||||
|
value: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'High',
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 2,
|
||||||
|
description: 'Severity of the alert. Default=Medium',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Start Date',
|
||||||
|
name: 'startDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
default: '',
|
||||||
|
description: 'Date and time of the begin of the case default=now',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Status',
|
||||||
|
name: 'status',
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Open',
|
||||||
|
value: 'Open',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Resolved',
|
||||||
|
value: 'Resolved',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Deleted',
|
||||||
|
value: 'Deleted',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'Open',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Summary',
|
||||||
|
name: 'summary',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Summary of the case, to be provided when closing a case',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Tags',
|
||||||
|
name: 'tags',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Title',
|
||||||
|
name: 'title',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Title of the case',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'TLP',
|
||||||
|
name: 'tlp',
|
||||||
|
type: 'options',
|
||||||
|
required: false,
|
||||||
|
default: 2,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'White',
|
||||||
|
value: TLP.white,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Green',
|
||||||
|
value: TLP.green,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Amber',
|
||||||
|
value: TLP.amber,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Red',
|
||||||
|
value: TLP.red,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Traffict Light Protocol (TLP). Default=Amber',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
] as INodeProperties[];
|
262
packages/nodes-base/nodes/TheHive/descriptions/LogDescription.ts
Normal file
262
packages/nodes-base/nodes/TheHive/descriptions/LogDescription.ts
Normal file
|
@ -0,0 +1,262 @@
|
||||||
|
import {
|
||||||
|
INodeProperties,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
export const logOperations = [
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
default: 'getAll',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'log',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Create',
|
||||||
|
value: 'create',
|
||||||
|
description: 'Create task log',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Execute Responder',
|
||||||
|
value: 'executeResponder',
|
||||||
|
description: 'Execute a responder on a selected log'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Get All',
|
||||||
|
value: 'getAll',
|
||||||
|
description: 'Get all task logs'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Get',
|
||||||
|
value: 'get',
|
||||||
|
description: 'Get a single log',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
] as INodeProperties[];
|
||||||
|
|
||||||
|
export const logFields = [
|
||||||
|
{
|
||||||
|
displayName: 'Task ID',
|
||||||
|
name: 'taskId',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'log',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'ID of the task',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Return All',
|
||||||
|
name: 'returnAll',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'log',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'If all results should be returned or only up to a given limit.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Limit',
|
||||||
|
name: 'limit',
|
||||||
|
type: 'number',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'log',
|
||||||
|
],
|
||||||
|
returnAll: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typeOptions: {
|
||||||
|
minValue: 1,
|
||||||
|
maxValue: 500,
|
||||||
|
},
|
||||||
|
default: 100,
|
||||||
|
description: 'How many results to return.',
|
||||||
|
},
|
||||||
|
// required attributs
|
||||||
|
{
|
||||||
|
displayName: 'Log ID',
|
||||||
|
name: 'id',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'log',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'executeResponder',
|
||||||
|
'get',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Message',
|
||||||
|
name: 'message',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'log',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Content of the Log',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Start Date',
|
||||||
|
name: 'startDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'log',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Date of the log submission default=now',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Status',
|
||||||
|
name: 'status',
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Ok',
|
||||||
|
value: 'Ok',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Deleted',
|
||||||
|
value: 'Deleted',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'log',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Status of the log (Ok or Deleted) default=Ok',
|
||||||
|
},
|
||||||
|
// required for responder execution
|
||||||
|
{
|
||||||
|
displayName: 'Responder ID',
|
||||||
|
name: 'responder',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsDependsOn: [
|
||||||
|
'id',
|
||||||
|
],
|
||||||
|
loadOptionsMethod: 'loadResponders'
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'log',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'executeResponder',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hide: {
|
||||||
|
id: [
|
||||||
|
'',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Optional attributs
|
||||||
|
{
|
||||||
|
displayName: 'Options',
|
||||||
|
name: 'options',
|
||||||
|
type: 'collection',
|
||||||
|
default: {},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'log',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
placeholder: 'Add Option',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Attachment',
|
||||||
|
name: 'attachmentValues',
|
||||||
|
placeholder: 'Add Attachment',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: false,
|
||||||
|
},
|
||||||
|
default: {},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Attachment',
|
||||||
|
name: 'attachmentValues',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Binary Property',
|
||||||
|
name: 'binaryProperty',
|
||||||
|
type: 'string',
|
||||||
|
default: 'data',
|
||||||
|
description: 'Object property name which holds binary data.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'File attached to the log',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
] as INodeProperties[];
|
|
@ -0,0 +1,787 @@
|
||||||
|
import {
|
||||||
|
INodeProperties,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
import {
|
||||||
|
TLP,
|
||||||
|
} from '../interfaces/AlertInterface';
|
||||||
|
|
||||||
|
export const observableOperations = [
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
default: 'getAll',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsDependsOn: [
|
||||||
|
'resource',
|
||||||
|
],
|
||||||
|
loadOptionsMethod: 'loadObservableOptions',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] as INodeProperties[];
|
||||||
|
|
||||||
|
export const observableFields = [
|
||||||
|
{
|
||||||
|
displayName: 'Case ID',
|
||||||
|
name: 'caseId',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'ID of the case',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Return All',
|
||||||
|
name: 'returnAll',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
'search',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'If all results should be returned or only up to a given limit.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Limit',
|
||||||
|
name: 'limit',
|
||||||
|
type: 'number',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
'search',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
returnAll: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typeOptions: {
|
||||||
|
minValue: 1,
|
||||||
|
maxValue: 500,
|
||||||
|
},
|
||||||
|
default: 100,
|
||||||
|
description: 'How many results to return.',
|
||||||
|
},
|
||||||
|
// required attributs
|
||||||
|
{
|
||||||
|
displayName: 'Observable ID',
|
||||||
|
name: 'id',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'update',
|
||||||
|
'executeResponder',
|
||||||
|
'executeAnalyzer',
|
||||||
|
'get',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'ID of the observable',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Data Type',
|
||||||
|
name: 'dataType',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'domain',
|
||||||
|
value: 'domain',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'file',
|
||||||
|
value: 'file'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'filename',
|
||||||
|
value: 'filename'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'fqdn',
|
||||||
|
value: 'fqdn'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'hash',
|
||||||
|
value: 'hash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ip',
|
||||||
|
value: 'ip'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'mail',
|
||||||
|
value: 'mail'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'mail_subject',
|
||||||
|
value: 'mail_subject'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'other',
|
||||||
|
value: 'other'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'regexp',
|
||||||
|
value: 'regexp'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'registry',
|
||||||
|
value: 'registry'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'uri_path',
|
||||||
|
value: 'uri_path'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'url',
|
||||||
|
value: 'url'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'user-agent',
|
||||||
|
value: 'user-agent'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
'executeAnalyzer',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Type of the observable',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Data',
|
||||||
|
name: 'data',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hide: {
|
||||||
|
dataType: [
|
||||||
|
'file',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Binary Property',
|
||||||
|
name: 'binaryProperty',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: 'data',
|
||||||
|
description: 'Binary Property that represent the attachment file',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
dataType: [
|
||||||
|
'file',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Message',
|
||||||
|
name: 'message',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'observable'
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Description of the observable in the context of the case',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Start Date',
|
||||||
|
name: 'startDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Date and time of the begin of the case default=now',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'TLP',
|
||||||
|
name: 'tlp',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
default: 2,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'White',
|
||||||
|
value: TLP.white,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Green',
|
||||||
|
value: TLP.green,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Amber',
|
||||||
|
value: TLP.amber,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Red',
|
||||||
|
value: TLP.red,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Traffict Light Protocol (TLP). Default=Amber',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'IOC',
|
||||||
|
name: 'ioc',
|
||||||
|
type: 'boolean',
|
||||||
|
required: true,
|
||||||
|
default: false,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Indicates if the observable is an IOC (Indicator of compromise)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Sighted',
|
||||||
|
name: 'sighted',
|
||||||
|
type: 'boolean',
|
||||||
|
required: true,
|
||||||
|
default: false,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Sighted previously',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Status',
|
||||||
|
name: 'status',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Ok',
|
||||||
|
value: 'Ok',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Deleted',
|
||||||
|
value: 'Deleted',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Status of the observable. Default=Ok',
|
||||||
|
},
|
||||||
|
// required for analyzer execution
|
||||||
|
{
|
||||||
|
displayName: 'Analyzer',
|
||||||
|
name: 'analyzers',
|
||||||
|
type: 'multiOptions',
|
||||||
|
required: true,
|
||||||
|
default: [],
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsDependsOn: [
|
||||||
|
'id',
|
||||||
|
'dataType',
|
||||||
|
],
|
||||||
|
loadOptionsMethod: 'loadAnalyzers',
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'executeAnalyzer',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hide: {
|
||||||
|
id: [
|
||||||
|
'',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// required for responder execution
|
||||||
|
{
|
||||||
|
displayName: 'Responder ID',
|
||||||
|
name: 'responder',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsDependsOn: [
|
||||||
|
'id',
|
||||||
|
],
|
||||||
|
loadOptionsMethod: 'loadResponders',
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'executeResponder',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hide: {
|
||||||
|
id: [
|
||||||
|
'',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Optional attributes (Create operation)
|
||||||
|
{
|
||||||
|
displayName: 'Options',
|
||||||
|
name: 'options',
|
||||||
|
type: 'collection',
|
||||||
|
placeholder: 'Add Option',
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Observable Tags',
|
||||||
|
name: 'tags',
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
placeholder: 'tag1,tag2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Optional attributes (Update operation)
|
||||||
|
{
|
||||||
|
displayName: 'Update Fields',
|
||||||
|
name: 'updateFields',
|
||||||
|
type: 'collection',
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'update',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Message',
|
||||||
|
name: 'message',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Description of the observable in the context of the case',
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Observable Tags',
|
||||||
|
name: 'tags',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'tag1,tag2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'TLP',
|
||||||
|
name: 'tlp',
|
||||||
|
type: 'options',
|
||||||
|
default: 2,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'White',
|
||||||
|
value: TLP.white,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Green',
|
||||||
|
value: TLP.green,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Amber',
|
||||||
|
value: TLP.amber,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Red',
|
||||||
|
value: TLP.red,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Traffict Light Protocol (TLP). Default=Amber',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'IOC',
|
||||||
|
name: 'ioc',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Indicates if the observable is an IOC (Indicator of compromise)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Sighted',
|
||||||
|
name: 'sighted',
|
||||||
|
description: 'sighted previously',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Status',
|
||||||
|
name: 'status',
|
||||||
|
type: 'options',
|
||||||
|
default: '',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Ok',
|
||||||
|
value: 'Ok',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Deleted',
|
||||||
|
value: 'Deleted',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Status of the observable. Default=Ok',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// query options
|
||||||
|
{
|
||||||
|
displayName: 'Options',
|
||||||
|
name: 'options',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
'search',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: 'collection',
|
||||||
|
placeholder: 'Add Option',
|
||||||
|
default: {},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Sort',
|
||||||
|
name: 'sort',
|
||||||
|
type: 'string',
|
||||||
|
placeholder: '±Attribut, exp +status',
|
||||||
|
description: 'Specify the sorting attribut, + for asc, - for desc',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// query attributes
|
||||||
|
{
|
||||||
|
displayName: 'Filters',
|
||||||
|
name: 'filters',
|
||||||
|
type: 'collection',
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
placeholder: 'Add Filter',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'observable',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'search',
|
||||||
|
'count',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Data Type',
|
||||||
|
name: 'dataType',
|
||||||
|
type: 'multiOptions',
|
||||||
|
default: [],
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'domain',
|
||||||
|
value: 'domain'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'file',
|
||||||
|
value: 'file'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'filename',
|
||||||
|
value: 'filename'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'fqdn',
|
||||||
|
value: 'fqdn'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'hash',
|
||||||
|
value: 'hash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ip',
|
||||||
|
value: 'ip'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'mail',
|
||||||
|
value: 'mail'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'mail_subject',
|
||||||
|
value: 'mail_subject'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'other',
|
||||||
|
value: 'other'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'regexp',
|
||||||
|
value: 'regexp'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'registry',
|
||||||
|
value: 'registry'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'uri_path',
|
||||||
|
value: 'uri_path'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'url',
|
||||||
|
value: 'url'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'user-agent',
|
||||||
|
value: 'user-agent'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Type of the observable',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Date range',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
name: 'range',
|
||||||
|
default: {},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Add date range inputs',
|
||||||
|
name: 'dateRange',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'From date',
|
||||||
|
name: 'fromDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'To date',
|
||||||
|
name: 'toDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Description',
|
||||||
|
name: 'description',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'exp,freetext',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'IOC',
|
||||||
|
name: 'ioc',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Indicates if the observable is an IOC (Indicator of compromise)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Keyword',
|
||||||
|
name: 'keyword',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'exp,freetext',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Message',
|
||||||
|
name: 'message',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Description of the observable in the context of the case',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Observable Tags',
|
||||||
|
name: 'tags',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'tag1,tag2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Sighted',
|
||||||
|
name: 'sighted',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Status',
|
||||||
|
displayName: 'Status',
|
||||||
|
type: 'options',
|
||||||
|
default: '',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Ok',
|
||||||
|
value: 'Ok',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Deleted',
|
||||||
|
value: 'Deleted',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Status of the observable. Default=Ok',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'TLP',
|
||||||
|
name: 'tlp',
|
||||||
|
type: 'options',
|
||||||
|
default: 2,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'White',
|
||||||
|
value: TLP.white,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Green',
|
||||||
|
value: TLP.green,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Amber',
|
||||||
|
value: TLP.amber,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Red',
|
||||||
|
value: TLP.red,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Traffict Light Protocol (TLP). Default=Amber',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Value',
|
||||||
|
name: 'data',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'example.com; 8.8.8.8',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
] as INodeProperties[];
|
|
@ -0,0 +1,468 @@
|
||||||
|
import {
|
||||||
|
INodeProperties,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
export const taskOperations = [
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
default: 'getAll',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'task',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsDependsOn: [
|
||||||
|
'operation',
|
||||||
|
],
|
||||||
|
loadOptionsMethod: 'loadTaskOptions',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] as INodeProperties[];
|
||||||
|
|
||||||
|
export const taskFields = [
|
||||||
|
{
|
||||||
|
displayName: 'Task ID',
|
||||||
|
name: 'id',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'task',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'update',
|
||||||
|
'executeResponder',
|
||||||
|
'get',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'ID of the taks',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Case ID',
|
||||||
|
name: 'caseId',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'task',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Return All',
|
||||||
|
name: 'returnAll',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'search',
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'task',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'If all results should be returned or only up to a given limit.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Limit',
|
||||||
|
name: 'limit',
|
||||||
|
type: 'number',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'search',
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'task',
|
||||||
|
],
|
||||||
|
returnAll: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typeOptions: {
|
||||||
|
minValue: 1,
|
||||||
|
maxValue: 500,
|
||||||
|
},
|
||||||
|
default: 100,
|
||||||
|
description: 'How many results to return.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Title',
|
||||||
|
name: 'title',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'task',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Task details',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Status',
|
||||||
|
name: 'status',
|
||||||
|
type: 'options',
|
||||||
|
default: 'Waiting',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Waiting',
|
||||||
|
value: 'Waiting',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'InProgress',
|
||||||
|
value: 'InProgress',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Completed',
|
||||||
|
value: 'Completed',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Cancel',
|
||||||
|
value: 'Cancel',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'task',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Status of the task. Default=Waiting',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Flag',
|
||||||
|
name: 'flag',
|
||||||
|
type: 'boolean',
|
||||||
|
required: true,
|
||||||
|
default: false,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'task',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Flag of the task. Default=false',
|
||||||
|
},
|
||||||
|
// required for responder execution
|
||||||
|
{
|
||||||
|
displayName: 'Responder ID',
|
||||||
|
name: 'responder',
|
||||||
|
type: 'options',
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsDependsOn: [
|
||||||
|
'id',
|
||||||
|
],
|
||||||
|
loadOptionsMethod: 'loadResponders',
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'task',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'executeResponder',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hide: {
|
||||||
|
id: [
|
||||||
|
'',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// optional attributes (Create operations)
|
||||||
|
{
|
||||||
|
displayName: 'Options',
|
||||||
|
type: 'collection',
|
||||||
|
name: 'options',
|
||||||
|
placeholder: 'Add Option',
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'task',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Description',
|
||||||
|
name: 'description',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Task details',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'End Date',
|
||||||
|
name: 'endDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
default: '',
|
||||||
|
description: 'Date of the end of the task. This is automatically set when status is set to Completed',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Owner',
|
||||||
|
name: 'owner',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: `User who owns the task. This is automatically set to current user when status is set to InProgress`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Start Date',
|
||||||
|
name: 'startDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
default: '',
|
||||||
|
description: 'Date of the beginning of the task. This is automatically set when status is set to Open',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// optional attributes (Update operation)
|
||||||
|
|
||||||
|
{
|
||||||
|
displayName: 'Update Fields',
|
||||||
|
type: 'collection',
|
||||||
|
name: 'updateFields',
|
||||||
|
placeholder: 'Add Field',
|
||||||
|
default: '',
|
||||||
|
required: false,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'task',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'update',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Description',
|
||||||
|
name: 'description',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Task details',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'End Date',
|
||||||
|
name: 'endDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
default: '',
|
||||||
|
description: 'Date of the end of the task. This is automatically set when status is set to Completed',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Flag',
|
||||||
|
name: 'flag',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Flag of the task. Default=false',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Owner',
|
||||||
|
name: 'owner',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: `User who owns the task. This is automatically set to current user when status is set to InProgress`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Start Date',
|
||||||
|
name: 'startDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
default: '',
|
||||||
|
description: 'Date of the beginning of the task. This is automatically set when status is set to Open',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'status',
|
||||||
|
name: 'status',
|
||||||
|
type: 'options',
|
||||||
|
default: 'Waiting',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Waiting',
|
||||||
|
value: 'Waiting',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'In Progress',
|
||||||
|
value: 'InProgress',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Completed',
|
||||||
|
value: 'Completed',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Cancel',
|
||||||
|
value: 'Cancel',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Status of the task. Default=Waiting',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Title',
|
||||||
|
name: 'title',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Task details',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// query options
|
||||||
|
{
|
||||||
|
displayName: 'Options',
|
||||||
|
name: 'options',
|
||||||
|
placeholder: 'Add Option',
|
||||||
|
type: 'collection',
|
||||||
|
default: {},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
'search',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'task',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Sort',
|
||||||
|
name: 'sort',
|
||||||
|
type: 'string',
|
||||||
|
placeholder: '±Attribut, exp +status',
|
||||||
|
description: 'Specify the sorting attribut, + for asc, - for desc',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// query attributes
|
||||||
|
{
|
||||||
|
displayName: 'Filters',
|
||||||
|
name: 'filters',
|
||||||
|
type: 'collection',
|
||||||
|
required: false,
|
||||||
|
default: {},
|
||||||
|
placeholder: 'Add Filter',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'task',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'search',
|
||||||
|
'count',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Description',
|
||||||
|
name: 'description',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Task details',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'End Date',
|
||||||
|
name: 'endDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
default: '',
|
||||||
|
description: 'Date of the end of the task. This is automatically set when status is set to Completed',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Flag',
|
||||||
|
name: 'flag',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Flag of the task. Default=false',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Owner',
|
||||||
|
name: 'owner',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: `User who owns the task. This is automatically set to current user when status is set to InProgress`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Start Date',
|
||||||
|
name: 'startDate',
|
||||||
|
type: 'dateTime',
|
||||||
|
default: '',
|
||||||
|
description: 'Date of the beginning of the task. This is automatically set when status is set to Open',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Status',
|
||||||
|
name: 'status',
|
||||||
|
type: 'options',
|
||||||
|
default: 'Waiting',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Waiting',
|
||||||
|
value: 'Waiting',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'In Progress',
|
||||||
|
value: 'InProgress'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Completed',
|
||||||
|
value: 'Completed'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Cancel',
|
||||||
|
value: 'Cancel'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Status of the task. Default=Waiting',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Title',
|
||||||
|
name: 'title',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Task details',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
] as INodeProperties[];
|
|
@ -0,0 +1,44 @@
|
||||||
|
import {
|
||||||
|
IDataObject
|
||||||
|
}from 'n8n-workflow'
|
||||||
|
export enum AlertStatus{
|
||||||
|
NEW="New",
|
||||||
|
UPDATED="Updated",
|
||||||
|
IGNORED="Ignored",
|
||||||
|
IMPORTED="Imported",
|
||||||
|
}
|
||||||
|
export enum TLP{
|
||||||
|
white,
|
||||||
|
green,
|
||||||
|
amber,
|
||||||
|
red
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IAlert{
|
||||||
|
// Required attributes
|
||||||
|
id?:string;
|
||||||
|
title?:string;
|
||||||
|
description?:string;
|
||||||
|
severity?:number;
|
||||||
|
date?:Date;
|
||||||
|
tags?:string[];
|
||||||
|
tlp?:TLP;
|
||||||
|
status?:AlertStatus;
|
||||||
|
type?:string;
|
||||||
|
source?:string;
|
||||||
|
sourceRef?:string;
|
||||||
|
artifacts?:IDataObject[];
|
||||||
|
follow?:boolean;
|
||||||
|
|
||||||
|
// Optional attributes
|
||||||
|
caseTemplate?:string;
|
||||||
|
|
||||||
|
// Backend generated attributes
|
||||||
|
lastSyncDate?:Date;
|
||||||
|
case?:string;
|
||||||
|
|
||||||
|
createdBy?:string;
|
||||||
|
createdAt?:Date;
|
||||||
|
updatedBy?:string;
|
||||||
|
upadtedAt?:Date;
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
import { IDataObject } from "n8n-workflow";
|
||||||
|
import { TLP } from './AlertInterface';
|
||||||
|
export interface ICase{
|
||||||
|
// Required attributes
|
||||||
|
id?:string;
|
||||||
|
title?:string;
|
||||||
|
description?:string;
|
||||||
|
severity?:number;
|
||||||
|
startDate?:Date;
|
||||||
|
owner?:string;
|
||||||
|
flag?:boolean;
|
||||||
|
tlp?:TLP;
|
||||||
|
tags?:string[];
|
||||||
|
|
||||||
|
// Optional attributes
|
||||||
|
resolutionStatus?:CaseResolutionStatus;
|
||||||
|
impactStatus?:CaseImpactStatus;
|
||||||
|
summary?:string;
|
||||||
|
endDate?:Date;
|
||||||
|
metrics?:IDataObject;
|
||||||
|
|
||||||
|
// Backend generated attributes
|
||||||
|
status?:CaseStatus;
|
||||||
|
caseId?:number; // auto-generated attribute
|
||||||
|
mergeInto?:string;
|
||||||
|
mergeFrom?:string[];
|
||||||
|
|
||||||
|
createdBy?:string;
|
||||||
|
createdAt?:Date;
|
||||||
|
updatedBy?:string;
|
||||||
|
upadtedAt?:Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export enum CaseStatus{
|
||||||
|
OPEN="Open",
|
||||||
|
RESOLVED="Resolved",
|
||||||
|
DELETED="Deleted",
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum CaseResolutionStatus{
|
||||||
|
INDETERMINATE="Indeterminate",
|
||||||
|
FALSEPOSITIVE="FalsePositive",
|
||||||
|
TRUEPOSITIVE="TruePositive",
|
||||||
|
OTHER="Other",
|
||||||
|
DUPLICATED="Duplicated",
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum CaseImpactStatus{
|
||||||
|
NOIMPACT="NoImpact",
|
||||||
|
WITHIMPACT="WithImpact",
|
||||||
|
NOTAPPLICABLE="NotApplicable",
|
||||||
|
}
|
23
packages/nodes-base/nodes/TheHive/interfaces/LogInterface.ts
Normal file
23
packages/nodes-base/nodes/TheHive/interfaces/LogInterface.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import { IDataObject } from "n8n-workflow";
|
||||||
|
import {IAttachment} from "./ObservableInterface";
|
||||||
|
export enum LogStatus{
|
||||||
|
OK="Ok",
|
||||||
|
DELETED="Deleted"
|
||||||
|
}
|
||||||
|
export interface ILog{
|
||||||
|
// Required attributes
|
||||||
|
id?:string;
|
||||||
|
message?:string;
|
||||||
|
startDate?:Date;
|
||||||
|
status?:LogStatus;
|
||||||
|
|
||||||
|
// Optional attributes
|
||||||
|
attachment?:IAttachment;
|
||||||
|
|
||||||
|
// Backend generated attributes
|
||||||
|
|
||||||
|
createdBy?:string;
|
||||||
|
createdAt?:Date;
|
||||||
|
updatedBy?:string;
|
||||||
|
upadtedAt?:Date;
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
import {
|
||||||
|
TLP
|
||||||
|
}from './AlertInterface'
|
||||||
|
import { IDataObject } from 'n8n-workflow';
|
||||||
|
|
||||||
|
export enum ObservableStatus{
|
||||||
|
OK="Ok",
|
||||||
|
DELETED="Deleted",
|
||||||
|
}
|
||||||
|
export enum ObservableDataType{
|
||||||
|
"domain"= "domain",
|
||||||
|
"file"= "file",
|
||||||
|
"filename"= "filename",
|
||||||
|
"fqdn"= "fqdn",
|
||||||
|
"hash"= "hash",
|
||||||
|
"ip"= "ip",
|
||||||
|
"mail"= "mail",
|
||||||
|
"mail_subject"= "mail_subject",
|
||||||
|
"other"= "other",
|
||||||
|
"regexp"= "regexp",
|
||||||
|
"registry"= "registry",
|
||||||
|
"uri_path"= "uri_path",
|
||||||
|
"url"= "url",
|
||||||
|
"user-agent"= "user-agent"
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IAttachment{
|
||||||
|
name?:string;
|
||||||
|
size?:number;
|
||||||
|
id?:string;
|
||||||
|
contentType?:string;
|
||||||
|
hashes:string[];
|
||||||
|
}
|
||||||
|
export interface IObservable{
|
||||||
|
// Required attributes
|
||||||
|
id?:string;
|
||||||
|
data?:string;
|
||||||
|
attachment?:IAttachment;
|
||||||
|
dataType?:ObservableDataType;
|
||||||
|
message?:string;
|
||||||
|
startDate?:Date;
|
||||||
|
tlp?:TLP;
|
||||||
|
ioc?:boolean;
|
||||||
|
status?:ObservableStatus;
|
||||||
|
// Optional attributes
|
||||||
|
tags:string[];
|
||||||
|
// Backend generated attributes
|
||||||
|
|
||||||
|
createdBy?:string;
|
||||||
|
createdAt?:Date;
|
||||||
|
updatedBy?:string;
|
||||||
|
upadtedAt?:Date;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
export interface ITask{
|
||||||
|
// Required attributes
|
||||||
|
id?:string;
|
||||||
|
title?:string;
|
||||||
|
status?:TaskStatus;
|
||||||
|
flag?:boolean;
|
||||||
|
// Optional attributes
|
||||||
|
owner?:string;
|
||||||
|
description?:string;
|
||||||
|
startDate?:Date;
|
||||||
|
endDate?:Date;
|
||||||
|
// Backend generated attributes
|
||||||
|
|
||||||
|
createdBy?:string;
|
||||||
|
createdAt?:Date;
|
||||||
|
updatedBy?:string;
|
||||||
|
upadtedAt?:Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum TaskStatus{
|
||||||
|
WAITING="Waiting",
|
||||||
|
INPROGRESS="InProgress",
|
||||||
|
COMPLETED="Completed",
|
||||||
|
CANCEL="Cancel",
|
||||||
|
}
|
BIN
packages/nodes-base/nodes/TheHive/thehive.png
Normal file
BIN
packages/nodes-base/nodes/TheHive/thehive.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.5 KiB |
|
@ -54,6 +54,7 @@
|
||||||
"dist/credentials/ContentfulApi.credentials.js",
|
"dist/credentials/ContentfulApi.credentials.js",
|
||||||
"dist/credentials/ConvertKitApi.credentials.js",
|
"dist/credentials/ConvertKitApi.credentials.js",
|
||||||
"dist/credentials/CopperApi.credentials.js",
|
"dist/credentials/CopperApi.credentials.js",
|
||||||
|
"dist/credentials/CortexApi.credentials.js",
|
||||||
"dist/credentials/CalendlyApi.credentials.js",
|
"dist/credentials/CalendlyApi.credentials.js",
|
||||||
"dist/credentials/CustomerIoApi.credentials.js",
|
"dist/credentials/CustomerIoApi.credentials.js",
|
||||||
"dist/credentials/S3.credentials.js",
|
"dist/credentials/S3.credentials.js",
|
||||||
|
@ -195,6 +196,7 @@
|
||||||
"dist/credentials/TaigaCloudApi.credentials.js",
|
"dist/credentials/TaigaCloudApi.credentials.js",
|
||||||
"dist/credentials/TaigaServerApi.credentials.js",
|
"dist/credentials/TaigaServerApi.credentials.js",
|
||||||
"dist/credentials/TelegramApi.credentials.js",
|
"dist/credentials/TelegramApi.credentials.js",
|
||||||
|
"dist/credentials/TheHiveApi.credentials.js",
|
||||||
"dist/credentials/TodoistApi.credentials.js",
|
"dist/credentials/TodoistApi.credentials.js",
|
||||||
"dist/credentials/TodoistOAuth2Api.credentials.js",
|
"dist/credentials/TodoistOAuth2Api.credentials.js",
|
||||||
"dist/credentials/TravisCiApi.credentials.js",
|
"dist/credentials/TravisCiApi.credentials.js",
|
||||||
|
@ -265,6 +267,7 @@
|
||||||
"dist/nodes/ConvertKit/ConvertKit.node.js",
|
"dist/nodes/ConvertKit/ConvertKit.node.js",
|
||||||
"dist/nodes/ConvertKit/ConvertKitTrigger.node.js",
|
"dist/nodes/ConvertKit/ConvertKitTrigger.node.js",
|
||||||
"dist/nodes/Copper/CopperTrigger.node.js",
|
"dist/nodes/Copper/CopperTrigger.node.js",
|
||||||
|
"dist/nodes/Cortex/Cortex.node.js",
|
||||||
"dist/nodes/CrateDb/CrateDb.node.js",
|
"dist/nodes/CrateDb/CrateDb.node.js",
|
||||||
"dist/nodes/Cron.node.js",
|
"dist/nodes/Cron.node.js",
|
||||||
"dist/nodes/Crypto.node.js",
|
"dist/nodes/Crypto.node.js",
|
||||||
|
@ -420,6 +423,8 @@
|
||||||
"dist/nodes/Taiga/TaigaTrigger.node.js",
|
"dist/nodes/Taiga/TaigaTrigger.node.js",
|
||||||
"dist/nodes/Telegram/Telegram.node.js",
|
"dist/nodes/Telegram/Telegram.node.js",
|
||||||
"dist/nodes/Telegram/TelegramTrigger.node.js",
|
"dist/nodes/Telegram/TelegramTrigger.node.js",
|
||||||
|
"dist/nodes/TheHive/TheHive.node.js",
|
||||||
|
"dist/nodes/TheHive/TheHiveTrigger.node.js",
|
||||||
"dist/nodes/Todoist/Todoist.node.js",
|
"dist/nodes/Todoist/Todoist.node.js",
|
||||||
"dist/nodes/Toggl/TogglTrigger.node.js",
|
"dist/nodes/Toggl/TogglTrigger.node.js",
|
||||||
"dist/nodes/TravisCi/TravisCi.node.js",
|
"dist/nodes/TravisCi/TravisCi.node.js",
|
||||||
|
|
Loading…
Reference in a new issue