From f354dd1d1f61fd96fa5bcbfc7a86d9c9ffa54aa1 Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Sun, 10 Apr 2022 11:30:47 +0200 Subject: [PATCH] :zap: Set timezone in luxon --- packages/cli/src/CredentialsHelper.ts | 23 +++-- packages/cli/src/Server.ts | 12 +++ packages/cli/src/WebhookHelpers.ts | 61 ++++++-------- .../cli/test/unit/CredentialsHelper.test.ts | 3 + packages/core/src/NodeExecuteFunctions.ts | 21 +++++ .../editor-ui/src/components/CodeEdit.vue | 2 +- .../src/components/VariableSelector.vue | 2 +- .../src/components/mixins/workflowHelpers.ts | 6 +- packages/workflow/src/Expression.ts | 11 +++ packages/workflow/src/Interfaces.ts | 2 + packages/workflow/src/NodeHelpers.ts | 84 +------------------ packages/workflow/src/RoutingNode.ts | 1 + packages/workflow/src/WorkflowDataProxy.ts | 14 +++- packages/workflow/test/Helpers.ts | 6 ++ packages/workflow/test/Workflow.test.ts | 3 + .../workflow/test/WorkflowDataProxy.test.ts | 22 ++--- 16 files changed, 130 insertions(+), 143 deletions(-) diff --git a/packages/cli/src/CredentialsHelper.ts b/packages/cli/src/CredentialsHelper.ts index 6806dd02943a9..27f838fffee73 100644 --- a/packages/cli/src/CredentialsHelper.ts +++ b/packages/cli/src/CredentialsHelper.ts @@ -79,6 +79,7 @@ export class CredentialsHelper extends ICredentialsHelper { incomingRequestOptions: IHttpRequestOptions | IRequestOptionsSimplified, workflow: Workflow, node: INode, + defaultTimezone: string, ): Promise { const requestOptions = incomingRequestOptions; const credentialType = this.credentialTypes.getByName(typeName); @@ -127,6 +128,7 @@ export class CredentialsHelper extends ICredentialsHelper { { $credentials: credentials }, workflow, node, + defaultTimezone, ); const value = this.resolveValue( @@ -135,6 +137,7 @@ export class CredentialsHelper extends ICredentialsHelper { { $credentials: credentials }, workflow, node, + defaultTimezone, ); requestOptions.headers[key] = value; } else if (authenticate.type === 'queryAuth') { @@ -144,6 +147,7 @@ export class CredentialsHelper extends ICredentialsHelper { { $credentials: credentials }, workflow, node, + defaultTimezone, ); const value = this.resolveValue( @@ -152,6 +156,7 @@ export class CredentialsHelper extends ICredentialsHelper { { $credentials: credentials }, workflow, node, + defaultTimezone, ); if (!requestOptions.qs) { requestOptions.qs = {}; @@ -172,6 +177,7 @@ export class CredentialsHelper extends ICredentialsHelper { additionalKeys: IWorkflowDataProxyAdditionalKeys, workflow: Workflow, node: INode, + defaultTimezone: string, ): string { if (parameterValue.charAt(0) !== '=') { return parameterValue; @@ -181,6 +187,7 @@ export class CredentialsHelper extends ICredentialsHelper { node, parameterValue, 'internal', + defaultTimezone, additionalKeys, '', ); @@ -293,6 +300,7 @@ export class CredentialsHelper extends ICredentialsHelper { nodeCredentials: INodeCredentialsDetails, type: string, mode: WorkflowExecuteMode, + defaultTimezone: string, raw?: boolean, expressionResolveValues?: ICredentialsExpressionResolveValues, ): Promise { @@ -307,6 +315,7 @@ export class CredentialsHelper extends ICredentialsHelper { decryptedDataOriginal, type, mode, + defaultTimezone, expressionResolveValues, ); } @@ -323,6 +332,7 @@ export class CredentialsHelper extends ICredentialsHelper { decryptedDataOriginal: ICredentialDataDecryptedObject, type: string, mode: WorkflowExecuteMode, + defaultTimezone: string, expressionResolveValues?: ICredentialsExpressionResolveValues, ): ICredentialDataDecryptedObject { const credentialsProperties = this.getCredentialsProperties(type); @@ -342,14 +352,11 @@ export class CredentialsHelper extends ICredentialsHelper { } if (expressionResolveValues) { + const timezone = + (expressionResolveValues.workflow.settings.timezone as string) || defaultTimezone; + try { - const workflow = new Workflow({ - nodes: Object.values(expressionResolveValues.workflow.nodes), - connections: expressionResolveValues.workflow.connectionsBySourceNode, - active: false, - nodeTypes: expressionResolveValues.workflow.nodeTypes, - }); - decryptedData = workflow.expression.getParameterValue( + decryptedData = expressionResolveValues.workflow.expression.getParameterValue( decryptedData as INodeParameters, expressionResolveValues.runExecutionData, expressionResolveValues.runIndex, @@ -357,6 +364,7 @@ export class CredentialsHelper extends ICredentialsHelper { expressionResolveValues.node.name, expressionResolveValues.connectionInputData, mode, + timezone, {}, false, decryptedData, @@ -387,6 +395,7 @@ export class CredentialsHelper extends ICredentialsHelper { node, decryptedData as INodeParameters, mode, + defaultTimezone, {}, undefined, decryptedData, diff --git a/packages/cli/src/Server.ts b/packages/cli/src/Server.ts index 2b386f048bdf0..d27ca2da112cd 100644 --- a/packages/cli/src/Server.ts +++ b/packages/cli/src/Server.ts @@ -1706,11 +1706,13 @@ class App { } const mode: WorkflowExecuteMode = 'internal'; + const timezone = config.getEnv('generic.timezone'); const credentialsHelper = new CredentialsHelper(encryptionKey); const decryptedDataOriginal = await credentialsHelper.getDecrypted( credential as INodeCredentialsDetails, credential.type, mode, + timezone, true, ); @@ -1718,6 +1720,7 @@ class App { decryptedDataOriginal, credential.type, mode, + timezone, ); const signatureMethod = _.get(oauthCredentials, 'signatureMethod') as string; @@ -1844,17 +1847,20 @@ class App { } const mode: WorkflowExecuteMode = 'internal'; + const timezone = config.getEnv('generic.timezone'); const credentialsHelper = new CredentialsHelper(encryptionKey); const decryptedDataOriginal = await credentialsHelper.getDecrypted( credential as INodeCredentialsDetails, credential.type, mode, + timezone, true, ); const oauthCredentials = credentialsHelper.applyDefaultsAndOverwrites( decryptedDataOriginal, credential.type, mode, + timezone, ); const options: OptionsWithUrl = { @@ -1959,11 +1965,13 @@ class App { } const mode: WorkflowExecuteMode = 'internal'; + const timezone = config.getEnv('generic.timezone'); const credentialsHelper = new CredentialsHelper(encryptionKey); const decryptedDataOriginal = await credentialsHelper.getDecrypted( credential as INodeCredentialsDetails, credential.type, mode, + timezone, true, ); @@ -1971,6 +1979,7 @@ class App { decryptedDataOriginal, credential.type, mode, + timezone, ); const token = new csrf(); @@ -2099,17 +2108,20 @@ class App { } const mode: WorkflowExecuteMode = 'internal'; + const timezone = config.getEnv('generic.timezone'); const credentialsHelper = new CredentialsHelper(encryptionKey); const decryptedDataOriginal = await credentialsHelper.getDecrypted( credential as INodeCredentialsDetails, credential.type, mode, + timezone, true, ); const oauthCredentials = credentialsHelper.applyDefaultsAndOverwrites( decryptedDataOriginal, credential.type, mode, + timezone, ); const token = new csrf(); diff --git a/packages/cli/src/WebhookHelpers.ts b/packages/cli/src/WebhookHelpers.ts index c2af87a0b2c73..ad177e57e77dd 100644 --- a/packages/cli/src/WebhookHelpers.ts +++ b/packages/cli/src/WebhookHelpers.ts @@ -132,26 +132,6 @@ export function encodeWebhookResponse( return response; } -/** - * Returns all the webhooks which should be created for the give workflow - * - * @export - * @param {string} workflowId - * @param {Workflow} workflow - * @returns {IWebhookData[]} - */ -export function getWorkflowWebhooksBasic(workflow: Workflow): IWebhookData[] { - // Check all the nodes in the workflow if they have webhooks - - const returnData: IWebhookData[] = []; - - for (const node of Object.values(workflow.nodes)) { - returnData.push.apply(returnData, NodeHelpers.getNodeWebhooksBasic(workflow, node)); - } - - return returnData; -} - /** * Executes a webhook * @@ -194,11 +174,29 @@ export async function executeWebhook( $executionId: executionId, }; + let user: User; + if ( + (workflowData as WorkflowEntity).shared?.length && + (workflowData as WorkflowEntity).shared[0].user + ) { + user = (workflowData as WorkflowEntity).shared[0].user; + } else { + try { + user = await getWorkflowOwner(workflowData.id.toString()); + } catch (error) { + throw new ResponseHelper.ResponseError('Cannot find workflow', undefined, 404); + } + } + + // Prepare everything that is needed to run the workflow + const additionalData = await WorkflowExecuteAdditionalData.getBase(user.id); + // Get the responseMode const responseMode = workflow.expression.getSimpleParameterValue( workflowStartNode, webhookData.webhookDescription.responseMode, executionMode, + additionalData.timezone, additionalKeys, 'onReceived', ); @@ -206,6 +204,7 @@ export async function executeWebhook( workflowStartNode, webhookData.webhookDescription.responseCode, executionMode, + additionalData.timezone, additionalKeys, 200, ) as number; @@ -214,6 +213,7 @@ export async function executeWebhook( workflowStartNode, webhookData.webhookDescription.responseData, executionMode, + additionalData.timezone, additionalKeys, 'firstEntryJson', ); @@ -227,23 +227,6 @@ export async function executeWebhook( throw new ResponseHelper.ResponseError(errorMessage, 500, 500); } - let user: User; - if ( - (workflowData as WorkflowEntity).shared?.length && - (workflowData as WorkflowEntity).shared[0].user - ) { - user = (workflowData as WorkflowEntity).shared[0].user; - } else { - try { - user = await getWorkflowOwner(workflowData.id.toString()); - } catch (error) { - throw new ResponseHelper.ResponseError('Cannot find workflow', undefined, 404); - } - } - - // Prepare everything that is needed to run the workflow - const additionalData = await WorkflowExecuteAdditionalData.getBase(user.id); - // Add the Response and Request so that this data can be accessed in the node additionalData.httpRequest = req; additionalData.httpResponse = res; @@ -302,6 +285,7 @@ export async function executeWebhook( workflowStartNode, webhookData.webhookDescription.responseHeaders, executionMode, + additionalData.timezone, additionalKeys, undefined, ) as { @@ -560,6 +544,7 @@ export async function executeWebhook( workflowStartNode, webhookData.webhookDescription.responsePropertyName, executionMode, + additionalData.timezone, additionalKeys, undefined, ); @@ -572,6 +557,7 @@ export async function executeWebhook( workflowStartNode, webhookData.webhookDescription.responseContentType, executionMode, + additionalData.timezone, additionalKeys, undefined, ); @@ -616,6 +602,7 @@ export async function executeWebhook( workflowStartNode, webhookData.webhookDescription.responseBinaryPropertyName, executionMode, + additionalData.timezone, additionalKeys, 'data', ); diff --git a/packages/cli/test/unit/CredentialsHelper.test.ts b/packages/cli/test/unit/CredentialsHelper.test.ts index 7617630588bfc..b8de4e0529429 100644 --- a/packages/cli/test/unit/CredentialsHelper.test.ts +++ b/packages/cli/test/unit/CredentialsHelper.test.ts @@ -277,6 +277,8 @@ describe('CredentialsHelper', () => { nodeTypes, }); + const timezone = 'America/New_York'; + for (const testData of tests) { test(testData.description, async () => { const credentialTypes: ICredentialTypeData = { @@ -296,6 +298,7 @@ describe('CredentialsHelper', () => { JSON.parse(JSON.stringify(incomingRequestOptions)), workflow, node, + timezone, ); expect(result).toEqual(testData.output); diff --git a/packages/core/src/NodeExecuteFunctions.ts b/packages/core/src/NodeExecuteFunctions.ts index cdb171e8b5604..c742cd08e43fc 100644 --- a/packages/core/src/NodeExecuteFunctions.ts +++ b/packages/core/src/NodeExecuteFunctions.ts @@ -1100,6 +1100,7 @@ export async function httpRequestWithAuthentication( requestOptions, workflow, node, + additionalData.timezone, ); return await httpRequest(requestOptions); @@ -1222,6 +1223,7 @@ export async function requestWithAuthentication( requestOptions as IHttpRequestOptions, workflow, node, + additionalData.timezone, ); return await proxyRequestToAxios(requestOptions as IDataObject); @@ -1372,6 +1374,7 @@ export async function getCredentials( nodeCredentials, type, mode, + additionalData.timezone, false, expressionResolveValues, ); @@ -1413,6 +1416,7 @@ export function getNodeParameter( parameterName: string, itemIndex: number, mode: WorkflowExecuteMode, + timezone: string, additionalKeys: IWorkflowDataProxyAdditionalKeys, fallbackValue?: any, ): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object { @@ -1437,6 +1441,7 @@ export function getNodeParameter( node.name, connectionInputData, mode, + timezone, additionalKeys, ); } catch (e) { @@ -1475,6 +1480,7 @@ export function getNodeWebhookUrl( node: INode, additionalData: IWorkflowExecuteAdditionalData, mode: WorkflowExecuteMode, + timezone: string, additionalKeys: IWorkflowDataProxyAdditionalKeys, isTest?: boolean, ): string | undefined { @@ -1493,6 +1499,7 @@ export function getNodeWebhookUrl( node, webhookDescription.path, mode, + timezone, additionalKeys, ); if (path === undefined) { @@ -1503,6 +1510,7 @@ export function getNodeWebhookUrl( node, webhookDescription.isFullPath, mode, + timezone, additionalKeys, false, ) as boolean; @@ -1632,6 +1640,7 @@ export function getExecutePollFunctions( parameterName, itemIndex, mode, + additionalData.timezone, getAdditionalKeys(additionalData), fallbackValue, ); @@ -1785,6 +1794,7 @@ export function getExecuteTriggerFunctions( parameterName, itemIndex, mode, + additionalData.timezone, getAdditionalKeys(additionalData), fallbackValue, ); @@ -1916,6 +1926,7 @@ export function getExecuteFunctions( node.name, connectionInputData, mode, + additionalData.timezone, getAdditionalKeys(additionalData), ); }, @@ -1991,6 +2002,7 @@ export function getExecuteFunctions( parameterName, itemIndex, mode, + additionalData.timezone, getAdditionalKeys(additionalData), fallbackValue, ); @@ -2020,6 +2032,7 @@ export function getExecuteFunctions( connectionInputData, {}, mode, + additionalData.timezone, getAdditionalKeys(additionalData), ); return dataProxy.getDataProxy(); @@ -2173,6 +2186,7 @@ export function getExecuteSingleFunctions( node.name, connectionInputData, mode, + additionalData.timezone, getAdditionalKeys(additionalData), ); }, @@ -2249,6 +2263,7 @@ export function getExecuteSingleFunctions( parameterName, itemIndex, mode, + additionalData.timezone, getAdditionalKeys(additionalData), fallbackValue, ); @@ -2266,6 +2281,7 @@ export function getExecuteSingleFunctions( connectionInputData, {}, mode, + additionalData.timezone, getAdditionalKeys(additionalData), ); return dataProxy.getDataProxy(); @@ -2422,6 +2438,7 @@ export function getLoadOptionsFunctions( parameterName, itemIndex, 'internal' as WorkflowExecuteMode, + additionalData.timezone, getAdditionalKeys(additionalData), fallbackValue, ); @@ -2551,6 +2568,7 @@ export function getExecuteHookFunctions( parameterName, itemIndex, mode, + additionalData.timezone, getAdditionalKeys(additionalData), fallbackValue, ); @@ -2562,6 +2580,7 @@ export function getExecuteHookFunctions( node, additionalData, mode, + additionalData.timezone, getAdditionalKeys(additionalData), isTest, ); @@ -2711,6 +2730,7 @@ export function getExecuteWebhookFunctions( parameterName, itemIndex, mode, + additionalData.timezone, getAdditionalKeys(additionalData), fallbackValue, ); @@ -2746,6 +2766,7 @@ export function getExecuteWebhookFunctions( node, additionalData, mode, + additionalData.timezone, getAdditionalKeys(additionalData), ); }, diff --git a/packages/editor-ui/src/components/CodeEdit.vue b/packages/editor-ui/src/components/CodeEdit.vue index 59461a3c782ca..04a5808d481a6 100644 --- a/packages/editor-ui/src/components/CodeEdit.vue +++ b/packages/editor-ui/src/components/CodeEdit.vue @@ -171,7 +171,7 @@ export default mixins( $resumeWebhookUrl: PLACEHOLDER_FILLED_AT_EXECUTION_TIME, }; - const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, activeNode!.name, connectionInputData || [], {}, mode, additionalProxyKeys); + const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, activeNode!.name, connectionInputData || [], {}, mode, this.$store.getters.timezone, additionalProxyKeys); const proxy = dataProxy.getDataProxy(); const autoCompleteItems = [ diff --git a/packages/editor-ui/src/components/VariableSelector.vue b/packages/editor-ui/src/components/VariableSelector.vue index bbee96a932f40..03d6621364a40 100644 --- a/packages/editor-ui/src/components/VariableSelector.vue +++ b/packages/editor-ui/src/components/VariableSelector.vue @@ -386,7 +386,7 @@ export default mixins( $resumeWebhookUrl: PLACEHOLDER_FILLED_AT_EXECUTION_TIME, }; - const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, nodeName, connectionInputData, {}, 'manual', additionalKeys); + const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, nodeName, connectionInputData, {}, 'manual', this.$store.getters.timezone, additionalKeys); const proxy = dataProxy.getDataProxy(); // @ts-ignore diff --git a/packages/editor-ui/src/components/mixins/workflowHelpers.ts b/packages/editor-ui/src/components/mixins/workflowHelpers.ts index 3c8965c2dcaf4..d7a34ae81f18a 100644 --- a/packages/editor-ui/src/components/mixins/workflowHelpers.ts +++ b/packages/editor-ui/src/components/mixins/workflowHelpers.ts @@ -249,9 +249,9 @@ export const workflowHelpers = mixins( const workflowName = this.$store.getters.workflowName; if (copyData === true) { - return new Workflow({ id: workflowId, name: workflowName, nodes: JSON.parse(JSON.stringify(nodes)), connections: JSON.parse(JSON.stringify(connections)), active: false, nodeTypes}); + return new Workflow({ id: workflowId, name: workflowName, nodes: JSON.parse(JSON.stringify(nodes)), connections: JSON.parse(JSON.stringify(connections)), active: false, nodeTypes, settings: this.$store.getters.workflowSettings}); } else { - return new Workflow({ id: workflowId, name: workflowName, nodes, connections, active: false, nodeTypes}); + return new Workflow({ id: workflowId, name: workflowName, nodes, connections, active: false, nodeTypes, settings: this.$store.getters.workflowSettings}); } }, @@ -408,7 +408,7 @@ export const workflowHelpers = mixins( $resumeWebhookUrl: PLACEHOLDER_FILLED_AT_EXECUTION_TIME, }; - return workflow.expression.getParameterValue(parameter, runExecutionData, runIndex, itemIndex, activeNode.name, connectionInputData, 'manual', additionalKeys, false) as IDataObject; + return workflow.expression.getParameterValue(parameter, runExecutionData, runIndex, itemIndex, activeNode.name, connectionInputData, 'manual', this.$store.getters.timezone, additionalKeys, false) as IDataObject; }, resolveExpression(expression: string, siblingParameters: INodeParameters = {}) { diff --git a/packages/workflow/src/Expression.ts b/packages/workflow/src/Expression.ts index e14c9b960a4f4..b89b9114cdee9 100644 --- a/packages/workflow/src/Expression.ts +++ b/packages/workflow/src/Expression.ts @@ -69,6 +69,7 @@ export class Expression { activeNodeName: string, connectionInputData: INodeExecutionData[], mode: WorkflowExecuteMode, + timezone: string, additionalKeys: IWorkflowDataProxyAdditionalKeys, returnObjectAsString = false, selfData = {}, @@ -95,6 +96,7 @@ export class Expression { connectionInputData, siblingParameters, mode, + timezone, additionalKeys, -1, selfData, @@ -157,6 +159,7 @@ export class Expression { node: INode, parameterValue: string | boolean | undefined, mode: WorkflowExecuteMode, + timezone: string, additionalKeys: IWorkflowDataProxyAdditionalKeys, defaultValue?: boolean | number | string, ): boolean | number | string | undefined { @@ -183,6 +186,7 @@ export class Expression { node.name, connectionInputData, mode, + timezone, additionalKeys, ) as boolean | number | string | undefined; } @@ -200,6 +204,7 @@ export class Expression { node: INode, parameterValue: NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[], mode: WorkflowExecuteMode, + timezone: string, additionalKeys: IWorkflowDataProxyAdditionalKeys, defaultValue: | NodeParameterValue @@ -233,6 +238,7 @@ export class Expression { node.name, connectionInputData, mode, + timezone, additionalKeys, false, selfData, @@ -247,6 +253,7 @@ export class Expression { node.name, connectionInputData, mode, + timezone, additionalKeys, false, selfData, @@ -276,6 +283,7 @@ export class Expression { activeNodeName: string, connectionInputData: INodeExecutionData[], mode: WorkflowExecuteMode, + timezone: string, additionalKeys: IWorkflowDataProxyAdditionalKeys, returnObjectAsString = false, selfData = {}, @@ -301,6 +309,7 @@ export class Expression { activeNodeName, connectionInputData, mode, + timezone, additionalKeys, returnObjectAsString, selfData, @@ -315,6 +324,7 @@ export class Expression { activeNodeName, connectionInputData, mode, + timezone, additionalKeys, returnObjectAsString, selfData, @@ -332,6 +342,7 @@ export class Expression { activeNodeName, connectionInputData, mode, + timezone, additionalKeys, returnObjectAsString, selfData, diff --git a/packages/workflow/src/Interfaces.ts b/packages/workflow/src/Interfaces.ts index 5a0fba9d00b0e..240a912b71a94 100644 --- a/packages/workflow/src/Interfaces.ts +++ b/packages/workflow/src/Interfaces.ts @@ -160,6 +160,7 @@ export abstract class ICredentialsHelper { requestOptions: IHttpRequestOptions | IRequestOptionsSimplified, workflow: Workflow, node: INode, + defaultTimezone: string, ): Promise; abstract getCredentials( @@ -171,6 +172,7 @@ export abstract class ICredentialsHelper { nodeCredentials: INodeCredentialsDetails, type: string, mode: WorkflowExecuteMode, + defaultTimezone: string, raw?: boolean, expressionResolveValues?: ICredentialsExpressionResolveValues, ): Promise; diff --git a/packages/workflow/src/NodeHelpers.ts b/packages/workflow/src/NodeHelpers.ts index f56fc5d9437c1..109905be0ba79 100644 --- a/packages/workflow/src/NodeHelpers.ts +++ b/packages/workflow/src/NodeHelpers.ts @@ -867,6 +867,7 @@ export function getNodeWebhooks( node, webhookDescription.path, mode, + additionalData.timezone, {}, ); if (nodeWebhookPath === undefined) { @@ -890,6 +891,7 @@ export function getNodeWebhooks( node, webhookDescription.isFullPath, 'internal', + additionalData.timezone, {}, false, ) as boolean; @@ -897,6 +899,7 @@ export function getNodeWebhooks( node, webhookDescription.restartWebhook, 'internal', + additionalData.timezone, {}, false, ) as boolean; @@ -906,6 +909,7 @@ export function getNodeWebhooks( node, webhookDescription.httpMethod, mode, + additionalData.timezone, {}, 'GET', ); @@ -937,86 +941,6 @@ export function getNodeWebhooks( return returnData; } -export function getNodeWebhooksBasic(workflow: Workflow, node: INode): IWebhookData[] { - if (node.disabled === true) { - // Node is disabled so webhooks will also not be enabled - return []; - } - - const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion) as INodeType; - - if (nodeType.description.webhooks === undefined) { - // Node does not have any webhooks so return - return []; - } - - const workflowId = workflow.id || '__UNSAVED__'; - - const mode = 'internal'; - - const returnData: IWebhookData[] = []; - for (const webhookDescription of nodeType.description.webhooks) { - let nodeWebhookPath = workflow.expression.getSimpleParameterValue( - node, - webhookDescription.path, - mode, - {}, - ); - if (nodeWebhookPath === undefined) { - // TODO: Use a proper logger - console.error( - `No webhook path could be found for node "${node.name}" in workflow "${workflowId}".`, - ); - continue; - } - - nodeWebhookPath = nodeWebhookPath.toString(); - - if (nodeWebhookPath.startsWith('/')) { - nodeWebhookPath = nodeWebhookPath.slice(1); - } - if (nodeWebhookPath.endsWith('/')) { - nodeWebhookPath = nodeWebhookPath.slice(0, -1); - } - - const isFullPath: boolean = workflow.expression.getSimpleParameterValue( - node, - webhookDescription.isFullPath, - mode, - {}, - false, - ) as boolean; - - const path = getNodeWebhookPath(workflowId, node, nodeWebhookPath, isFullPath); - - const httpMethod = workflow.expression.getSimpleParameterValue( - node, - webhookDescription.httpMethod, - mode, - {}, - ); - - if (httpMethod === undefined) { - // TODO: Use a proper logger - console.error( - `The webhook "${path}" for node "${node.name}" in workflow "${workflowId}" could not be added because the httpMethod is not defined.`, - ); - continue; - } - - // @ts-ignore - returnData.push({ - httpMethod: httpMethod.toString() as WebhookHttpMethod, - node: node.name, - path, - webhookDescription, - workflowId, - }); - } - - return returnData; -} - /** * Returns the webhook path * diff --git a/packages/workflow/src/RoutingNode.ts b/packages/workflow/src/RoutingNode.ts index 6a6aab984d107..d7779be17493a 100644 --- a/packages/workflow/src/RoutingNode.ts +++ b/packages/workflow/src/RoutingNode.ts @@ -558,6 +558,7 @@ export class RoutingNode { this.node.name, this.connectionInputData, this.mode, + this.additionalData.timezone, additionalKeys ?? {}, returnObjectAsString, ); diff --git a/packages/workflow/src/WorkflowDataProxy.ts b/packages/workflow/src/WorkflowDataProxy.ts index 7e7416e694de9..4cfc185a370ac 100644 --- a/packages/workflow/src/WorkflowDataProxy.ts +++ b/packages/workflow/src/WorkflowDataProxy.ts @@ -7,7 +7,7 @@ /* eslint-disable no-prototype-builtins */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ -import { DateTime, Duration, Interval } from 'luxon'; +import { DateTime, Duration, Interval, Settings } from 'luxon'; import * as jmespath from 'jmespath'; // eslint-disable-next-line import/no-cycle @@ -47,6 +47,10 @@ export class WorkflowDataProxy { private additionalKeys: IWorkflowDataProxyAdditionalKeys; + private defaultTimezone: string; + + private timezone: string; + constructor( workflow: Workflow, runExecutionData: IRunExecutionData | null, @@ -56,6 +60,7 @@ export class WorkflowDataProxy { connectionInputData: INodeExecutionData[], siblingParameters: INodeParameters, mode: WorkflowExecuteMode, + defaultTimezone: string, additionalKeys: IWorkflowDataProxyAdditionalKeys, defaultReturnRunIndex = -1, selfData = {}, @@ -69,8 +74,12 @@ export class WorkflowDataProxy { this.connectionInputData = connectionInputData; this.siblingParameters = siblingParameters; this.mode = mode; + this.defaultTimezone = defaultTimezone; + this.timezone = (this.workflow.settings.timezone as string) || this.defaultTimezone; this.selfData = selfData; this.additionalKeys = additionalKeys; + + Settings.defaultZone = this.timezone; } /** @@ -191,6 +200,7 @@ export class WorkflowDataProxy { that.activeNodeName, that.connectionInputData, that.mode, + that.timezone, that.additionalKeys, ); } @@ -633,6 +643,7 @@ export class WorkflowDataProxy { that.activeNodeName, that.connectionInputData, that.mode, + that.timezone, that.additionalKeys, ); }, @@ -647,6 +658,7 @@ export class WorkflowDataProxy { this.connectionInputData, that.siblingParameters, that.mode, + that.defaultTimezone, that.additionalKeys, defaultReturnRunIndex, ); diff --git a/packages/workflow/test/Helpers.ts b/packages/workflow/test/Helpers.ts index 58df9f09332ec..8e66d737d196a 100644 --- a/packages/workflow/test/Helpers.ts +++ b/packages/workflow/test/Helpers.ts @@ -144,6 +144,7 @@ export function getNodeParameter( parameterName: string, itemIndex: number, mode: WorkflowExecuteMode, + timezone: string, additionalKeys: IWorkflowDataProxyAdditionalKeys, fallbackValue?: any, ): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object { @@ -168,6 +169,7 @@ export function getNodeParameter( node.name, connectionInputData, mode, + timezone, additionalKeys, ); } catch (e) { @@ -253,6 +255,7 @@ export function getExecuteFunctions( parameterName, itemIndex, mode, + additionalData.timezone, {}, fallbackValue, ); @@ -286,6 +289,7 @@ export function getExecuteFunctions( connectionInputData, {}, mode, + additionalData.timezone, {}, ); return dataProxy.getDataProxy(); @@ -445,6 +449,7 @@ export function getExecuteSingleFunctions( parameterName, itemIndex, mode, + additionalData.timezone, {}, fallbackValue, ); @@ -466,6 +471,7 @@ export function getExecuteSingleFunctions( connectionInputData, {}, mode, + additionalData.timezone, {}, ); return dataProxy.getDataProxy(); diff --git a/packages/workflow/test/Workflow.test.ts b/packages/workflow/test/Workflow.test.ts index effb4963701c5..453bdcc2d8e10 100644 --- a/packages/workflow/test/Workflow.test.ts +++ b/packages/workflow/test/Workflow.test.ts @@ -998,6 +998,7 @@ describe('Workflow', () => { ]; const nodeTypes = Helpers.NodeTypes(); + const timezone = 'America/New_York'; for (const testData of tests) { test(testData.description, () => { @@ -1110,6 +1111,7 @@ describe('Workflow', () => { activeNodeName, connectionInputData, 'manual', + timezone, {}, ); // @ts-ignore @@ -1264,6 +1266,7 @@ describe('Workflow', () => { activeNodeName, connectionInputData, 'manual', + timezone, {}, ); diff --git a/packages/workflow/test/WorkflowDataProxy.test.ts b/packages/workflow/test/WorkflowDataProxy.test.ts index 3d795c414e83c..9509a36ddb96d 100644 --- a/packages/workflow/test/WorkflowDataProxy.test.ts +++ b/packages/workflow/test/WorkflowDataProxy.test.ts @@ -1,11 +1,6 @@ import { Workflow, WorkflowDataProxy } from '../src'; import * as Helpers from './Helpers'; -import { - IConnections, - INode, - INodeExecutionData, - IRunExecutionData, -} from '../src/Interfaces'; +import { IConnections, INode, INodeExecutionData, IRunExecutionData } from '../src/Interfaces'; describe('WorkflowDataProxy', () => { describe('test data proxy', () => { @@ -133,13 +128,13 @@ describe('WorkflowDataProxy', () => { }, }; - const renameNodeConnectionInputData: INodeExecutionData[] = [ - { json: { length: 105 } }, - { json: { length: 160 } }, - { json: { length: 121 } }, - { json: { length: 275 } }, - { json: { length: 950 } } - ] + const renameNodeConnectionInputData: INodeExecutionData[] = [ + { json: { length: 105 } }, + { json: { length: 160 } }, + { json: { length: 121 } }, + { json: { length: 275 } }, + { json: { length: 950 } }, + ]; const nodeTypes = Helpers.NodeTypes(); const workflow = new Workflow({ nodes, connections, active: false, nodeTypes }); @@ -153,6 +148,7 @@ describe('WorkflowDataProxy', () => { renameNodeConnectionInputData || [], {}, 'manual', + 'America/New_York', {}, ); const proxy = dataProxy.getDataProxy();