n8n/packages/cli/src/TestWebhooks.ts

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

393 lines
11 KiB
TypeScript
Raw Normal View History

import type express from 'express';
import { Service } from 'typedi';
2019-06-23 03:35:23 -07:00
import {
type IWebhookData,
type IWorkflowExecuteAdditionalData,
type IHttpRequestMethods,
type Workflow,
type WorkflowActivateMode,
type WorkflowExecuteMode,
WebhookPathTakenError,
2019-06-23 03:35:23 -07:00
} from 'n8n-workflow';
import type {
IResponseCallbackData,
IWebhookManager,
IWorkflowDb,
RegisteredWebhook,
WebhookAccessControlOptions,
WebhookRequest,
} from '@/Interfaces';
import { Push } from '@/push';
import { NodeTypes } from '@/NodeTypes';
import * as WebhookHelpers from '@/WebhookHelpers';
import { NotFoundError } from './errors/response-errors/not-found.error';
import { TIME } from './constants';
import { WorkflowMissingIdError } from './errors/workflow-missing-id.error';
import { WebhookNotFoundError } from './errors/response-errors/webhook-not-found.error';
import * as NodeExecuteFunctions from 'n8n-core';
2019-06-23 03:35:23 -07:00
@Service()
export class TestWebhooks implements IWebhookManager {
constructor(
private readonly push: Push,
private readonly nodeTypes: NodeTypes,
) {}
private registeredWebhooks: { [webhookKey: string]: RegisteredWebhook } = {};
private workflowWebhooks: { [workflowId: string]: IWebhookData[] } = {};
private webhookUrls: { [webhookUrl: string]: IWebhookData[] } = {};
2019-06-23 03:35:23 -07:00
/**
* Executes a test-webhook and returns the data. It also makes sure that the
* data gets additionally send to the UI. After the request got handled it
* automatically remove the test-webhook.
*/
async executeWebhook(
request: WebhookRequest,
2019-06-23 03:35:23 -07:00
response: express.Response,
): Promise<IResponseCallbackData> {
const httpMethod = request.method;
let path = request.params.path.endsWith('/')
? request.params.path.slice(0, -1)
: request.params.path;
request.params = {} as WebhookRequest['params'];
let webhook = this.getActiveWebhook(httpMethod, path);
if (!webhook) {
// no static webhook, so check if dynamic
// e.g. `/webhook-test/<uuid>/user/:id/create`
const [webhookId, ...segments] = path.split('/');
webhook = this.getActiveWebhook(httpMethod, segments.join('/'), webhookId);
if (!webhook)
throw new WebhookNotFoundError({
path,
httpMethod,
webhookMethods: await this.getWebhookMethods(path),
});
path = webhook.path;
path.split('/').forEach((segment, index) => {
if (segment.startsWith(':')) {
request.params[segment.slice(1)] = segments[index];
: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
}
});
2019-06-23 03:35:23 -07:00
}
const key = [
this.toWebhookKey(webhook.httpMethod, webhook.path, webhook.webhookId),
webhook.workflowId,
].join('|');
if (!(key in this.registeredWebhooks))
throw new WebhookNotFoundError({
path,
httpMethod,
webhookMethods: await this.getWebhookMethods(path),
});
const { destinationNode, sessionId, workflow, workflowEntity, timeout } =
this.registeredWebhooks[key];
2019-06-23 03:35:23 -07:00
// Get the node which has the webhook defined to know where to start from and to
// get additional data
const workflowStartNode = workflow.getNode(webhook.node);
2019-06-23 03:35:23 -07:00
if (workflowStartNode === null) {
throw new NotFoundError('Could not find node to process webhook.');
2019-06-23 03:35:23 -07:00
}
return new Promise(async (resolve, reject) => {
try {
const executionMode = 'manual';
:sparkles: Implement Wait functionality (#1817) * refactor saving * refactor api layer to be stateless * refactor header details * set variable for menu height * clean up scss * clean up indentation * clean up dropdown impl * refactor no tags view * split away header * Fix tslint issues * Refactor tag manager * add tags to patch request * clean up scss * :zap: Refactor types to entities * fix issues * update no workflow error * clean up tagscontainer * use getters instead of state * remove imports * use custom colors * clean up tags container * clean up dropdown * clean up focusoncreate * :zap: Ignore mistaken ID in POST /workflows * :zap: Fix undefined tag ID in PATCH /workflows * :zap: Shorten response for POST /tags * remove scss mixins * clean up imports * :zap: Implement validation with class-validator * address ivan's comments * implement modals * Fix lint issues * fix disabling shortcuts * fix focus issues * fix focus issues * fix focus issues with modal * fix linting issues * use dispatch * use constants for modal keys * fix focus * fix lint issues * remove unused prop * add modal root * fix lint issues * remove unused methods * fix shortcut * remove max width * :zap: Fix duplicate entry error for pg and MySQL * update rename messaging * update order of buttons * fix firefox overflow on windows * fix dropdown height * :hammer: refactor tag crud controllers * 🧹 remove unused imports * use variable for number of items * fix dropdown spacing * :zap: Restore type to fix build * :zap: Fix post-refactor PATCH /workflows/:id * :zap: Fix PATCH /workflows/:id for zero tags * :zap: Fix usage count becoming stringified * address max's comments * fix filter spacing * fix blur bug * address most of ivan's comments * address tags type concern * remove defaults * :zap: return tag id as string * :hammer: add hooks to tag CUD operations * 🏎 simplify timestamp pruning * remove blur event * fix onblur bug * :zap: Fix fs import to fix build * address max's comments * implement responsive tag container * fix lint issues * update tag limits * address ivan's comments * remove rename, refactor header, implement new designs for save, remove responsive tag container * update styling * update styling * implement responsive tag container * implement header tags edit * implement header tags edit * fix lint issues * implement expandable input * minor fixes * minor fixes * use variable * rename save as * duplicate fixes * minor edit fixes * lint fixes * style fixes * hook up saving name * hook up tags * clean up impl * fix dirty state bug * update limit * update notification messages * on click outside * fix minor bug with count * lint fixes * handle minor edge cases * handle minor edge cases * handle minor bugs; fix firefox dropdown issue * Fix min width * apply tags only after api success * remove count fix * clean up workflow tags impl, fix tags delete bug * fix minor issue * fix minor spacing issue * disable wrap for ops * fix viewport root; save on click in dropdown * save button loading when saving name/tags * implement max width on tags container * implement cleaner create experience * disable edit while updating * codacy hex color * refactor tags container * fix clickability * fix workflow open and count * clean up structure * fix up lint issues * fix button size * increase workflow name limit for larger screen * tslint fixes * disable responsiveness for workflow modal * rename event * change min width for tags * clean up pr * address max's comments on styles * remove success toasts * add hover mode to name * minor fixes * refactor name preview * fix name input not to jiggle * finish up name input * Fix up add tags * clean up param * clean up scss * fix resizing name * fix resizing name * fix resize bug * clean up edit spacing * ignore on esc * fix input bug * focus input on clear * build * fix up add tags clickablity * remove scrollbars * move into folders * clean up multiple patch req * remove padding top from edit * update tags on enter * build * rollout blur on enter behavior * rollout esc behavior * fix tags bug when duplicating tags * move key to reload tags * update header spacing * build * update hex case * refactor workflow title * remove unusued prop * keep focus on error, fix bug on error * Fix bug with name / tags toggle on error * fix connection push bug * :spakles: Implement wait functionality * :bug: Do not delete waiting executions with prune * :zap: Improve SQLite migration to not lose execution data anymore * :zap: Make it possible to restart waiting execution via webhook * :zap: Add missing file * :bug: Some more merge fixes * :zap: Do not show error for Wait-Nodes if in time-mode * :zap: Make $executionId available in expressions * :shirt: Fix lint issue * :shirt: Fix lint issue * :shirt: Fix lint issue * :zap: Set the unlimited sleep time as a variable * :zap: Add also sleeping webhook path to config * :zap: Make it possible to retrieve restartUrl in workflow * :zap: Add authentication to Wait-Node in Webhook-Mode * :zap: Return 404 when trying to restart execution via webhook which does not support it * :sparkles: Make it possible to set absolute time on Wait-Node * :zap: Remove not needed imports * :zap: Fix description format * :sparkles: Implement missing webhook features on Wait-Node * :zap: Display webhook variable in NodeWebhooks * :zap: Include also date in displayed sleep time * :zap: Make it possible to see sleep time on node * :zap: Make sure that no executions does get executed twice * :zap: Add comment * :zap: Further improvements * :zap: Make Wait-Node easier to use * :sparkles: Add support for "notice" parameter type * Fixing wait node to work with queue, improved logging and execution view * Added support for mysql and pg * :sparkles: Add support for webhook postfix path * :sparkles: Make it possible to stop sleeping executions * :zap: Fix issue with webhook paths in not webhook mode * :zap: Remove not needed console.log * :zap: Update TODOs * :zap: Increase min time of workflow staying active to descrease possible issue with overlap * :shirt: Fix lint issue * :bug: Fix issues with webhooks * :zap: Make error message clearer * :zap: Fix issue with missing execution ID in scaling mode * Fixed execution list to correctly display waiting executins * Feature: enable webhook wait workflows to continue after specified time * Fixed linting * :zap: Improve waiting description text * :zap: Fix parameter display issue and rename * :zap: Remove comment * :zap: Do not display webhooks on Wait-Node * Changed wording from restart to resume on wait node * Fixed wording and inconsistent screen when changing resume modes * Removed dots from the descriptions * Changed docs url and renaming postfix to suffix * Changed names from sleep to wait * :zap: Apply suggestions from ben Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com> * Some fixes by Ben * :zap: Remove console.logs * :zap: Fixes and improvements Co-authored-by: Mutasem <mutdmour@gmail.com> Co-authored-by: Iván Ovejero <ivov.src@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com> Co-authored-by: Omar Ajoue <krynble@gmail.com>
2021-08-21 05:11:32 -07:00
const executionId = await WebhookHelpers.executeWebhook(
workflow,
webhook!,
workflowEntity,
:sparkles: Implement Wait functionality (#1817) * refactor saving * refactor api layer to be stateless * refactor header details * set variable for menu height * clean up scss * clean up indentation * clean up dropdown impl * refactor no tags view * split away header * Fix tslint issues * Refactor tag manager * add tags to patch request * clean up scss * :zap: Refactor types to entities * fix issues * update no workflow error * clean up tagscontainer * use getters instead of state * remove imports * use custom colors * clean up tags container * clean up dropdown * clean up focusoncreate * :zap: Ignore mistaken ID in POST /workflows * :zap: Fix undefined tag ID in PATCH /workflows * :zap: Shorten response for POST /tags * remove scss mixins * clean up imports * :zap: Implement validation with class-validator * address ivan's comments * implement modals * Fix lint issues * fix disabling shortcuts * fix focus issues * fix focus issues * fix focus issues with modal * fix linting issues * use dispatch * use constants for modal keys * fix focus * fix lint issues * remove unused prop * add modal root * fix lint issues * remove unused methods * fix shortcut * remove max width * :zap: Fix duplicate entry error for pg and MySQL * update rename messaging * update order of buttons * fix firefox overflow on windows * fix dropdown height * :hammer: refactor tag crud controllers * 🧹 remove unused imports * use variable for number of items * fix dropdown spacing * :zap: Restore type to fix build * :zap: Fix post-refactor PATCH /workflows/:id * :zap: Fix PATCH /workflows/:id for zero tags * :zap: Fix usage count becoming stringified * address max's comments * fix filter spacing * fix blur bug * address most of ivan's comments * address tags type concern * remove defaults * :zap: return tag id as string * :hammer: add hooks to tag CUD operations * 🏎 simplify timestamp pruning * remove blur event * fix onblur bug * :zap: Fix fs import to fix build * address max's comments * implement responsive tag container * fix lint issues * update tag limits * address ivan's comments * remove rename, refactor header, implement new designs for save, remove responsive tag container * update styling * update styling * implement responsive tag container * implement header tags edit * implement header tags edit * fix lint issues * implement expandable input * minor fixes * minor fixes * use variable * rename save as * duplicate fixes * minor edit fixes * lint fixes * style fixes * hook up saving name * hook up tags * clean up impl * fix dirty state bug * update limit * update notification messages * on click outside * fix minor bug with count * lint fixes * handle minor edge cases * handle minor edge cases * handle minor bugs; fix firefox dropdown issue * Fix min width * apply tags only after api success * remove count fix * clean up workflow tags impl, fix tags delete bug * fix minor issue * fix minor spacing issue * disable wrap for ops * fix viewport root; save on click in dropdown * save button loading when saving name/tags * implement max width on tags container * implement cleaner create experience * disable edit while updating * codacy hex color * refactor tags container * fix clickability * fix workflow open and count * clean up structure * fix up lint issues * fix button size * increase workflow name limit for larger screen * tslint fixes * disable responsiveness for workflow modal * rename event * change min width for tags * clean up pr * address max's comments on styles * remove success toasts * add hover mode to name * minor fixes * refactor name preview * fix name input not to jiggle * finish up name input * Fix up add tags * clean up param * clean up scss * fix resizing name * fix resizing name * fix resize bug * clean up edit spacing * ignore on esc * fix input bug * focus input on clear * build * fix up add tags clickablity * remove scrollbars * move into folders * clean up multiple patch req * remove padding top from edit * update tags on enter * build * rollout blur on enter behavior * rollout esc behavior * fix tags bug when duplicating tags * move key to reload tags * update header spacing * build * update hex case * refactor workflow title * remove unusued prop * keep focus on error, fix bug on error * Fix bug with name / tags toggle on error * fix connection push bug * :spakles: Implement wait functionality * :bug: Do not delete waiting executions with prune * :zap: Improve SQLite migration to not lose execution data anymore * :zap: Make it possible to restart waiting execution via webhook * :zap: Add missing file * :bug: Some more merge fixes * :zap: Do not show error for Wait-Nodes if in time-mode * :zap: Make $executionId available in expressions * :shirt: Fix lint issue * :shirt: Fix lint issue * :shirt: Fix lint issue * :zap: Set the unlimited sleep time as a variable * :zap: Add also sleeping webhook path to config * :zap: Make it possible to retrieve restartUrl in workflow * :zap: Add authentication to Wait-Node in Webhook-Mode * :zap: Return 404 when trying to restart execution via webhook which does not support it * :sparkles: Make it possible to set absolute time on Wait-Node * :zap: Remove not needed imports * :zap: Fix description format * :sparkles: Implement missing webhook features on Wait-Node * :zap: Display webhook variable in NodeWebhooks * :zap: Include also date in displayed sleep time * :zap: Make it possible to see sleep time on node * :zap: Make sure that no executions does get executed twice * :zap: Add comment * :zap: Further improvements * :zap: Make Wait-Node easier to use * :sparkles: Add support for "notice" parameter type * Fixing wait node to work with queue, improved logging and execution view * Added support for mysql and pg * :sparkles: Add support for webhook postfix path * :sparkles: Make it possible to stop sleeping executions * :zap: Fix issue with webhook paths in not webhook mode * :zap: Remove not needed console.log * :zap: Update TODOs * :zap: Increase min time of workflow staying active to descrease possible issue with overlap * :shirt: Fix lint issue * :bug: Fix issues with webhooks * :zap: Make error message clearer * :zap: Fix issue with missing execution ID in scaling mode * Fixed execution list to correctly display waiting executins * Feature: enable webhook wait workflows to continue after specified time * Fixed linting * :zap: Improve waiting description text * :zap: Fix parameter display issue and rename * :zap: Remove comment * :zap: Do not display webhooks on Wait-Node * Changed wording from restart to resume on wait node * Fixed wording and inconsistent screen when changing resume modes * Removed dots from the descriptions * Changed docs url and renaming postfix to suffix * Changed names from sleep to wait * :zap: Apply suggestions from ben Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com> * Some fixes by Ben * :zap: Remove console.logs * :zap: Fixes and improvements Co-authored-by: Mutasem <mutdmour@gmail.com> Co-authored-by: Iván Ovejero <ivov.src@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com> Co-authored-by: Omar Ajoue <krynble@gmail.com>
2021-08-21 05:11:32 -07:00
workflowStartNode,
executionMode,
sessionId,
:sparkles: Implement Wait functionality (#1817) * refactor saving * refactor api layer to be stateless * refactor header details * set variable for menu height * clean up scss * clean up indentation * clean up dropdown impl * refactor no tags view * split away header * Fix tslint issues * Refactor tag manager * add tags to patch request * clean up scss * :zap: Refactor types to entities * fix issues * update no workflow error * clean up tagscontainer * use getters instead of state * remove imports * use custom colors * clean up tags container * clean up dropdown * clean up focusoncreate * :zap: Ignore mistaken ID in POST /workflows * :zap: Fix undefined tag ID in PATCH /workflows * :zap: Shorten response for POST /tags * remove scss mixins * clean up imports * :zap: Implement validation with class-validator * address ivan's comments * implement modals * Fix lint issues * fix disabling shortcuts * fix focus issues * fix focus issues * fix focus issues with modal * fix linting issues * use dispatch * use constants for modal keys * fix focus * fix lint issues * remove unused prop * add modal root * fix lint issues * remove unused methods * fix shortcut * remove max width * :zap: Fix duplicate entry error for pg and MySQL * update rename messaging * update order of buttons * fix firefox overflow on windows * fix dropdown height * :hammer: refactor tag crud controllers * 🧹 remove unused imports * use variable for number of items * fix dropdown spacing * :zap: Restore type to fix build * :zap: Fix post-refactor PATCH /workflows/:id * :zap: Fix PATCH /workflows/:id for zero tags * :zap: Fix usage count becoming stringified * address max's comments * fix filter spacing * fix blur bug * address most of ivan's comments * address tags type concern * remove defaults * :zap: return tag id as string * :hammer: add hooks to tag CUD operations * 🏎 simplify timestamp pruning * remove blur event * fix onblur bug * :zap: Fix fs import to fix build * address max's comments * implement responsive tag container * fix lint issues * update tag limits * address ivan's comments * remove rename, refactor header, implement new designs for save, remove responsive tag container * update styling * update styling * implement responsive tag container * implement header tags edit * implement header tags edit * fix lint issues * implement expandable input * minor fixes * minor fixes * use variable * rename save as * duplicate fixes * minor edit fixes * lint fixes * style fixes * hook up saving name * hook up tags * clean up impl * fix dirty state bug * update limit * update notification messages * on click outside * fix minor bug with count * lint fixes * handle minor edge cases * handle minor edge cases * handle minor bugs; fix firefox dropdown issue * Fix min width * apply tags only after api success * remove count fix * clean up workflow tags impl, fix tags delete bug * fix minor issue * fix minor spacing issue * disable wrap for ops * fix viewport root; save on click in dropdown * save button loading when saving name/tags * implement max width on tags container * implement cleaner create experience * disable edit while updating * codacy hex color * refactor tags container * fix clickability * fix workflow open and count * clean up structure * fix up lint issues * fix button size * increase workflow name limit for larger screen * tslint fixes * disable responsiveness for workflow modal * rename event * change min width for tags * clean up pr * address max's comments on styles * remove success toasts * add hover mode to name * minor fixes * refactor name preview * fix name input not to jiggle * finish up name input * Fix up add tags * clean up param * clean up scss * fix resizing name * fix resizing name * fix resize bug * clean up edit spacing * ignore on esc * fix input bug * focus input on clear * build * fix up add tags clickablity * remove scrollbars * move into folders * clean up multiple patch req * remove padding top from edit * update tags on enter * build * rollout blur on enter behavior * rollout esc behavior * fix tags bug when duplicating tags * move key to reload tags * update header spacing * build * update hex case * refactor workflow title * remove unusued prop * keep focus on error, fix bug on error * Fix bug with name / tags toggle on error * fix connection push bug * :spakles: Implement wait functionality * :bug: Do not delete waiting executions with prune * :zap: Improve SQLite migration to not lose execution data anymore * :zap: Make it possible to restart waiting execution via webhook * :zap: Add missing file * :bug: Some more merge fixes * :zap: Do not show error for Wait-Nodes if in time-mode * :zap: Make $executionId available in expressions * :shirt: Fix lint issue * :shirt: Fix lint issue * :shirt: Fix lint issue * :zap: Set the unlimited sleep time as a variable * :zap: Add also sleeping webhook path to config * :zap: Make it possible to retrieve restartUrl in workflow * :zap: Add authentication to Wait-Node in Webhook-Mode * :zap: Return 404 when trying to restart execution via webhook which does not support it * :sparkles: Make it possible to set absolute time on Wait-Node * :zap: Remove not needed imports * :zap: Fix description format * :sparkles: Implement missing webhook features on Wait-Node * :zap: Display webhook variable in NodeWebhooks * :zap: Include also date in displayed sleep time * :zap: Make it possible to see sleep time on node * :zap: Make sure that no executions does get executed twice * :zap: Add comment * :zap: Further improvements * :zap: Make Wait-Node easier to use * :sparkles: Add support for "notice" parameter type * Fixing wait node to work with queue, improved logging and execution view * Added support for mysql and pg * :sparkles: Add support for webhook postfix path * :sparkles: Make it possible to stop sleeping executions * :zap: Fix issue with webhook paths in not webhook mode * :zap: Remove not needed console.log * :zap: Update TODOs * :zap: Increase min time of workflow staying active to descrease possible issue with overlap * :shirt: Fix lint issue * :bug: Fix issues with webhooks * :zap: Make error message clearer * :zap: Fix issue with missing execution ID in scaling mode * Fixed execution list to correctly display waiting executins * Feature: enable webhook wait workflows to continue after specified time * Fixed linting * :zap: Improve waiting description text * :zap: Fix parameter display issue and rename * :zap: Remove comment * :zap: Do not display webhooks on Wait-Node * Changed wording from restart to resume on wait node * Fixed wording and inconsistent screen when changing resume modes * Removed dots from the descriptions * Changed docs url and renaming postfix to suffix * Changed names from sleep to wait * :zap: Apply suggestions from ben Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com> * Some fixes by Ben * :zap: Remove console.logs * :zap: Fixes and improvements Co-authored-by: Mutasem <mutdmour@gmail.com> Co-authored-by: Iván Ovejero <ivov.src@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com> Co-authored-by: Omar Ajoue <krynble@gmail.com>
2021-08-21 05:11:32 -07:00
undefined,
undefined,
request,
response,
(error: Error | null, data: IResponseCallbackData) => {
if (error !== null) reject(error);
else resolve(data);
2019-06-23 03:35:23 -07:00
},
destinationNode,
2019-06-23 03:35:23 -07:00
);
// The workflow did not run as the request was probably setup related
// or a ping so do not resolve the promise and wait for the real webhook
// request instead.
if (executionId === undefined) return;
2019-06-23 03:35:23 -07:00
// Inform editor-ui that webhook got received
if (sessionId !== undefined) {
this.push.send(
'testWebhookReceived',
{ workflowId: webhook?.workflowId, executionId },
sessionId,
);
2019-06-23 03:35:23 -07:00
}
} catch {}
2019-06-23 03:35:23 -07:00
// Delete webhook also if an error is thrown
if (timeout) clearTimeout(timeout);
delete this.registeredWebhooks[key];
await this.deactivateWebhooksFor(workflow);
2019-06-23 03:35:23 -07:00
});
}
async getWebhookMethods(path: string) {
const webhookMethods = Object.keys(this.webhookUrls)
.filter((key) => key.includes(path))
.map((key) => key.split('|')[0] as IHttpRequestMethods);
if (!webhookMethods.length) throw new WebhookNotFoundError({ path });
return webhookMethods;
}
async findAccessControlOptions(path: string, httpMethod: IHttpRequestMethods) {
const webhookKey = Object.keys(this.registeredWebhooks).find(
(key) => key.includes(path) && key.startsWith(httpMethod),
);
if (!webhookKey) return;
const { workflow } = this.registeredWebhooks[webhookKey];
const webhookNode = Object.values(workflow.nodes).find(
({ type, parameters, typeVersion }) =>
parameters?.path === path &&
(parameters?.httpMethod ?? 'GET') === httpMethod &&
'webhook' in this.nodeTypes.getByNameAndVersion(type, typeVersion),
);
return webhookNode?.parameters?.options as WebhookAccessControlOptions;
}
async needsWebhook(
workflowEntity: IWorkflowDb,
workflow: Workflow,
additionalData: IWorkflowExecuteAdditionalData,
executionMode: WorkflowExecuteMode,
activationMode: WorkflowActivateMode,
sessionId?: string,
destinationNode?: string,
) {
if (!workflow.id) throw new WorkflowMissingIdError(workflow);
:sparkles: Implement Wait functionality (#1817) * refactor saving * refactor api layer to be stateless * refactor header details * set variable for menu height * clean up scss * clean up indentation * clean up dropdown impl * refactor no tags view * split away header * Fix tslint issues * Refactor tag manager * add tags to patch request * clean up scss * :zap: Refactor types to entities * fix issues * update no workflow error * clean up tagscontainer * use getters instead of state * remove imports * use custom colors * clean up tags container * clean up dropdown * clean up focusoncreate * :zap: Ignore mistaken ID in POST /workflows * :zap: Fix undefined tag ID in PATCH /workflows * :zap: Shorten response for POST /tags * remove scss mixins * clean up imports * :zap: Implement validation with class-validator * address ivan's comments * implement modals * Fix lint issues * fix disabling shortcuts * fix focus issues * fix focus issues * fix focus issues with modal * fix linting issues * use dispatch * use constants for modal keys * fix focus * fix lint issues * remove unused prop * add modal root * fix lint issues * remove unused methods * fix shortcut * remove max width * :zap: Fix duplicate entry error for pg and MySQL * update rename messaging * update order of buttons * fix firefox overflow on windows * fix dropdown height * :hammer: refactor tag crud controllers * 🧹 remove unused imports * use variable for number of items * fix dropdown spacing * :zap: Restore type to fix build * :zap: Fix post-refactor PATCH /workflows/:id * :zap: Fix PATCH /workflows/:id for zero tags * :zap: Fix usage count becoming stringified * address max's comments * fix filter spacing * fix blur bug * address most of ivan's comments * address tags type concern * remove defaults * :zap: return tag id as string * :hammer: add hooks to tag CUD operations * 🏎 simplify timestamp pruning * remove blur event * fix onblur bug * :zap: Fix fs import to fix build * address max's comments * implement responsive tag container * fix lint issues * update tag limits * address ivan's comments * remove rename, refactor header, implement new designs for save, remove responsive tag container * update styling * update styling * implement responsive tag container * implement header tags edit * implement header tags edit * fix lint issues * implement expandable input * minor fixes * minor fixes * use variable * rename save as * duplicate fixes * minor edit fixes * lint fixes * style fixes * hook up saving name * hook up tags * clean up impl * fix dirty state bug * update limit * update notification messages * on click outside * fix minor bug with count * lint fixes * handle minor edge cases * handle minor edge cases * handle minor bugs; fix firefox dropdown issue * Fix min width * apply tags only after api success * remove count fix * clean up workflow tags impl, fix tags delete bug * fix minor issue * fix minor spacing issue * disable wrap for ops * fix viewport root; save on click in dropdown * save button loading when saving name/tags * implement max width on tags container * implement cleaner create experience * disable edit while updating * codacy hex color * refactor tags container * fix clickability * fix workflow open and count * clean up structure * fix up lint issues * fix button size * increase workflow name limit for larger screen * tslint fixes * disable responsiveness for workflow modal * rename event * change min width for tags * clean up pr * address max's comments on styles * remove success toasts * add hover mode to name * minor fixes * refactor name preview * fix name input not to jiggle * finish up name input * Fix up add tags * clean up param * clean up scss * fix resizing name * fix resizing name * fix resize bug * clean up edit spacing * ignore on esc * fix input bug * focus input on clear * build * fix up add tags clickablity * remove scrollbars * move into folders * clean up multiple patch req * remove padding top from edit * update tags on enter * build * rollout blur on enter behavior * rollout esc behavior * fix tags bug when duplicating tags * move key to reload tags * update header spacing * build * update hex case * refactor workflow title * remove unusued prop * keep focus on error, fix bug on error * Fix bug with name / tags toggle on error * fix connection push bug * :spakles: Implement wait functionality * :bug: Do not delete waiting executions with prune * :zap: Improve SQLite migration to not lose execution data anymore * :zap: Make it possible to restart waiting execution via webhook * :zap: Add missing file * :bug: Some more merge fixes * :zap: Do not show error for Wait-Nodes if in time-mode * :zap: Make $executionId available in expressions * :shirt: Fix lint issue * :shirt: Fix lint issue * :shirt: Fix lint issue * :zap: Set the unlimited sleep time as a variable * :zap: Add also sleeping webhook path to config * :zap: Make it possible to retrieve restartUrl in workflow * :zap: Add authentication to Wait-Node in Webhook-Mode * :zap: Return 404 when trying to restart execution via webhook which does not support it * :sparkles: Make it possible to set absolute time on Wait-Node * :zap: Remove not needed imports * :zap: Fix description format * :sparkles: Implement missing webhook features on Wait-Node * :zap: Display webhook variable in NodeWebhooks * :zap: Include also date in displayed sleep time * :zap: Make it possible to see sleep time on node * :zap: Make sure that no executions does get executed twice * :zap: Add comment * :zap: Further improvements * :zap: Make Wait-Node easier to use * :sparkles: Add support for "notice" parameter type * Fixing wait node to work with queue, improved logging and execution view * Added support for mysql and pg * :sparkles: Add support for webhook postfix path * :sparkles: Make it possible to stop sleeping executions * :zap: Fix issue with webhook paths in not webhook mode * :zap: Remove not needed console.log * :zap: Update TODOs * :zap: Increase min time of workflow staying active to descrease possible issue with overlap * :shirt: Fix lint issue * :bug: Fix issues with webhooks * :zap: Make error message clearer * :zap: Fix issue with missing execution ID in scaling mode * Fixed execution list to correctly display waiting executins * Feature: enable webhook wait workflows to continue after specified time * Fixed linting * :zap: Improve waiting description text * :zap: Fix parameter display issue and rename * :zap: Remove comment * :zap: Do not display webhooks on Wait-Node * Changed wording from restart to resume on wait node * Fixed wording and inconsistent screen when changing resume modes * Removed dots from the descriptions * Changed docs url and renaming postfix to suffix * Changed names from sleep to wait * :zap: Apply suggestions from ben Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com> * Some fixes by Ben * :zap: Remove console.logs * :zap: Fixes and improvements Co-authored-by: Mutasem <mutdmour@gmail.com> Co-authored-by: Iván Ovejero <ivov.src@gmail.com> Co-authored-by: Ben Hesseldieck <b.hesseldieck@gmail.com> Co-authored-by: Ben Hesseldieck <1849459+BHesseldieck@users.noreply.github.com> Co-authored-by: Omar Ajoue <krynble@gmail.com>
2021-08-21 05:11:32 -07:00
const webhooks = WebhookHelpers.getWorkflowWebhooks(
workflow,
additionalData,
destinationNode,
true,
);
2019-06-23 03:35:23 -07:00
if (!webhooks.find((w) => w.webhookDescription.restartWebhook !== true)) {
return false; // no webhooks found to start a workflow
}
2019-06-23 03:35:23 -07:00
const timeout = setTimeout(() => {
this.cancelTestWebhook(workflowEntity.id);
}, 2 * TIME.MINUTE);
2019-06-23 03:35:23 -07:00
const activatedKeys: string[] = [];
for (const webhook of webhooks) {
const key = [
this.toWebhookKey(webhook.httpMethod, webhook.path, webhook.webhookId),
workflowEntity.id,
].join('|');
activatedKeys.push(key);
2020-05-30 16:03:58 -07:00
this.registeredWebhooks[key] = {
2019-06-23 03:35:23 -07:00
sessionId,
timeout,
workflow,
workflowEntity,
destinationNode,
2019-06-23 03:35:23 -07:00
};
try {
await this.activateWebhook(workflow, webhook, executionMode, activationMode);
} catch (error) {
activatedKeys.forEach((ak) => delete this.registeredWebhooks[ak]);
await this.deactivateWebhooksFor(workflow);
throw error;
}
}
2019-06-23 03:35:23 -07:00
return true;
}
cancelTestWebhook(workflowId: string) {
2019-06-23 03:35:23 -07:00
let foundWebhook = false;
for (const key of Object.keys(this.registeredWebhooks)) {
const { sessionId, timeout, workflow, workflowEntity } = this.registeredWebhooks[key];
2019-06-23 03:35:23 -07:00
if (workflowEntity.id !== workflowId) continue;
2019-06-23 03:35:23 -07:00
clearTimeout(timeout);
2019-06-23 03:35:23 -07:00
if (sessionId !== undefined) {
2019-06-23 03:35:23 -07:00
try {
this.push.send('testWebhookDeleted', { workflowId }, sessionId);
} catch {
// Could not inform editor, probably is not connected anymore. So simply go on.
2019-06-23 03:35:23 -07:00
}
}
delete this.registeredWebhooks[key];
if (!foundWebhook) {
// As it removes all webhooks of the workflow execute only once
void this.deactivateWebhooksFor(workflow);
}
foundWebhook = true;
2019-06-23 03:35:23 -07:00
}
return foundWebhook;
}
async activateWebhook(
workflow: Workflow,
webhook: IWebhookData,
executionMode: WorkflowExecuteMode,
activationMode: WorkflowActivateMode,
) {
if (!workflow.id) throw new WorkflowMissingIdError(workflow);
if (webhook.path.endsWith('/')) {
webhook.path = webhook.path.slice(0, -1);
}
const key = this.toWebhookKey(webhook.httpMethod, webhook.path, webhook.webhookId);
// check that there is not a webhook already registered with that path/method
if (this.webhookUrls[key] && !webhook.webhookId) {
throw new WebhookPathTakenError(webhook.node);
}
if (this.workflowWebhooks[webhook.workflowId] === undefined) {
this.workflowWebhooks[webhook.workflowId] = [];
}
// Make the webhook available directly because sometimes to create it successfully
// it gets called
if (!this.webhookUrls[key]) {
this.webhookUrls[key] = [];
}
webhook.isTest = true;
this.webhookUrls[key].push(webhook);
try {
await workflow.createWebhookIfNotExists(
webhook,
NodeExecuteFunctions,
executionMode,
activationMode,
);
} catch (error) {
// If there was a problem unregister the webhook again
if (this.webhookUrls[key].length <= 1) {
delete this.webhookUrls[key];
} else {
this.webhookUrls[key] = this.webhookUrls[key].filter((w) => w.path !== w.path);
}
throw error;
}
this.workflowWebhooks[webhook.workflowId].push(webhook);
}
getActiveWebhook(httpMethod: IHttpRequestMethods, path: string, webhookId?: string) {
const webhookKey = this.toWebhookKey(httpMethod, path, webhookId);
if (this.webhookUrls[webhookKey] === undefined) {
return undefined;
}
let webhook: IWebhookData | undefined;
let maxMatches = 0;
const pathElementsSet = new Set(path.split('/'));
// check if static elements match in path
// if more results have been returned choose the one with the most static-route matches
this.webhookUrls[webhookKey].forEach((dynamicWebhook) => {
const staticElements = dynamicWebhook.path.split('/').filter((ele) => !ele.startsWith(':'));
const allStaticExist = staticElements.every((staticEle) => pathElementsSet.has(staticEle));
if (allStaticExist && staticElements.length > maxMatches) {
maxMatches = staticElements.length;
webhook = dynamicWebhook;
}
// handle routes with no static elements
else if (staticElements.length === 0 && !webhook) {
webhook = dynamicWebhook;
}
});
return webhook;
}
toWebhookKey(httpMethod: IHttpRequestMethods, path: string, webhookId?: string) {
if (!webhookId) return `${httpMethod}|${path}`;
if (path.startsWith(webhookId)) {
const cutFromIndex = path.indexOf('/') + 1;
path = path.slice(cutFromIndex);
}
return `${httpMethod}|${webhookId}|${path.split('/').length}`;
}
async deactivateWebhooksFor(workflow: Workflow) {
const workflowId = workflow.id;
if (this.workflowWebhooks[workflowId] === undefined) {
// If it did not exist then there is nothing to remove
return false;
}
const webhooks = this.workflowWebhooks[workflowId];
const mode = 'internal';
// Go through all the registered webhooks of the workflow and remove them
for (const webhookData of webhooks) {
await workflow.deleteWebhook(webhookData, NodeExecuteFunctions, mode, 'update');
const key = this.toWebhookKey(
webhookData.httpMethod,
webhookData.path,
webhookData.webhookId,
);
delete this.webhookUrls[key];
}
// Remove also the workflow-webhook entry
delete this.workflowWebhooks[workflowId];
return true;
}
2019-06-23 03:35:23 -07:00
}