add credentials

This commit is contained in:
Henry
2023-07-15 14:25:52 +01:00
parent aee0a51f73
commit 413d654493
37 changed files with 1858 additions and 126 deletions
+10
View File
@@ -59,7 +59,9 @@ export interface INodeParams {
description?: string
warning?: string
options?: Array<INodeOptionsValue>
credentialNames?: Array<string>
optional?: boolean | INodeDisplay
step?: number
rows?: number
list?: boolean
acceptVariable?: boolean
@@ -102,10 +104,18 @@ export interface INodeData extends INodeProperties {
id: string
inputs?: ICommonObject
outputs?: ICommonObject
credential?: string
instance?: any
loadMethod?: string // method to load async options
}
export interface INodeCredential {
label: string
name: string
description?: string
inputs?: INodeParams[]
}
export interface IMessage {
message: string
type: MessageType
+86
View File
@@ -6,6 +6,9 @@ import { JSDOM } from 'jsdom'
import { BaseCallbackHandler } from 'langchain/callbacks'
import { Server } from 'socket.io'
import { ChainValues } from 'langchain/dist/schema'
import { DataSource } from 'typeorm'
import { ICommonObject, IDatabaseEntity, INodeData } from './Interface'
import { AES, enc } from 'crypto-js'
export const numberOrExpressionRegex = '^(\\d+\\.?\\d*|{{.*}})$' //return true if string consists only numbers OR expression {{}}
export const notEmptyRegex = '(.|\\s)*\\S(.|\\s)*' //return true if string is not empty or blank
@@ -350,6 +353,89 @@ export const getEnvironmentVariable = (name: string): string | undefined => {
}
}
/**
* Returns the path of encryption key
* @returns {string}
*/
const getEncryptionKeyFilePath = (): string => {
const checkPaths = [
path.join(__dirname, '..', '..', 'server', 'encryption.key'),
path.join(__dirname, '..', '..', '..', 'server', 'encryption.key'),
path.join(__dirname, '..', '..', '..', '..', 'server', 'encryption.key'),
path.join(__dirname, '..', '..', '..', '..', '..', 'server', 'encryption.key')
]
for (const checkPath of checkPaths) {
if (fs.existsSync(checkPath)) {
return checkPath
}
}
return ''
}
const getEncryptionKeyPath = (): string => {
return process.env.SECRETKEY_PATH ? path.join(process.env.SECRETKEY_PATH, 'encryption.key') : getEncryptionKeyFilePath()
}
/**
* Returns the encryption key
* @returns {Promise<string>}
*/
const getEncryptionKey = async (): Promise<string> => {
try {
return await fs.promises.readFile(getEncryptionKeyPath(), 'utf8')
} catch (error) {
throw new Error(error)
}
}
/**
* Decrypt credential data
* @param {string} encryptedData
* @param {string} componentCredentialName
* @param {IComponentCredentials} componentCredentials
* @returns {Promise<ICommonObject>}
*/
const decryptCredentialData = async (encryptedData: string): Promise<ICommonObject> => {
const encryptKey = await getEncryptionKey()
const decryptedData = AES.decrypt(encryptedData, encryptKey)
try {
return JSON.parse(decryptedData.toString(enc.Utf8))
} catch (e) {
console.error(e)
throw new Error('Credentials could not be decrypted.')
}
}
/**
* Get credential data
* @param {string} selectedCredentialId
* @param {ICommonObject} options
* @returns {Promise<ICommonObject>}
*/
export const getCredentialData = async (selectedCredentialId: string, options: ICommonObject): Promise<ICommonObject> => {
const appDataSource = options.appDataSource as DataSource
const databaseEntities = options.databaseEntities as IDatabaseEntity
try {
const credential = await appDataSource.getRepository(databaseEntities['Credential']).findOneBy({
id: selectedCredentialId
})
if (!credential) throw new Error(`Credential ${selectedCredentialId} not found`)
// Decrpyt credentialData
const decryptedCredentialData = await decryptCredentialData(credential.encryptedData)
return decryptedCredentialData
} catch (e) {
throw new Error(e)
}
}
export const getCredentialParam = (paramName: string, credentialData: ICommonObject, nodeData: INodeData): any => {
return (nodeData.inputs as ICommonObject)[paramName] ?? credentialData[paramName]
}
/**
* Custom chain handler class
*/