refactor(core): Abstract away InstanceSettings and encryptionKey into injectable services (no-changelog) (#7471)
This change ensures that things like `encryptionKey` and `instanceId` are always available directly where they are needed, instead of passing them around throughout the code.
This commit is contained in:
committed by
GitHub
parent
519680c2cf
commit
b6de910cbe
@@ -61,11 +61,7 @@ EECredentialsController.get(
|
||||
|
||||
const { data: _, ...rest } = credential;
|
||||
|
||||
const key = await EECredentials.getEncryptionKey();
|
||||
const decryptedData = EECredentials.redact(
|
||||
await EECredentials.decrypt(key, credential),
|
||||
credential,
|
||||
);
|
||||
const decryptedData = EECredentials.redact(EECredentials.decrypt(credential), credential);
|
||||
|
||||
return { data: decryptedData, ...rest };
|
||||
}),
|
||||
@@ -81,8 +77,6 @@ EECredentialsController.post(
|
||||
ResponseHelper.send(async (req: CredentialRequest.Test): Promise<INodeCredentialTestResult> => {
|
||||
const { credentials } = req.body;
|
||||
|
||||
const encryptionKey = await EECredentials.getEncryptionKey();
|
||||
|
||||
const credentialId = credentials.id;
|
||||
const { ownsCredential } = await EECredentials.isOwned(req.user, credentialId);
|
||||
|
||||
@@ -92,17 +86,17 @@ EECredentialsController.post(
|
||||
throw new ResponseHelper.UnauthorizedError('Forbidden');
|
||||
}
|
||||
|
||||
const decryptedData = await EECredentials.decrypt(encryptionKey, sharing.credentials);
|
||||
const decryptedData = EECredentials.decrypt(sharing.credentials);
|
||||
Object.assign(credentials, { data: decryptedData });
|
||||
}
|
||||
|
||||
const mergedCredentials = deepCopy(credentials);
|
||||
if (mergedCredentials.data && sharing?.credentials) {
|
||||
const decryptedData = await EECredentials.decrypt(encryptionKey, sharing.credentials);
|
||||
const decryptedData = EECredentials.decrypt(sharing.credentials);
|
||||
mergedCredentials.data = EECredentials.unredact(mergedCredentials.data, decryptedData);
|
||||
}
|
||||
|
||||
return EECredentials.test(req.user, encryptionKey, mergedCredentials);
|
||||
return EECredentials.test(req.user, mergedCredentials);
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
@@ -86,9 +86,8 @@ credentialsController.get(
|
||||
return { ...rest };
|
||||
}
|
||||
|
||||
const key = await CredentialsService.getEncryptionKey();
|
||||
const decryptedData = CredentialsService.redact(
|
||||
await CredentialsService.decrypt(key, credential),
|
||||
CredentialsService.decrypt(credential),
|
||||
credential,
|
||||
);
|
||||
|
||||
@@ -106,16 +105,15 @@ credentialsController.post(
|
||||
ResponseHelper.send(async (req: CredentialRequest.Test): Promise<INodeCredentialTestResult> => {
|
||||
const { credentials } = req.body;
|
||||
|
||||
const encryptionKey = await CredentialsService.getEncryptionKey();
|
||||
const sharing = await CredentialsService.getSharing(req.user, credentials.id);
|
||||
|
||||
const mergedCredentials = deepCopy(credentials);
|
||||
if (mergedCredentials.data && sharing?.credentials) {
|
||||
const decryptedData = await CredentialsService.decrypt(encryptionKey, sharing.credentials);
|
||||
const decryptedData = CredentialsService.decrypt(sharing.credentials);
|
||||
mergedCredentials.data = CredentialsService.unredact(mergedCredentials.data, decryptedData);
|
||||
}
|
||||
|
||||
return CredentialsService.test(req.user, encryptionKey, mergedCredentials);
|
||||
return CredentialsService.test(req.user, mergedCredentials);
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -127,8 +125,7 @@ credentialsController.post(
|
||||
ResponseHelper.send(async (req: CredentialRequest.Create) => {
|
||||
const newCredential = await CredentialsService.prepareCreateData(req.body);
|
||||
|
||||
const key = await CredentialsService.getEncryptionKey();
|
||||
const encryptedData = CredentialsService.createEncryptedData(key, null, newCredential);
|
||||
const encryptedData = CredentialsService.createEncryptedData(null, newCredential);
|
||||
const credential = await CredentialsService.save(newCredential, encryptedData, req.user);
|
||||
|
||||
void Container.get(InternalHooks).onUserCreatedCredentials({
|
||||
@@ -165,14 +162,12 @@ credentialsController.patch(
|
||||
|
||||
const { credentials: credential } = sharing;
|
||||
|
||||
const key = await CredentialsService.getEncryptionKey();
|
||||
const decryptedData = await CredentialsService.decrypt(key, credential);
|
||||
const decryptedData = CredentialsService.decrypt(credential);
|
||||
const preparedCredentialData = await CredentialsService.prepareUpdateData(
|
||||
req.body,
|
||||
decryptedData,
|
||||
);
|
||||
const newCredentialData = CredentialsService.createEncryptedData(
|
||||
key,
|
||||
credentialId,
|
||||
preparedCredentialData,
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Credentials, UserSettings } from 'n8n-core';
|
||||
import { Credentials } from 'n8n-core';
|
||||
import type {
|
||||
ICredentialDataDecryptedObject,
|
||||
ICredentialsDecrypted,
|
||||
@@ -12,10 +12,9 @@ import type { FindManyOptions, FindOptionsWhere } from 'typeorm';
|
||||
import { In, Like } from 'typeorm';
|
||||
|
||||
import * as Db from '@/Db';
|
||||
import * as ResponseHelper from '@/ResponseHelper';
|
||||
import type { ICredentialsDb } from '@/Interfaces';
|
||||
import { CredentialsHelper, createCredentialsFromCredentialsEntity } from '@/CredentialsHelper';
|
||||
import { CREDENTIAL_BLANKING_VALUE, RESPONSE_ERROR_MESSAGES } from '@/constants';
|
||||
import { CREDENTIAL_BLANKING_VALUE } from '@/constants';
|
||||
import { CredentialsEntity } from '@db/entities/CredentialsEntity';
|
||||
import { SharedCredentials } from '@db/entities/SharedCredentials';
|
||||
import { validateEntity } from '@/GenericHelpers';
|
||||
@@ -205,18 +204,14 @@ export class CredentialsService {
|
||||
return updateData;
|
||||
}
|
||||
|
||||
static createEncryptedData(
|
||||
encryptionKey: string,
|
||||
credentialId: string | null,
|
||||
data: CredentialsEntity,
|
||||
): ICredentialsDb {
|
||||
static createEncryptedData(credentialId: string | null, data: CredentialsEntity): ICredentialsDb {
|
||||
const credentials = new Credentials(
|
||||
{ id: credentialId, name: data.name },
|
||||
data.type,
|
||||
data.nodesAccess,
|
||||
);
|
||||
|
||||
credentials.setData(data.data as unknown as ICredentialDataDecryptedObject, encryptionKey);
|
||||
credentials.setData(data.data as unknown as ICredentialDataDecryptedObject);
|
||||
|
||||
const newCredentialData = credentials.getDataToSave() as ICredentialsDb;
|
||||
|
||||
@@ -226,22 +221,9 @@ export class CredentialsService {
|
||||
return newCredentialData;
|
||||
}
|
||||
|
||||
static async getEncryptionKey(): Promise<string> {
|
||||
try {
|
||||
return await UserSettings.getEncryptionKey();
|
||||
} catch (error) {
|
||||
throw new ResponseHelper.InternalServerError(RESPONSE_ERROR_MESSAGES.NO_ENCRYPTION_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
static async decrypt(
|
||||
encryptionKey: string,
|
||||
credential: CredentialsEntity,
|
||||
): Promise<ICredentialDataDecryptedObject> {
|
||||
static decrypt(credential: CredentialsEntity): ICredentialDataDecryptedObject {
|
||||
const coreCredential = createCredentialsFromCredentialsEntity(credential);
|
||||
const data = coreCredential.getData(encryptionKey);
|
||||
|
||||
return data;
|
||||
return coreCredential.getData();
|
||||
}
|
||||
|
||||
static async update(
|
||||
@@ -303,11 +285,9 @@ export class CredentialsService {
|
||||
|
||||
static async test(
|
||||
user: User,
|
||||
encryptionKey: string,
|
||||
credentials: ICredentialsDecrypted,
|
||||
): Promise<INodeCredentialTestResult> {
|
||||
const helper = new CredentialsHelper(encryptionKey);
|
||||
|
||||
const helper = Container.get(CredentialsHelper);
|
||||
return helper.testCredentials(user, credentials.type, credentials);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,8 @@ import omit from 'lodash/omit';
|
||||
import set from 'lodash/set';
|
||||
import split from 'lodash/split';
|
||||
import unset from 'lodash/unset';
|
||||
import { Credentials, UserSettings } from 'n8n-core';
|
||||
import type {
|
||||
WorkflowExecuteMode,
|
||||
INodeCredentialsDetails,
|
||||
ICredentialsEncrypted,
|
||||
} from 'n8n-workflow';
|
||||
import { Credentials } from 'n8n-core';
|
||||
import type { WorkflowExecuteMode, INodeCredentialsDetails } from 'n8n-workflow';
|
||||
import { LoggerProxy, jsonStringify } from 'n8n-workflow';
|
||||
import { resolve as pathResolve } from 'path';
|
||||
|
||||
@@ -76,20 +72,13 @@ oauth2CredentialController.get(
|
||||
throw new ResponseHelper.NotFoundError(RESPONSE_ERROR_MESSAGES.NO_CREDENTIAL);
|
||||
}
|
||||
|
||||
let encryptionKey: string;
|
||||
try {
|
||||
encryptionKey = await UserSettings.getEncryptionKey();
|
||||
} catch (error) {
|
||||
throw new ResponseHelper.InternalServerError((error as Error).message);
|
||||
}
|
||||
|
||||
const additionalData = await WorkflowExecuteAdditionalData.getBase(req.user.id);
|
||||
|
||||
const credentialType = (credential as unknown as ICredentialsEncrypted).type;
|
||||
const credentialType = credential.type;
|
||||
|
||||
const mode: WorkflowExecuteMode = 'internal';
|
||||
const timezone = config.getEnv('generic.timezone');
|
||||
const credentialsHelper = new CredentialsHelper(encryptionKey);
|
||||
const credentialsHelper = Container.get(CredentialsHelper);
|
||||
const decryptedDataOriginal = await credentialsHelper.getDecrypted(
|
||||
additionalData,
|
||||
credential as INodeCredentialsDetails,
|
||||
@@ -152,7 +141,7 @@ oauth2CredentialController.get(
|
||||
const credentials = new Credentials(
|
||||
credential as INodeCredentialsDetails,
|
||||
credentialType,
|
||||
(credential as unknown as ICredentialsEncrypted).nodesAccess,
|
||||
credential.nodesAccess,
|
||||
);
|
||||
decryptedDataOriginal.csrfSecret = csrfSecret;
|
||||
|
||||
@@ -166,7 +155,7 @@ oauth2CredentialController.get(
|
||||
decryptedDataOriginal.codeVerifier = code_verifier;
|
||||
}
|
||||
|
||||
credentials.setData(decryptedDataOriginal, encryptionKey);
|
||||
credentials.setData(decryptedDataOriginal);
|
||||
const newCredentialsData = credentials.getDataToSave() as unknown as ICredentialsDb;
|
||||
|
||||
// Add special database related data
|
||||
@@ -228,16 +217,15 @@ oauth2CredentialController.get(
|
||||
return renderCallbackError(res, errorMessage);
|
||||
}
|
||||
|
||||
const encryptionKey = await UserSettings.getEncryptionKey();
|
||||
const additionalData = await WorkflowExecuteAdditionalData.getBase(state.cid);
|
||||
|
||||
const mode: WorkflowExecuteMode = 'internal';
|
||||
const timezone = config.getEnv('generic.timezone');
|
||||
const credentialsHelper = new CredentialsHelper(encryptionKey);
|
||||
const credentialsHelper = Container.get(CredentialsHelper);
|
||||
const decryptedDataOriginal = await credentialsHelper.getDecrypted(
|
||||
additionalData,
|
||||
credential as INodeCredentialsDetails,
|
||||
(credential as unknown as ICredentialsEncrypted).type,
|
||||
credential.type,
|
||||
mode,
|
||||
timezone,
|
||||
true,
|
||||
@@ -245,7 +233,7 @@ oauth2CredentialController.get(
|
||||
const oauthCredentials = credentialsHelper.applyDefaultsAndOverwrites(
|
||||
additionalData,
|
||||
decryptedDataOriginal,
|
||||
(credential as unknown as ICredentialsEncrypted).type,
|
||||
credential.type,
|
||||
mode,
|
||||
timezone,
|
||||
);
|
||||
@@ -330,10 +318,10 @@ oauth2CredentialController.get(
|
||||
|
||||
const credentials = new Credentials(
|
||||
credential as INodeCredentialsDetails,
|
||||
(credential as unknown as ICredentialsEncrypted).type,
|
||||
(credential as unknown as ICredentialsEncrypted).nodesAccess,
|
||||
credential.type,
|
||||
credential.nodesAccess,
|
||||
);
|
||||
credentials.setData(decryptedDataOriginal, encryptionKey);
|
||||
credentials.setData(decryptedDataOriginal);
|
||||
const newCredentialsData = credentials.getDataToSave() as unknown as ICredentialsDb;
|
||||
// Add special database related data
|
||||
newCredentialsData.updatedAt = new Date();
|
||||
|
||||
Reference in New Issue
Block a user