From 1dedb3f4b87750aeea4e7b00ea2d5bf6b8258cc5 Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Sun, 24 Jan 2021 13:33:57 +0100 Subject: [PATCH] :sparkles: Add expression support to credentials --- packages/cli/src/CredentialsHelper.ts | 37 ++++++++++++------- packages/core/src/NodeExecuteFunctions.ts | 23 +++++++++--- .../src/components/CredentialsInput.vue | 2 +- .../src/components/NodeCredentials.vue | 2 +- .../src/components/ParameterInput.vue | 6 +-- packages/workflow/src/Interfaces.ts | 13 ++++++- 6 files changed, 56 insertions(+), 27 deletions(-) diff --git a/packages/cli/src/CredentialsHelper.ts b/packages/cli/src/CredentialsHelper.ts index 4eae7932ce..4da6d76e4e 100644 --- a/packages/cli/src/CredentialsHelper.ts +++ b/packages/cli/src/CredentialsHelper.ts @@ -4,6 +4,7 @@ import { import { ICredentialDataDecryptedObject, + ICredentialsExpressionResolveValues, ICredentialsHelper, INode, INodeParameters, @@ -100,7 +101,7 @@ export class CredentialsHelper extends ICredentialsHelper { * @returns {ICredentialDataDecryptedObject} * @memberof CredentialsHelper */ - getDecrypted(name: string, type: string, raw?: boolean): ICredentialDataDecryptedObject { + getDecrypted(name: string, type: string, raw?: boolean, expressionResolveValues?: ICredentialsExpressionResolveValues): ICredentialDataDecryptedObject { const credentials = this.getCredentials(name, type); const decryptedDataOriginal = credentials.getData(this.encryptionKey); @@ -109,7 +110,7 @@ export class CredentialsHelper extends ICredentialsHelper { return decryptedDataOriginal; } - return this.applyDefaultsAndOverwrites(decryptedDataOriginal, type); + return this.applyDefaultsAndOverwrites(decryptedDataOriginal, type, expressionResolveValues); } @@ -121,7 +122,7 @@ export class CredentialsHelper extends ICredentialsHelper { * @returns {ICredentialDataDecryptedObject} * @memberof CredentialsHelper */ - applyDefaultsAndOverwrites(decryptedDataOriginal: ICredentialDataDecryptedObject, type: string): ICredentialDataDecryptedObject { + applyDefaultsAndOverwrites(decryptedDataOriginal: ICredentialDataDecryptedObject, type: string, expressionResolveValues?: ICredentialsExpressionResolveValues): ICredentialDataDecryptedObject { const credentialsProperties = this.getCredentialsProperties(type); // Add the default credential values @@ -133,17 +134,27 @@ export class CredentialsHelper extends ICredentialsHelper { decryptedData.oauthTokenData = decryptedDataOriginal.oauthTokenData; } - const mockNode: INode = { - name: '', - typeVersion: 1, - type: 'mock', - position: [0, 0], - parameters: decryptedData as INodeParameters, - }; + if (expressionResolveValues) { + try { + decryptedData = expressionResolveValues.workflow.expression.getParameterValue(decryptedData as INodeParameters, expressionResolveValues.runExecutionData, expressionResolveValues.runIndex, expressionResolveValues.itemIndex, expressionResolveValues.node.name, expressionResolveValues.connectionInputData) as ICredentialDataDecryptedObject; + } catch (e) { + e.message += ' [Error resolving credentials]'; + throw e; + } + } else { + const node = { + name: '', + typeVersion: 1, + type: 'mock', + position: [0, 0], + parameters: decryptedData as INodeParameters, + } as INode; - const workflow = new Workflow({ nodes: [mockNode], connections: {}, active: false, nodeTypes: mockNodeTypes}); - // Resolve expressions if any are set - decryptedData = workflow.expression.getComplexParameterValue(mockNode, decryptedData as INodeParameters, undefined) as ICredentialDataDecryptedObject; + const workflow = new Workflow({ nodes: [node!], connections: {}, active: false, nodeTypes: mockNodeTypes }); + + // Resolve expressions if any are set + decryptedData = workflow.expression.getComplexParameterValue(node!, decryptedData as INodeParameters, undefined) as ICredentialDataDecryptedObject; + } // Load and apply the credentials overwrites if any exist const credentialsOverwrites = CredentialsOverwrites(); diff --git a/packages/core/src/NodeExecuteFunctions.ts b/packages/core/src/NodeExecuteFunctions.ts index 3ad9b2477b..c944c0de72 100644 --- a/packages/core/src/NodeExecuteFunctions.ts +++ b/packages/core/src/NodeExecuteFunctions.ts @@ -11,6 +11,7 @@ import { IBinaryData, IContextObject, ICredentialDataDecryptedObject, + ICredentialsExpressionResolveValues, IDataObject, IExecuteFunctions, IExecuteSingleFunctions, @@ -298,7 +299,7 @@ export function returnJsonArray(jsonData: IDataObject | IDataObject[]): INodeExe * @param {IWorkflowExecuteAdditionalData} additionalData * @returns {(ICredentialDataDecryptedObject | undefined)} */ -export function getCredentials(workflow: Workflow, node: INode, type: string, additionalData: IWorkflowExecuteAdditionalData): ICredentialDataDecryptedObject | undefined { +export function getCredentials(workflow: Workflow, node: INode, type: string, additionalData: IWorkflowExecuteAdditionalData, runExecutionData?: IRunExecutionData | null, runIndex?: number, connectionInputData?: INodeExecutionData[], itemIndex?: number): ICredentialDataDecryptedObject | undefined { // Get the NodeType as it has the information if the credentials are required const nodeType = workflow.nodeTypes.getByName(node.type); @@ -338,9 +339,21 @@ export function getCredentials(workflow: Workflow, node: INode, type: string, ad } } + let expressionResolveValues: ICredentialsExpressionResolveValues | undefined; + if (connectionInputData && runExecutionData && runIndex !== undefined) { + expressionResolveValues = { + connectionInputData, + itemIndex: itemIndex || 0, + node, + runExecutionData, + runIndex, + workflow, + } as ICredentialsExpressionResolveValues; + } + const name = node.credentials[type]; - const decryptedDataObject = additionalData.credentialsHelper.getDecrypted(name, type); + const decryptedDataObject = additionalData.credentialsHelper.getDecrypted(name, type, false, expressionResolveValues); return decryptedDataObject; } @@ -662,8 +675,8 @@ export function getExecuteFunctions(workflow: Workflow, runExecutionData: IRunEx getContext(type: string): IContextObject { return NodeHelpers.getContext(runExecutionData, type, node); }, - getCredentials(type: string): ICredentialDataDecryptedObject | undefined { - return getCredentials(workflow, node, type, additionalData); + getCredentials(type: string, itemIndex?: number): ICredentialDataDecryptedObject | undefined { + return getCredentials(workflow, node, type, additionalData, runExecutionData, runIndex, connectionInputData, itemIndex); }, getInputData: (inputIndex = 0, inputName = 'main') => { @@ -758,7 +771,7 @@ export function getExecuteSingleFunctions(workflow: Workflow, runExecutionData: return NodeHelpers.getContext(runExecutionData, type, node); }, getCredentials(type: string): ICredentialDataDecryptedObject | undefined { - return getCredentials(workflow, node, type, additionalData); + return getCredentials(workflow, node, type, additionalData, runExecutionData, runIndex, connectionInputData, itemIndex); }, getInputData: (inputIndex = 0, inputName = 'main') => { if (!inputData.hasOwnProperty(inputName)) { diff --git a/packages/editor-ui/src/components/CredentialsInput.vue b/packages/editor-ui/src/components/CredentialsInput.vue index 0da2b05adb..e5c25b8121 100644 --- a/packages/editor-ui/src/components/CredentialsInput.vue +++ b/packages/editor-ui/src/components/CredentialsInput.vue @@ -30,7 +30,7 @@ - + diff --git a/packages/editor-ui/src/components/NodeCredentials.vue b/packages/editor-ui/src/components/NodeCredentials.vue index 1eb9cf7d3b..ba5115d015 100644 --- a/packages/editor-ui/src/components/NodeCredentials.vue +++ b/packages/editor-ui/src/components/NodeCredentials.vue @@ -1,6 +1,6 @@