2023-01-30 05:42:30 -08:00
|
|
|
import config from '@/config';
|
2022-11-23 07:20:28 -08:00
|
|
|
import type { ICredentialDataDecryptedObject, ICredentialTypes } from 'n8n-workflow';
|
|
|
|
import { deepCopy, LoggerProxy as Logger, jsonParse } from 'n8n-workflow';
|
2022-11-09 06:25:00 -08:00
|
|
|
import type { ICredentialsOverwrite } from '@/Interfaces';
|
2020-01-25 23:48:38 -08:00
|
|
|
|
|
|
|
class CredentialsOverwritesClass {
|
|
|
|
private overwriteData: ICredentialsOverwrite = {};
|
2020-09-13 03:35:13 -07:00
|
|
|
|
2021-08-29 11:58:11 -07:00
|
|
|
private resolvedTypes: string[] = [];
|
2020-01-25 23:48:38 -08:00
|
|
|
|
2023-01-30 05:42:30 -08:00
|
|
|
constructor(private credentialTypes: ICredentialTypes) {
|
|
|
|
const data = config.getEnv('credentials.overwrite.data');
|
2022-11-23 07:20:28 -08:00
|
|
|
const overwriteData = jsonParse<ICredentialsOverwrite>(data, {
|
|
|
|
errorMessage: 'The credentials-overwrite is not valid JSON.',
|
|
|
|
});
|
|
|
|
|
|
|
|
this.setData(overwriteData);
|
2020-01-25 23:48:38 -08:00
|
|
|
}
|
|
|
|
|
2022-11-23 07:20:28 -08:00
|
|
|
setData(overwriteData: ICredentialsOverwrite) {
|
|
|
|
// If data gets reinitialized reset the resolved types cache
|
|
|
|
this.resolvedTypes.length = 0;
|
2020-09-13 03:35:13 -07:00
|
|
|
|
2022-11-23 07:20:28 -08:00
|
|
|
this.overwriteData = overwriteData;
|
2020-09-13 03:35:13 -07:00
|
|
|
|
2022-11-23 07:20:28 -08:00
|
|
|
for (const type in overwriteData) {
|
|
|
|
const overwrites = this.getOverwrites(type);
|
2020-09-13 03:35:13 -07:00
|
|
|
|
|
|
|
if (overwrites && Object.keys(overwrites).length) {
|
|
|
|
this.overwriteData[type] = overwrites;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-25 23:48:38 -08:00
|
|
|
applyOverwrite(type: string, data: ICredentialDataDecryptedObject) {
|
|
|
|
const overwrites = this.get(type);
|
|
|
|
|
|
|
|
if (overwrites === undefined) {
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2022-10-18 04:33:31 -07:00
|
|
|
const returnData = deepCopy(data);
|
2020-09-06 13:16:42 -07:00
|
|
|
// Overwrite only if there is currently no data set
|
|
|
|
for (const key of Object.keys(overwrites)) {
|
2022-10-18 04:33:31 -07:00
|
|
|
// @ts-ignore
|
2020-09-06 13:16:42 -07:00
|
|
|
if ([null, undefined, ''].includes(returnData[key])) {
|
|
|
|
returnData[key] = overwrites[key];
|
|
|
|
}
|
|
|
|
}
|
2020-01-25 23:48:38 -08:00
|
|
|
|
|
|
|
return returnData;
|
|
|
|
}
|
|
|
|
|
2022-11-23 07:20:28 -08:00
|
|
|
private getOverwrites(type: string): ICredentialDataDecryptedObject | undefined {
|
2020-09-13 03:35:13 -07:00
|
|
|
if (this.resolvedTypes.includes(type)) {
|
|
|
|
// Type got already resolved and can so returned directly
|
|
|
|
return this.overwriteData[type];
|
|
|
|
}
|
|
|
|
|
2022-11-23 07:20:28 -08:00
|
|
|
if (!this.credentialTypes.recognizes(type)) {
|
|
|
|
Logger.warn(`Unknown credential type ${type} in Credential overwrites`);
|
|
|
|
return;
|
2020-09-12 12:13:57 -07:00
|
|
|
}
|
|
|
|
|
2022-11-23 07:20:28 -08:00
|
|
|
const credentialTypeData = this.credentialTypes.getByName(type);
|
|
|
|
|
2020-09-12 12:13:57 -07:00
|
|
|
if (credentialTypeData.extends === undefined) {
|
2020-09-13 03:35:13 -07:00
|
|
|
this.resolvedTypes.push(type);
|
2020-09-12 12:13:57 -07:00
|
|
|
return this.overwriteData[type];
|
|
|
|
}
|
|
|
|
|
|
|
|
const overwrites: ICredentialDataDecryptedObject = {};
|
|
|
|
for (const credentialsTypeName of credentialTypeData.extends) {
|
2022-11-23 07:20:28 -08:00
|
|
|
Object.assign(overwrites, this.getOverwrites(credentialsTypeName));
|
2020-09-12 12:13:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this.overwriteData[type] !== undefined) {
|
|
|
|
Object.assign(overwrites, this.overwriteData[type]);
|
|
|
|
}
|
|
|
|
|
2020-09-13 03:35:13 -07:00
|
|
|
this.resolvedTypes.push(type);
|
|
|
|
|
2020-09-12 12:13:57 -07:00
|
|
|
return overwrites;
|
2020-01-25 23:48:38 -08:00
|
|
|
}
|
|
|
|
|
2023-01-04 09:16:48 -08:00
|
|
|
private get(name: string): ICredentialDataDecryptedObject | undefined {
|
|
|
|
const parentTypes = this.credentialTypes.getParentTypes(name);
|
|
|
|
return [name, ...parentTypes]
|
|
|
|
.reverse()
|
|
|
|
.map((type) => this.overwriteData[type])
|
|
|
|
.filter((type) => !!type)
|
|
|
|
.reduce((acc, current) => Object.assign(acc, current), {});
|
2020-09-13 03:35:13 -07:00
|
|
|
}
|
|
|
|
|
2020-01-25 23:48:38 -08:00
|
|
|
getAll(): ICredentialsOverwrite {
|
|
|
|
return this.overwriteData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let credentialsOverwritesInstance: CredentialsOverwritesClass | undefined;
|
|
|
|
|
2021-08-29 11:58:11 -07:00
|
|
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
2022-11-23 07:20:28 -08:00
|
|
|
export function CredentialsOverwrites(
|
|
|
|
credentialTypes?: ICredentialTypes,
|
|
|
|
): CredentialsOverwritesClass {
|
|
|
|
if (!credentialsOverwritesInstance) {
|
|
|
|
if (credentialTypes) {
|
|
|
|
credentialsOverwritesInstance = new CredentialsOverwritesClass(credentialTypes);
|
|
|
|
} else {
|
|
|
|
throw new Error('CredentialsOverwrites not initialized yet');
|
|
|
|
}
|
2020-01-25 23:48:38 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
return credentialsOverwritesInstance;
|
|
|
|
}
|