2019-06-23 03:35:23 -07:00
|
|
|
import {
|
|
|
|
CredentialInformation,
|
2020-01-25 23:48:38 -08:00
|
|
|
ICredentialDataDecryptedObject,
|
|
|
|
ICredentials,
|
2019-06-23 03:35:23 -07:00
|
|
|
ICredentialsEncrypted,
|
|
|
|
} from 'n8n-workflow';
|
|
|
|
|
2020-10-22 06:46:03 -07:00
|
|
|
import { AES, enc } from 'crypto-js';
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2020-01-25 23:48:38 -08:00
|
|
|
export class Credentials extends ICredentials {
|
2019-06-23 03:35:23 -07:00
|
|
|
/**
|
|
|
|
* Returns if the given nodeType has access to data
|
|
|
|
*/
|
|
|
|
hasNodeAccess(nodeType: string): boolean {
|
2021-08-29 11:58:11 -07:00
|
|
|
// eslint-disable-next-line no-restricted-syntax
|
2019-06-23 03:35:23 -07:00
|
|
|
for (const accessData of this.nodesAccess) {
|
|
|
|
if (accessData.nodeType === nodeType) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets new credential object
|
|
|
|
*/
|
|
|
|
setData(data: ICredentialDataDecryptedObject, encryptionKey: string): void {
|
|
|
|
this.data = AES.encrypt(JSON.stringify(data), encryptionKey).toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets new credentials for given key
|
|
|
|
*/
|
|
|
|
setDataKey(key: string, data: CredentialInformation, encryptionKey: string): void {
|
|
|
|
let fullData;
|
|
|
|
try {
|
|
|
|
fullData = this.getData(encryptionKey);
|
|
|
|
} catch (e) {
|
|
|
|
fullData = {};
|
|
|
|
}
|
|
|
|
|
|
|
|
fullData[key] = data;
|
|
|
|
|
|
|
|
return this.setData(fullData, encryptionKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the decrypted credential object
|
|
|
|
*/
|
|
|
|
getData(encryptionKey: string, nodeType?: string): ICredentialDataDecryptedObject {
|
|
|
|
if (nodeType && !this.hasNodeAccess(nodeType)) {
|
2021-08-29 11:58:11 -07:00
|
|
|
throw new Error(
|
|
|
|
`The node of type "${nodeType}" does not have access to credentials "${this.name}" of type "${this.type}".`,
|
|
|
|
);
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this.data === undefined) {
|
|
|
|
throw new Error('No data is set so nothing can be returned.');
|
|
|
|
}
|
|
|
|
|
|
|
|
const decryptedData = AES.decrypt(this.data, encryptionKey);
|
|
|
|
|
|
|
|
try {
|
2021-08-29 11:58:11 -07:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
2019-06-23 03:35:23 -07:00
|
|
|
return JSON.parse(decryptedData.toString(enc.Utf8));
|
|
|
|
} catch (e) {
|
2021-08-29 11:58:11 -07:00
|
|
|
throw new Error(
|
|
|
|
'Credentials could not be decrypted. The likely reason is that a different "encryptionKey" was used to encrypt the data.',
|
|
|
|
);
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the decrypted credentials for given key
|
|
|
|
*/
|
|
|
|
getDataKey(key: string, encryptionKey: string, nodeType?: string): CredentialInformation {
|
|
|
|
const fullData = this.getData(encryptionKey, nodeType);
|
|
|
|
|
|
|
|
if (fullData === null) {
|
2021-08-27 08:25:54 -07:00
|
|
|
throw new Error(`No data was set.`);
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
|
2021-08-29 11:58:11 -07:00
|
|
|
// eslint-disable-next-line no-prototype-builtins
|
2019-06-23 03:35:23 -07:00
|
|
|
if (!fullData.hasOwnProperty(key)) {
|
|
|
|
throw new Error(`No data for key "${key}" exists.`);
|
|
|
|
}
|
|
|
|
|
|
|
|
return fullData[key];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the encrypted credentials to be saved
|
|
|
|
*/
|
|
|
|
getDataToSave(): ICredentialsEncrypted {
|
|
|
|
if (this.data === undefined) {
|
2021-08-27 08:25:54 -07:00
|
|
|
throw new Error(`No credentials were set to save.`);
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
name: this.name,
|
|
|
|
type: this.type,
|
|
|
|
data: this.data,
|
|
|
|
nodesAccess: this.nodesAccess,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|