diff --git a/packages/nodes-base/nodes/Wait/Wait.node.ts b/packages/nodes-base/nodes/Wait/Wait.node.ts index aa931c468c..3176747bad 100644 --- a/packages/nodes-base/nodes/Wait/Wait.node.ts +++ b/packages/nodes-base/nodes/Wait/Wait.node.ts @@ -21,6 +21,7 @@ import * as fs from 'fs'; import * as formidable from 'formidable'; +import * as isbot from 'isbot'; function authorizationError(resp: Response, realm: string, responseCode: number, message?: string) { if (message === undefined) { @@ -627,6 +628,13 @@ export class Wait implements INodeType { placeholder: 'webhook', description: 'This suffix path will be appended to the restart URL. Helpful when using multiple wait nodes. Note: Does not support expressions.', }, + { + displayName: 'Ignore Bots', + name: 'ignoreBots', + type: 'boolean', + default: false, + description: 'Set to true to ignore requests from bots like link previewers and web crawlers', + }, // { // displayName: 'Raw Body', // name: 'rawBody', @@ -656,6 +664,11 @@ export class Wait implements INodeType { const headers = this.getHeaderData(); const realm = 'Webhook'; + const ignoreBots = options.ignoreBots as boolean; + if (ignoreBots && isbot((headers as IDataObject)['user-agent'] as string)) { + return authorizationError(resp, realm, 403); + } + if (incomingAuthentication === 'basicAuth') { // Basic authorization is needed to call webhook const httpBasicAuth = await this.getCredentials('httpBasicAuth'); diff --git a/packages/nodes-base/nodes/Webhook/Webhook.node.ts b/packages/nodes-base/nodes/Webhook/Webhook.node.ts index b70394f4d8..efd6c5d493 100644 --- a/packages/nodes-base/nodes/Webhook/Webhook.node.ts +++ b/packages/nodes-base/nodes/Webhook/Webhook.node.ts @@ -20,6 +20,8 @@ import * as fs from 'fs'; import * as formidable from 'formidable'; +import * as isbot from 'isbot'; + function authorizationError(resp: Response, realm: string, responseCode: number, message?: string) { if (message === undefined) { message = 'Authorization problem!'; @@ -378,6 +380,13 @@ export class Webhook implements INodeType { default: false, description: 'Raw body (binary)', }, + { + displayName: 'Ignore Bots', + name: 'ignoreBots', + type: 'boolean', + default: false, + description: 'Set to true to ignore requests from bots like link previewers and web crawlers', + }, ], }, ], @@ -391,6 +400,11 @@ export class Webhook implements INodeType { const headers = this.getHeaderData(); const realm = 'Webhook'; + const ignoreBots = options.ignoreBots as boolean; + if (ignoreBots && isbot((headers as IDataObject)['user-agent'] as string)) { + return authorizationError(resp, realm, 403); + } + if (authentication === 'basicAuth') { // Basic authorization is needed to call webhook const httpBasicAuth = await this.getCredentials('httpBasicAuth'); diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index ac787b601a..a4bc9b7fe4 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -709,6 +709,7 @@ "iconv-lite": "^0.6.2", "ics": "^2.27.0", "imap-simple": "^4.3.0", + "isbot": "^3.3.4", "iso-639-1": "^2.1.3", "jsonwebtoken": "^8.5.1", "kafkajs": "^1.14.0",