import { Credentials } from 'n8n-core' ; import { ICredentialDataDecryptedObject , ICredentialsExpressionResolveValues , ICredentialsHelper , INode , INodeCredentialsDetails , INodeParameters , INodeProperties , INodeType , INodeTypeData , INodeTypes , NodeHelpers , Workflow , WorkflowExecuteMode , } from 'n8n-workflow' ; import { CredentialsOverwrites , CredentialTypes , Db , ICredentialsDb } from '.' ; const mockNodeTypes = { nodeTypes : { } , init : async ( nodeTypes ? ) : Promise < void > => { } , getAll : ( ) : INodeType [ ] => { return [ ] ; } , getByName : ( nodeType ) : INodeType | undefined => { return undefined ; } , getByNameAndVersion : ( ) : INodeType | undefined => { return undefined ; } , } ; export class CredentialsHelper extends ICredentialsHelper { param { INodeCredentialsDetails } nodeCredentials param { string } type returns { Credentials } memberof async getCredentials ( nodeCredentials , type ) { if ( ! nodeCredentials . id ) { throw new Error ( `Credentials "${ nodeCredentials . name }" for type "${ type }" don't have an ID.` ) ; } const credentials = await Db . collections . Credentials ?. findOne ( { id : nodeCredentials . id , type } ) ; if ( ! credentials ) { throw new Error ( `Credentials with ID "${ nodeCredentials . id }" don't exist for type "${ type }".` ) ; } return new Credentials ( { id : credentials . id . toString ( ) , name : credentials . name } , credentials . type , credentials . nodesAccess , credentials . data ) ; } param { string } type returns { INodeProperties [ ] } memberof getCredentialsProperties ( type ) { const credentialTypes = CredentialTypes ( ) ; const credentialTypeData = credentialTypes . getByName ( type ) ; if ( credentialTypeData === undefined ) { throw new Error ( `The credentials of type "${ type }" are not known.` ) ; } if ( credentialTypeData . extends === undefined ) { return credentialTypeData . properties ; } const combineProperties = [ ] as INodeProperties [ ] ; for ( const credentialsTypeName of credentialTypeData . extends ) { const mergeCredentialProperties = this . getCredentialsProperties ( credentialsTypeName ) ; NodeHelpers . mergeNodeProperties ( combineProperties , mergeCredentialProperties ) ; } NodeHelpers . mergeNodeProperties ( combineProperties , credentialTypeData . properties ) ; return combineProperties ; } param { INodeCredentialsDetails } nodeCredentials param { string } type param { boolean } raw returns { ICredentialDataDecryptedObject } memberof async getDecrypted ( nodeCredentials , type , mode , raw ? , expressionResolveValues ? ) { const credentials = await this . getCredentials ( nodeCredentials , type ) ; const decryptedDataOriginal = credentials . getData ( this . encryptionKey ) ; if ( raw === true ) { return decryptedDataOriginal ; } return this . applyDefaultsAndOverwrites ( decryptedDataOriginal , type , mode , expressionResolveValues ) ; } param { ICredentialDataDecryptedObject } decryptedDataOriginal param { string } type returns { ICredentialDataDecryptedObject } memberof applyDefaultsAndOverwrites ( decryptedDataOriginal , type , mode , expressionResolveValues ? ) { const credentialsProperties = this . getCredentialsProperties ( type ) ; let decryptedData = NodeHelpers . getNodeParameters ( credentialsProperties , decryptedDataOriginal as INodeParameters , true , false ) as ICredentialDataDecryptedObject ; if ( decryptedDataOriginal . oauthTokenData !== undefined ) { decryptedData . oauthTokenData = decryptedDataOriginal . oauthTokenData ; } if ( expressionResolveValues ) { 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 as INodeParameters , expressionResolveValues . runExecutionData , expressionResolveValues . runIndex , expressionResolveValues . itemIndex , expressionResolveValues . node . name , expressionResolveValues . connectionInputData , mode , { } , false , decryptedData ) as ICredentialDataDecryptedObject ; } catch ( e ) { e . message += ' [Error resolving credentials]' ; throw e ; } } else { const node = { name : '' , typeVersion : 1 , type : 'mock' , position : [ 0 , 0 ] , parameters : { } as INodeParameters , } as INode ; const workflow = new Workflow ( { nodes : [ node ] , connections : { } , active : false , nodeTypes : mockNodeTypes , } ) ; decryptedData = workflow . expression . getComplexParameterValue ( node , decryptedData as INodeParameters , mode , { } , undefined , decryptedData ) as ICredentialDataDecryptedObject ; } const credentialsOverwrites = CredentialsOverwrites ( ) ; return credentialsOverwrites . applyOverwrite ( type , decryptedData ) ; } param { string } name param { string } type param { ICredentialDataDecryptedObject } data returns { Promise < void > } memberof async updateCredentials ( nodeCredentials , type , data ) { const credentials = await this . getCredentials ( nodeCredentials , type ) ; if ( Db . collections . Credentials === null ) { await Db . init ( ) ; } credentials . setData ( data , this . encryptionKey ) ; const newCredentialsData = credentials . getDataToSave ( ) as ICredentialsDb ; newCredentialsData . updatedAt = new Date ( ) ; const findQuery = { id : credentials . id , type , } ; await Db . collections . Credentials ! . update ( findQuery , newCredentialsData ) ; } }