n8n/packages/nodes-base/nodes/Webhook/Webhook.node.ts

637 lines
15 KiB
TypeScript
Raw Normal View History

2019-06-23 03:35:23 -07:00
import {
2020-03-20 14:47:47 -07:00
BINARY_ENCODING,
2019-06-23 03:35:23 -07:00
IWebhookFunctions,
} from 'n8n-core';
import {
ICredentialDataDecryptedObject,
2019-06-23 03:35:23 -07:00
IDataObject,
2019-12-21 17:03:24 -08:00
INodeExecutionData,
2019-06-23 03:35:23 -07:00
INodeType,
INodeTypeDescription,
IWebhookResponseData,
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
NodeOperationError,
2019-06-23 03:35:23 -07:00
} from 'n8n-workflow';
import basicAuth from 'basic-auth';
2019-06-23 03:35:23 -07:00
import { Response } from 'express';
import fs from 'fs';
2020-02-06 08:21:25 -08:00
import formidable from 'formidable';
2020-02-06 08:21:25 -08:00
import isbot from 'isbot';
2019-06-23 03:35:23 -07:00
function authorizationError(resp: Response, realm: string, responseCode: number, message?: string) {
if (message === undefined) {
message = 'Authorization problem!';
if (responseCode === 401) {
message = 'Authorization is required!';
} else if (responseCode === 403) {
message = 'Authorization data is wrong!';
}
}
resp.writeHead(responseCode, { 'WWW-Authenticate': `Basic realm="${realm}"` });
resp.end(message);
return {
noWebhookResponse: true,
};
}
export class Webhook implements INodeType {
description: INodeTypeDescription = {
displayName: 'Webhook',
2021-06-18 14:48:38 -07:00
icon: 'file:webhook.svg',
2019-06-23 03:35:23 -07:00
name: 'webhook',
group: ['trigger'],
version: 1,
description: 'Starts the workflow when a webhook is called',
eventTriggerDescription: 'Waiting for you to call the Test URL',
:sparkles: Improve workflow activation (#2692) * feat: activator disabled based on thiggers * feat: tooltip over inactive switch * feat: message for trigger types * feat: deactivate on save if trigger is removed * chore: refactor executions modal * feat: calculate service name if possible * feat: alert on activation * chore: fix linting * feat: always enable activator when active * fix: adjust the alert * feat: take disabled state into account * feat: automatically save on activation * feat: rely on nodes name and edit messages * feat: isolate state for each activator instance * feat: create activation modal component * feat: activationModal checkbox and trigger message * feat: add activation messages to node config * chore: style activation modal * chore: style fixes * feat: refactor disabled state * chore: refactor modal * chore: refactor modal * chore: tidy the node config * chore: refactor and styling tweaks * chore: minor fixes * fix: check webhooks from ui nodes * chore: remove saving prompt * chore: explicit current workflow evaluation * feat: add settings link to activation modal * fix: immediately load executions on render * feat: exclude error trigger from trigger nodes * chore: add i18n keys * fix: check localstorage more strictly * fix: handle refresh in execution list * remove unnessary event * remove comment * fix closing executions modal bugs * update closing * update translation key * fix translation keys * fix modal closing * fix closing * fix drawer closing * close all modals when opening executions * update key * close all modals when opening workflow or new page * delete unnessary comment * clean up import * clean up unnessary initial data * clean up activator impl * rewrite * fix open modal bug * simply remove error * refactor activation logic * fix i18n and such * remove changes * revert saving changes * Revert "revert saving changes" 25c29d10553ebcc11939ff29938e8a5ac6b3ffae * add translation * fix new workflows saving * clean up modal impl * clean up impl * refactor common code out * remove active changes from saving * refactor differently * revert unnessary change * set dirty false * fix i18n bug * avoid opening two modals * fix tooltips * add comment * address other comments * address comments Co-authored-by: saintsebastian <tilitidam@gmail.com>
2022-01-21 09:00:00 -08:00
activationMessage: 'You can now make calls to your production webhook URL.',
2019-06-23 03:35:23 -07:00
defaults: {
name: 'Webhook',
},
refactor: Apply `eslint-plugin-n8n-nodes-base` autofixable rules (#3174) * :zap: Initial setup * :shirt: Update `.eslintignore` * :shirt: Autofix node-param-default-missing (#3173) * :fire: Remove duplicate key * :shirt: Add exceptions * :package: Update package-lock.json * :shirt: Apply `node-class-description-inputs-wrong-trigger-node` (#3176) * :shirt: Apply `node-class-description-inputs-wrong-regular-node` (#3177) * :shirt: Apply `node-class-description-outputs-wrong` (#3178) * :shirt: Apply `node-execute-block-double-assertion-for-items` (#3179) * :shirt: Apply `node-param-default-wrong-for-collection` (#3180) * :shirt: Apply node-param-default-wrong-for-boolean (#3181) * Autofixed default missing * Autofixed booleans, worked well * :zap: Fix params * :rewind: Undo exempted autofixes * :package: Update package-lock.json * :shirt: Apply node-class-description-missing-subtitle (#3182) * :zap: Fix missing comma * :shirt: Apply `node-param-default-wrong-for-fixed-collection` (#3184) * :shirt: Add exception for `node-class-description-missing-subtitle` * :shirt: Apply `node-param-default-wrong-for-multi-options` (#3185) * :shirt: Apply `node-param-collection-type-unsorted-items` (#3186) * Missing coma * :shirt: Apply `node-param-default-wrong-for-simplify` (#3187) * :shirt: Apply `node-param-description-comma-separated-hyphen` (#3190) * :shirt: Apply `node-param-description-empty-string` (#3189) * :shirt: Apply `node-param-description-excess-inner-whitespace` (#3191) * Rule looks good * Add whitespace rule in eslint config * :zao: fix * :shirt: Apply `node-param-description-identical-to-display-name` (#3193) * :shirt: Apply `node-param-description-missing-for-ignore-ssl-issues` (#3195) * :rewind: Revert ":zao: fix" This reverts commit ef8a76f3dfedffd1bdccf3178af8a8d90cf5a55c. * :shirt: Apply `node-param-description-missing-for-simplify` (#3196) * :shirt: Apply `node-param-description-missing-final-period` (#3194) * Rule working as intended * Add rule to eslint * :shirt: Apply node-param-description-missing-for-return-all (#3197) * :zap: Restore `lintfix` command Co-authored-by: agobrech <45268029+agobrech@users.noreply.github.com> Co-authored-by: Omar Ajoue <krynble@gmail.com> Co-authored-by: agobrech <ael.gobrecht@gmail.com> Co-authored-by: Michael Kret <michael.k@radency.com>
2022-04-22 09:29:51 -07:00
// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node
2019-06-23 03:35:23 -07:00
inputs: [],
outputs: ['main'],
credentials: [
{
name: 'httpBasicAuth',
required: true,
displayOptions: {
show: {
authentication: [
'basicAuth',
],
},
},
},
{
name: 'httpHeaderAuth',
required: true,
displayOptions: {
show: {
authentication: [
'headerAuth',
],
},
},
},
],
webhooks: [
{
name: 'default',
httpMethod: '={{$parameter["httpMethod"]}}',
isFullPath: true,
responseCode: '={{$parameter["responseCode"]}}',
2019-08-28 08:16:09 -07:00
responseMode: '={{$parameter["responseMode"]}}',
responseData: '={{$parameter["responseData"] || ($parameter.options.noResponseBody ? "noData" : undefined) }}',
2019-06-23 03:35:23 -07:00
responseBinaryPropertyName: '={{$parameter["responseBinaryPropertyName"]}}',
responseContentType: '={{$parameter["options"]["responseContentType"]}}',
responsePropertyName: '={{$parameter["options"]["responsePropertyName"]}}',
responseHeaders: '={{$parameter["options"]["responseHeaders"]}}',
2019-06-23 03:35:23 -07:00
path: '={{$parameter["path"]}}',
},
],
properties: [
{
displayName: 'Authentication',
name: 'authentication',
type: 'options',
options: [
{
name: 'Basic Auth',
2020-10-22 06:46:03 -07:00
value: 'basicAuth',
2019-06-23 03:35:23 -07:00
},
{
name: 'Header Auth',
2020-10-22 06:46:03 -07:00
value: 'headerAuth',
2019-06-23 03:35:23 -07:00
},
{
name: 'None',
2020-10-22 06:46:03 -07:00
value: 'none',
2019-06-23 03:35:23 -07:00
},
],
default: 'none',
description: 'The way to authenticate',
2019-06-23 03:35:23 -07:00
},
{
displayName: 'HTTP Method',
name: 'httpMethod',
type: 'options',
options: [
{
name: 'DELETE',
value: 'DELETE',
},
2019-06-23 03:35:23 -07:00
{
name: 'GET',
value: 'GET',
},
{
name: 'HEAD',
value: 'HEAD',
},
{
name: 'PATCH',
value: 'PATCH',
},
2019-06-23 03:35:23 -07:00
{
name: 'POST',
value: 'POST',
},
{
name: 'PUT',
value: 'PUT',
},
2019-06-23 03:35:23 -07:00
],
default: 'GET',
description: 'The HTTP method to listen to',
2019-06-23 03:35:23 -07:00
},
{
displayName: 'Path',
name: 'path',
type: 'string',
default: '',
placeholder: 'webhook',
2019-06-23 03:35:23 -07:00
required: true,
description: 'The path to listen to',
2019-06-23 03:35:23 -07:00
},
{
displayName: 'Respond',
2019-08-28 08:16:09 -07:00
name: 'responseMode',
2019-06-23 03:35:23 -07:00
type: 'options',
options: [
{
name: 'Immediately',
2019-06-23 03:35:23 -07:00
value: 'onReceived',
description: 'As soon as this node executes',
2019-06-23 03:35:23 -07:00
},
{
name: 'When last node finishes',
2019-06-23 03:35:23 -07:00
value: 'lastNode',
description: 'Returns data of the last-executed node',
},
{
name: 'Using \'Respond to Webhook\' node',
value: 'responseNode',
description: 'Response defined in that node',
2019-06-23 03:35:23 -07:00
},
],
default: 'onReceived',
description: 'When and how to respond to the webhook',
2019-06-23 03:35:23 -07:00
},
{
displayName: 'Insert a \'Respond to Webhook\' node to control when and how you respond. <a href="https://docs.n8n.io/nodes/n8n-nodes-base.respondToWebhook" target="_blank">More details</a>',
name: 'webhookNotice',
type: 'notice',
displayOptions: {
show: {
responseMode: [
'responseNode',
],
},
},
default: '',
},
{
displayName: 'Response Code',
name: 'responseCode',
type: 'number',
displayOptions: {
hide: {
responseMode: [
'responseNode',
],
},
},
typeOptions: {
minValue: 100,
maxValue: 599,
},
default: 200,
description: 'The HTTP Response code to return',
},
2019-06-23 03:35:23 -07:00
{
2019-08-28 08:16:09 -07:00
displayName: 'Response Data',
name: 'responseData',
2019-06-23 03:35:23 -07:00
type: 'options',
displayOptions: {
show: {
2019-08-28 08:16:09 -07:00
responseMode: [
2019-06-23 03:35:23 -07:00
'lastNode',
],
},
},
options: [
{
name: 'All Entries',
value: 'allEntries',
description: 'Returns all the entries of the last node. Always returns an array.',
},
{
name: 'First Entry JSON',
value: 'firstEntryJson',
description: 'Returns the JSON data of the first entry of the last node. Always returns a JSON object.',
},
{
name: 'First Entry Binary',
value: 'firstEntryBinary',
description: 'Returns the binary data of the first entry of the last node. Always returns a binary file.',
},
{
name: 'No Response Body',
value: 'noData',
description: 'Returns without a body',
},
2019-06-23 03:35:23 -07:00
],
default: 'firstEntryJson',
:zap: Remove unnessasry <br/> (#2340) * introduce analytics * add user survey backend * add user survey backend * set answers on survey submit Co-authored-by: Mutasem Aldmour <4711238+mutdmour@users.noreply.github.com> * change name to personalization * lint Co-authored-by: Mutasem Aldmour <4711238+mutdmour@users.noreply.github.com> * N8n 2495 add personalization modal (#2280) * update modals * add onboarding modal * implement questions * introduce analytics * simplify impl * implement survey handling * add personalized cateogry * update modal behavior * add thank you view * handle empty cases * rename modal * standarize modal names * update image, add tags to headings * remove unused file * remove unused interfaces * clean up footer spacing * introduce analytics * refactor to fix bug * update endpoint * set min height * update stories * update naming from questions to survey * remove spacing after core categories * fix bug in logic * sort nodes * rename types * merge with be * rename userSurvey * clean up rest api * use constants for keys * use survey keys * clean up types * move personalization to its own file Co-authored-by: ahsan-virani <ahsan.virani@gmail.com> * update parameter inputs to be multiline * update spacing * Survey new options (#2300) * split up options * fix quotes * remove unused import * refactor node credentials * add user created workflow event (#2301) * update multi params * simplify env vars * fix versionCli on FE * update personalization env * clean up node detail settings * fix event User opened Credentials panel * fix font sizes across modals * clean up input spacing * fix select modal spacing * increase spacing * fix input copy * fix webhook, tab spacing, retry button * fix button sizes * fix button size * add mini xlarge sizes * fix webhook spacing * fix nodes panel event * fix workflow id in workflow execute event * improve telemetry error logging * fix config and stop process events * add flush call on n8n stop * ready for release * fix input error highlighting * revert change * update toggle spacing * fix delete positioning * keep tooltip while focused * set strict size * increase left spacing * fix sort icons * remove unnessasry <br/> * remove unnessary break * remove unnessary margin * clean unused functionality * remove unnessary css * remove duplicate tracking * only show tooltip when hovering over label * remove extra space * add br * remove extra space * clean up commas * clean up commas * remove extra space * remove extra space * rewrite desc * add commas * add space * remove extra space * add space * add dot * update credentials section * use includes Co-authored-by: ahsan-virani <ahsan.virani@gmail.com> Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2021-10-27 13:00:13 -07:00
description: 'What data should be returned. If it should return all items as an array or only the first item as object.',
2019-06-23 03:35:23 -07:00
},
{
displayName: 'Property Name',
name: 'responseBinaryPropertyName',
type: 'string',
required: true,
default: 'data',
displayOptions: {
show: {
2019-08-28 08:16:09 -07:00
responseData: [
2020-10-22 06:46:03 -07:00
'firstEntryBinary',
2019-06-23 03:35:23 -07:00
],
},
},
description: 'Name of the binary property to return',
},
{
displayName: 'Options',
name: 'options',
type: 'collection',
placeholder: 'Add Option',
default: {},
options: [
{
displayName: 'Binary Data',
name: 'binaryData',
type: 'boolean',
displayOptions: {
show: {
'/httpMethod': [
'PATCH',
'PUT',
'POST',
],
},
},
default: false,
description: 'Set to true if webhook will receive binary data',
},
{
displayName: 'Binary Property',
name: 'binaryPropertyName',
type: 'string',
default: 'data',
required: true,
displayOptions: {
show: {
binaryData: [
true,
],
},
},
refactor: Apply `eslint-plugin-n8n-nodes-base` autofixable rules (#3174) * :zap: Initial setup * :shirt: Update `.eslintignore` * :shirt: Autofix node-param-default-missing (#3173) * :fire: Remove duplicate key * :shirt: Add exceptions * :package: Update package-lock.json * :shirt: Apply `node-class-description-inputs-wrong-trigger-node` (#3176) * :shirt: Apply `node-class-description-inputs-wrong-regular-node` (#3177) * :shirt: Apply `node-class-description-outputs-wrong` (#3178) * :shirt: Apply `node-execute-block-double-assertion-for-items` (#3179) * :shirt: Apply `node-param-default-wrong-for-collection` (#3180) * :shirt: Apply node-param-default-wrong-for-boolean (#3181) * Autofixed default missing * Autofixed booleans, worked well * :zap: Fix params * :rewind: Undo exempted autofixes * :package: Update package-lock.json * :shirt: Apply node-class-description-missing-subtitle (#3182) * :zap: Fix missing comma * :shirt: Apply `node-param-default-wrong-for-fixed-collection` (#3184) * :shirt: Add exception for `node-class-description-missing-subtitle` * :shirt: Apply `node-param-default-wrong-for-multi-options` (#3185) * :shirt: Apply `node-param-collection-type-unsorted-items` (#3186) * Missing coma * :shirt: Apply `node-param-default-wrong-for-simplify` (#3187) * :shirt: Apply `node-param-description-comma-separated-hyphen` (#3190) * :shirt: Apply `node-param-description-empty-string` (#3189) * :shirt: Apply `node-param-description-excess-inner-whitespace` (#3191) * Rule looks good * Add whitespace rule in eslint config * :zao: fix * :shirt: Apply `node-param-description-identical-to-display-name` (#3193) * :shirt: Apply `node-param-description-missing-for-ignore-ssl-issues` (#3195) * :rewind: Revert ":zao: fix" This reverts commit ef8a76f3dfedffd1bdccf3178af8a8d90cf5a55c. * :shirt: Apply `node-param-description-missing-for-simplify` (#3196) * :shirt: Apply `node-param-description-missing-final-period` (#3194) * Rule working as intended * Add rule to eslint * :shirt: Apply node-param-description-missing-for-return-all (#3197) * :zap: Restore `lintfix` command Co-authored-by: agobrech <45268029+agobrech@users.noreply.github.com> Co-authored-by: Omar Ajoue <krynble@gmail.com> Co-authored-by: agobrech <ael.gobrecht@gmail.com> Co-authored-by: Michael Kret <michael.k@radency.com>
2022-04-22 09:29:51 -07:00
description: 'Name of the binary property to write the data of the received file to. If the data gets received via "Form-Data Multipart" it will be the prefix and a number starting with 0 will be attached to it.',
},
{
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: 'No Response Body',
name: 'noResponseBody',
type: 'boolean',
default: false,
description: 'Do not send any body in the response',
displayOptions: {
hide: {
'rawBody': [
true,
],
},
show: {
'/responseMode': [
'onReceived',
],
},
},
},
{
displayName: 'Raw Body',
name: 'rawBody',
type: 'boolean',
displayOptions: {
hide: {
binaryData: [
true,
],
'noResponseBody': [
true,
],
},
},
default: false,
description: 'Raw body (binary)',
},
{
displayName: 'Response Data',
name: 'responseData',
type: 'string',
displayOptions: {
show: {
'/responseMode': [
'onReceived',
],
},
hide: {
'noResponseBody': [
true,
],
},
},
default: '',
placeholder: 'success',
description: 'Custom response data to send',
},
{
displayName: 'Response Content-Type',
name: 'responseContentType',
type: 'string',
2019-12-21 17:03:24 -08:00
displayOptions: {
show: {
'/responseData': [
'firstEntryJson',
],
'/responseMode': [
'lastNode',
],
},
},
default: '',
placeholder: 'application/xml',
description: 'Set a custom content-type to return if another one as the "application/json" should be returned',
},
{
displayName: 'Response Headers',
name: 'responseHeaders',
placeholder: 'Add Response Header',
description: 'Add headers to the webhook response',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
default: {},
options: [
{
name: 'entries',
displayName: 'Entries',
values: [
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
description: 'Name of the header',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'Value of the header',
},
2020-10-22 06:46:03 -07:00
],
},
],
},
{
displayName: 'Property Name',
name: 'responsePropertyName',
type: 'string',
2019-12-21 17:03:24 -08:00
displayOptions: {
show: {
'/responseData': [
'firstEntryJson',
],
'/responseMode': [
'lastNode',
],
},
},
default: 'data',
description: 'Name of the property to return the data of instead of the whole JSON',
},
2019-12-21 12:36:08 -08:00
],
},
2019-06-23 03:35:23 -07:00
],
};
async webhook(this: IWebhookFunctions): Promise<IWebhookResponseData> {
const authentication = this.getNodeParameter('authentication') as string;
const options = this.getNodeParameter('options', {}) as IDataObject;
2019-06-23 03:35:23 -07:00
const req = this.getRequestObject();
const resp = this.getResponseObject();
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);
}
2019-06-23 03:35:23 -07:00
if (authentication === 'basicAuth') {
// Basic authorization is needed to call webhook
let httpBasicAuth: ICredentialDataDecryptedObject | undefined;
try {
httpBasicAuth = await this.getCredentials('httpBasicAuth');
} catch (error) {
// Do nothing
}
2019-06-23 03:35:23 -07:00
if (httpBasicAuth === undefined || !httpBasicAuth.user || !httpBasicAuth.password) {
// Data is not defined on node so can not authenticate
return authorizationError(resp, realm, 500, 'No authentication data defined on node!');
}
const basicAuthData = basicAuth(req);
if (basicAuthData === undefined) {
// Authorization data is missing
return authorizationError(resp, realm, 401);
}
if (basicAuthData.name !== httpBasicAuth!.user || basicAuthData.pass !== httpBasicAuth!.password) {
// Provided authentication data is wrong
return authorizationError(resp, realm, 403);
}
} else if (authentication === 'headerAuth') {
// Special header with value is needed to call webhook
let httpHeaderAuth: ICredentialDataDecryptedObject | undefined;
try {
httpHeaderAuth = await this.getCredentials('httpHeaderAuth');
} catch (error) {
// Do nothing
}
2019-06-23 03:35:23 -07:00
if (httpHeaderAuth === undefined || !httpHeaderAuth.name || !httpHeaderAuth.value) {
// Data is not defined on node so can not authenticate
return authorizationError(resp, realm, 500, 'No authentication data defined on node!');
}
const headerName = (httpHeaderAuth.name as string).toLowerCase();
const headerValue = (httpHeaderAuth.value as string);
if (!headers.hasOwnProperty(headerName) || (headers as IDataObject)[headerName] !== headerValue) {
// Provided authentication data is wrong
return authorizationError(resp, realm, 403);
}
}
2019-12-21 17:03:24 -08:00
// @ts-ignore
const mimeType = headers['content-type'] || 'application/json';
2020-02-06 08:21:25 -08:00
if (mimeType.includes('multipart/form-data')) {
// @ts-ignore
const form = new formidable.IncomingForm({ multiples: true });
2020-02-06 08:21:25 -08:00
return new Promise((resolve, reject) => {
form.parse(req, async (err, data, files) => {
const returnItem: INodeExecutionData = {
binary: {},
json: {
headers,
:sparkles: Add support for webhook route parameters (#1343) * :construction: add webhookId to URL * :construction: add webhookId to webhook entity, :wrench: refactor migrations * :construction: :elephant: postgres migration * :construction: add mySQL migration * :construction: refactor mongoDB * :construction: add webhookId to IWebhookDb * :construction: starting workflow with dynamic route works * :zap: production dynamic webhooks complete * :art: fix lint issues * :wrench: dynamic path for webhook-test complete * :art: fix lint issues * :art: fix typescript issue * :zap: add error message for dynamic webhook-test * :hammer: improve handling of leading `/` * :construction: add webhookId to URL * :construction: add webhookId to webhook entity, :wrench: refactor migrations * :construction: :elephant: postgres migration * :construction: add mySQL migration * :construction: refactor mongoDB * :construction: add webhookId to IWebhookDb * :construction: starting workflow with dynamic route works * :zap: production dynamic webhooks complete * :art: fix lint issues * :wrench: dynamic path for webhook-test complete * :art: fix lint issues * :art: fix typescript issue * :zap: add error message for dynamic webhook-test * :hammer: improve handling of leading `/` * :zap: Fix issue that tab-title did not get reset on new workflow * Revert ":zap: Fix issue that tab-title did not get reset on new workflow" This reverts commit 699d0a8946e08339558c72b2714601329fbf5f2c. * :wrench: reset params before extraction * :elephant: removing unique constraint for webhookId * :construction: handle multiple webhooks per id * :wrench: enable webhook-test for multiple WH with same id * :elephant: add migration for postgres * :zap: add mysql migration * :art: fix lint issue Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2021-01-23 11:00:32 -08:00
params: this.getParamsData(),
query: this.getQueryData(),
:sparkles: Add support for webhook route parameters (#1343) * :construction: add webhookId to URL * :construction: add webhookId to webhook entity, :wrench: refactor migrations * :construction: :elephant: postgres migration * :construction: add mySQL migration * :construction: refactor mongoDB * :construction: add webhookId to IWebhookDb * :construction: starting workflow with dynamic route works * :zap: production dynamic webhooks complete * :art: fix lint issues * :wrench: dynamic path for webhook-test complete * :art: fix lint issues * :art: fix typescript issue * :zap: add error message for dynamic webhook-test * :hammer: improve handling of leading `/` * :construction: add webhookId to URL * :construction: add webhookId to webhook entity, :wrench: refactor migrations * :construction: :elephant: postgres migration * :construction: add mySQL migration * :construction: refactor mongoDB * :construction: add webhookId to IWebhookDb * :construction: starting workflow with dynamic route works * :zap: production dynamic webhooks complete * :art: fix lint issues * :wrench: dynamic path for webhook-test complete * :art: fix lint issues * :art: fix typescript issue * :zap: add error message for dynamic webhook-test * :hammer: improve handling of leading `/` * :zap: Fix issue that tab-title did not get reset on new workflow * Revert ":zap: Fix issue that tab-title did not get reset on new workflow" This reverts commit 699d0a8946e08339558c72b2714601329fbf5f2c. * :wrench: reset params before extraction * :elephant: removing unique constraint for webhookId * :construction: handle multiple webhooks per id * :wrench: enable webhook-test for multiple WH with same id * :elephant: add migration for postgres * :zap: add mysql migration * :art: fix lint issue Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2021-01-23 11:00:32 -08:00
body: data,
},
};
let count = 0;
for (const xfile of Object.keys(files)) {
2021-08-29 14:08:56 -07:00
const processFiles: formidable.File[] = [];
let multiFile = false;
if (Array.isArray(files[xfile])) {
processFiles.push(...files[xfile] as formidable.File[]);
multiFile = true;
} else {
2021-08-29 14:08:56 -07:00
processFiles.push(files[xfile] as formidable.File);
}
let fileCount = 0;
2021-08-29 14:08:56 -07:00
for (const file of processFiles) {
let binaryPropertyName = xfile;
if (binaryPropertyName.endsWith('[]')) {
binaryPropertyName = binaryPropertyName.slice(0, -2);
}
if (multiFile === true) {
binaryPropertyName += fileCount++;
}
if (options.binaryPropertyName) {
binaryPropertyName = `${options.binaryPropertyName}${count}`;
}
2021-08-29 14:08:56 -07:00
const fileJson = file.toJSON() as unknown as IDataObject;
const fileContent = await fs.promises.readFile(file.path);
returnItem.binary![binaryPropertyName] = await this.helpers.prepareBinaryData(Buffer.from(fileContent), fileJson.name as string, fileJson.type as string);
count += 1;
}
2020-02-06 08:21:25 -08:00
}
resolve({
workflowData: [
[
returnItem,
2020-10-22 06:46:03 -07:00
],
2020-02-06 08:21:25 -08:00
],
});
});
});
}
2019-12-21 17:03:24 -08:00
if (options.binaryData === true) {
2020-03-20 11:53:51 -07:00
return new Promise((resolve, reject) => {
const binaryPropertyName = options.binaryPropertyName || 'data';
2020-03-20 11:53:51 -07:00
const data: Buffer[] = [];
req.on('data', (chunk) => {
data.push(chunk);
});
req.on('end', async () => {
const returnItem: INodeExecutionData = {
binary: {},
json: {
headers,
:sparkles: Add support for webhook route parameters (#1343) * :construction: add webhookId to URL * :construction: add webhookId to webhook entity, :wrench: refactor migrations * :construction: :elephant: postgres migration * :construction: add mySQL migration * :construction: refactor mongoDB * :construction: add webhookId to IWebhookDb * :construction: starting workflow with dynamic route works * :zap: production dynamic webhooks complete * :art: fix lint issues * :wrench: dynamic path for webhook-test complete * :art: fix lint issues * :art: fix typescript issue * :zap: add error message for dynamic webhook-test * :hammer: improve handling of leading `/` * :construction: add webhookId to URL * :construction: add webhookId to webhook entity, :wrench: refactor migrations * :construction: :elephant: postgres migration * :construction: add mySQL migration * :construction: refactor mongoDB * :construction: add webhookId to IWebhookDb * :construction: starting workflow with dynamic route works * :zap: production dynamic webhooks complete * :art: fix lint issues * :wrench: dynamic path for webhook-test complete * :art: fix lint issues * :art: fix typescript issue * :zap: add error message for dynamic webhook-test * :hammer: improve handling of leading `/` * :zap: Fix issue that tab-title did not get reset on new workflow * Revert ":zap: Fix issue that tab-title did not get reset on new workflow" This reverts commit 699d0a8946e08339558c72b2714601329fbf5f2c. * :wrench: reset params before extraction * :elephant: removing unique constraint for webhookId * :construction: handle multiple webhooks per id * :wrench: enable webhook-test for multiple WH with same id * :elephant: add migration for postgres * :zap: add mysql migration * :art: fix lint issue Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2021-01-23 11:00:32 -08:00
params: this.getParamsData(),
query: this.getQueryData(),
:sparkles: Add support for webhook route parameters (#1343) * :construction: add webhookId to URL * :construction: add webhookId to webhook entity, :wrench: refactor migrations * :construction: :elephant: postgres migration * :construction: add mySQL migration * :construction: refactor mongoDB * :construction: add webhookId to IWebhookDb * :construction: starting workflow with dynamic route works * :zap: production dynamic webhooks complete * :art: fix lint issues * :wrench: dynamic path for webhook-test complete * :art: fix lint issues * :art: fix typescript issue * :zap: add error message for dynamic webhook-test * :hammer: improve handling of leading `/` * :construction: add webhookId to URL * :construction: add webhookId to webhook entity, :wrench: refactor migrations * :construction: :elephant: postgres migration * :construction: add mySQL migration * :construction: refactor mongoDB * :construction: add webhookId to IWebhookDb * :construction: starting workflow with dynamic route works * :zap: production dynamic webhooks complete * :art: fix lint issues * :wrench: dynamic path for webhook-test complete * :art: fix lint issues * :art: fix typescript issue * :zap: add error message for dynamic webhook-test * :hammer: improve handling of leading `/` * :zap: Fix issue that tab-title did not get reset on new workflow * Revert ":zap: Fix issue that tab-title did not get reset on new workflow" This reverts commit 699d0a8946e08339558c72b2714601329fbf5f2c. * :wrench: reset params before extraction * :elephant: removing unique constraint for webhookId * :construction: handle multiple webhooks per id * :wrench: enable webhook-test for multiple WH with same id * :elephant: add migration for postgres * :zap: add mysql migration * :art: fix lint issue Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2021-01-23 11:00:32 -08:00
body: this.getBodyData(),
},
};
returnItem.binary![binaryPropertyName as string] = await this.helpers.prepareBinaryData(Buffer.concat(data));
2020-03-20 11:53:51 -07:00
return resolve({
workflowData: [
[
2020-10-22 06:46:03 -07:00
returnItem,
],
2020-03-20 11:53:51 -07:00
],
});
});
:sparkles: Improve node error handling (#1309) * Add path mapping and response error interfaces * Add error handling and throwing functionality * Refactor error handling into a single function * Re-implement error handling in Hacker News node * Fix linting details * Re-implement error handling in Spotify node * Re-implement error handling in G Suite Admin node * :construction: create basic setup NodeError * :construction: add httpCodes * :construction: add path priolist * :construction: handle statusCode in error, adjust interfaces * :construction: fixing type issues w/Ivan * :construction: add error exploration * 👔 fix linter issues * :wrench: improve object check * :construction: remove path passing from NodeApiError * :construction: add multi error + refactor findProperty method * 👔 allow any * :wrench: handle multi error message callback * :zap: change return type of callback * :zap: add customCallback to MultiError * :construction: refactor to use INode * :hammer: handle arrays, continue search after first null property found * 🚫 refactor method access * :construction: setup NodeErrorView * :zap: change timestamp to Date.now * :books: Add documentation for methods and constants * :construction: change message setting * 🚚 move NodeErrors to workflow * :sparkles: add new ErrorView for Nodes * :art: improve error notification * :art: refactor interfaces * :zap: add WorkflowOperationError, refactor error throwing * 👕 fix linter issues * :art: rename param * :bug: fix handling normal errors * :zap: add usage of NodeApiError * :art: fix throw new error instead of constructor * :art: remove unnecessary code/comments * :art: adjusted spacing + updated status messages * :art: fix tab indentation * ✨ Replace current errors with custom errors (#1576) * :zap: Introduce NodeApiError in catch blocks * :zap: Introduce NodeOperationError in nodes * :zap: Add missing errors and remove incompatible * :zap: Fix NodeOperationError in incompatible nodes * :wrench: Adjust error handling in missed nodes PayPal, FileMaker, Reddit, Taiga and Facebook Graph API nodes * :hammer: Adjust Strava Trigger node error handling * :hammer: Adjust AWS nodes error handling * :hammer: Remove duplicate instantiation of NodeApiError * :bug: fix strava trigger node error handling * Add XML parsing to NodeApiError constructor (#1633) * :bug: Remove type annotation from catch variable * :sparkles: Add XML parsing to NodeApiError * :zap: Simplify error handling in Rekognition node * :zap: Pass in XML flag in generic functions * :fire: Remove try/catch wrappers at call sites * :hammer: Refactor setting description from XML * :hammer: Refactor let to const in resource loaders * :zap: Find property in parsed XML * :zap: Change let to const * :fire: Remove unneeded try/catch block * :shirt: Fix linting issues * :bug: Fix errors from merge conflict resolution * :zap: Add custom errors to latest contributions * :shirt: Fix linting issues * :zap: Refactor MongoDB helpers for custom errors * :bug: Correct custom error type * :zap: Apply feedback to A nodes * :zap: Apply feedback to missed A node * :zap: Apply feedback to B-D nodes * :zap: Apply feedback to E-F nodes * :zap: Apply feedback to G nodes * :zap: Apply feedback to H-L nodes * :zap: Apply feedback to M nodes * :zap: Apply feedback to P nodes * :zap: Apply feedback to R nodes * :zap: Apply feedback to S nodes * :zap: Apply feedback to T nodes * :zap: Apply feedback to V-Z nodes * :zap: Add HTTP code to iterable node error * :hammer: Standardize e as error * :hammer: Standardize err as error * :zap: Fix error handling for non-standard nodes Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com>
2021-04-16 09:33:36 -07:00
req.on('error', (error) => {
throw new NodeOperationError(this.getNode(), error);
2020-03-20 11:53:51 -07:00
});
});
}
2019-12-21 17:03:24 -08:00
const response: INodeExecutionData = {
2019-12-21 12:36:08 -08:00
json: {
2019-06-23 03:35:23 -07:00
headers,
:sparkles: Add support for webhook route parameters (#1343) * :construction: add webhookId to URL * :construction: add webhookId to webhook entity, :wrench: refactor migrations * :construction: :elephant: postgres migration * :construction: add mySQL migration * :construction: refactor mongoDB * :construction: add webhookId to IWebhookDb * :construction: starting workflow with dynamic route works * :zap: production dynamic webhooks complete * :art: fix lint issues * :wrench: dynamic path for webhook-test complete * :art: fix lint issues * :art: fix typescript issue * :zap: add error message for dynamic webhook-test * :hammer: improve handling of leading `/` * :construction: add webhookId to URL * :construction: add webhookId to webhook entity, :wrench: refactor migrations * :construction: :elephant: postgres migration * :construction: add mySQL migration * :construction: refactor mongoDB * :construction: add webhookId to IWebhookDb * :construction: starting workflow with dynamic route works * :zap: production dynamic webhooks complete * :art: fix lint issues * :wrench: dynamic path for webhook-test complete * :art: fix lint issues * :art: fix typescript issue * :zap: add error message for dynamic webhook-test * :hammer: improve handling of leading `/` * :zap: Fix issue that tab-title did not get reset on new workflow * Revert ":zap: Fix issue that tab-title did not get reset on new workflow" This reverts commit 699d0a8946e08339558c72b2714601329fbf5f2c. * :wrench: reset params before extraction * :elephant: removing unique constraint for webhookId * :construction: handle multiple webhooks per id * :wrench: enable webhook-test for multiple WH with same id * :elephant: add migration for postgres * :zap: add mysql migration * :art: fix lint issue Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2021-01-23 11:00:32 -08:00
params: this.getParamsData(),
2019-06-23 03:35:23 -07:00
query: this.getQueryData(),
:sparkles: Add support for webhook route parameters (#1343) * :construction: add webhookId to URL * :construction: add webhookId to webhook entity, :wrench: refactor migrations * :construction: :elephant: postgres migration * :construction: add mySQL migration * :construction: refactor mongoDB * :construction: add webhookId to IWebhookDb * :construction: starting workflow with dynamic route works * :zap: production dynamic webhooks complete * :art: fix lint issues * :wrench: dynamic path for webhook-test complete * :art: fix lint issues * :art: fix typescript issue * :zap: add error message for dynamic webhook-test * :hammer: improve handling of leading `/` * :construction: add webhookId to URL * :construction: add webhookId to webhook entity, :wrench: refactor migrations * :construction: :elephant: postgres migration * :construction: add mySQL migration * :construction: refactor mongoDB * :construction: add webhookId to IWebhookDb * :construction: starting workflow with dynamic route works * :zap: production dynamic webhooks complete * :art: fix lint issues * :wrench: dynamic path for webhook-test complete * :art: fix lint issues * :art: fix typescript issue * :zap: add error message for dynamic webhook-test * :hammer: improve handling of leading `/` * :zap: Fix issue that tab-title did not get reset on new workflow * Revert ":zap: Fix issue that tab-title did not get reset on new workflow" This reverts commit 699d0a8946e08339558c72b2714601329fbf5f2c. * :wrench: reset params before extraction * :elephant: removing unique constraint for webhookId * :construction: handle multiple webhooks per id * :wrench: enable webhook-test for multiple WH with same id * :elephant: add migration for postgres * :zap: add mysql migration * :art: fix lint issue Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2021-01-23 11:00:32 -08:00
body: this.getBodyData(),
2019-12-21 12:36:08 -08:00
},
};
if (options.rawBody) {
response.binary = {
2019-12-21 17:03:24 -08:00
data: {
// @ts-ignore
2020-03-20 14:47:47 -07:00
data: req.rawBody.toString(BINARY_ENCODING),
2019-12-21 17:03:24 -08:00
mimeType,
2020-10-22 06:46:03 -07:00
},
2019-12-21 12:36:08 -08:00
};
}
let webhookResponse: string | undefined;
if (options.responseData) {
webhookResponse = options.responseData as string;
}
2019-06-23 03:35:23 -07:00
return {
webhookResponse,
2019-06-23 03:35:23 -07:00
workflowData: [
2019-12-21 12:36:08 -08:00
[
response,
],
2019-06-23 03:35:23 -07:00
],
};
}
}