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
@@ -12,14 +12,10 @@ import type { SourceControlPreferences } from './types/sourceControlPreferences'
|
||||
import {
|
||||
SOURCE_CONTROL_DEFAULT_EMAIL,
|
||||
SOURCE_CONTROL_DEFAULT_NAME,
|
||||
SOURCE_CONTROL_GIT_FOLDER,
|
||||
SOURCE_CONTROL_README,
|
||||
SOURCE_CONTROL_SSH_FOLDER,
|
||||
SOURCE_CONTROL_SSH_KEY_NAME,
|
||||
} from './constants';
|
||||
import { LoggerProxy } from 'n8n-workflow';
|
||||
import { SourceControlGitService } from './sourceControlGit.service.ee';
|
||||
import { UserSettings } from 'n8n-core';
|
||||
import type { PushResult } from 'simple-git';
|
||||
import { SourceControlExportService } from './sourceControlExport.service.ee';
|
||||
import { BadRequestError } from '@/ResponseHelper';
|
||||
@@ -55,10 +51,10 @@ export class SourceControlService {
|
||||
private sourceControlImportService: SourceControlImportService,
|
||||
private tagRepository: TagRepository,
|
||||
) {
|
||||
const userFolder = UserSettings.getUserN8nFolderPath();
|
||||
this.sshFolder = path.join(userFolder, SOURCE_CONTROL_SSH_FOLDER);
|
||||
this.gitFolder = path.join(userFolder, SOURCE_CONTROL_GIT_FOLDER);
|
||||
this.sshKeyName = path.join(this.sshFolder, SOURCE_CONTROL_SSH_KEY_NAME);
|
||||
const { gitFolder, sshFolder, sshKeyName } = sourceControlPreferencesService;
|
||||
this.gitFolder = gitFolder;
|
||||
this.sshFolder = sshFolder;
|
||||
this.sshKeyName = sshKeyName;
|
||||
}
|
||||
|
||||
async init(): Promise<void> {
|
||||
|
||||
@@ -11,7 +11,7 @@ import type { ICredentialDataDecryptedObject } from 'n8n-workflow';
|
||||
import { LoggerProxy } from 'n8n-workflow';
|
||||
import { writeFile as fsWriteFile, rm as fsRm } from 'fs/promises';
|
||||
import { rmSync } from 'fs';
|
||||
import { Credentials, UserSettings } from 'n8n-core';
|
||||
import { Credentials, InstanceSettings } from 'n8n-core';
|
||||
import type { ExportableWorkflow } from './types/exportableWorkflow';
|
||||
import type { ExportableCredential } from './types/exportableCredential';
|
||||
import type { ExportResult } from './types/exportResult';
|
||||
@@ -39,9 +39,9 @@ export class SourceControlExportService {
|
||||
constructor(
|
||||
private readonly variablesService: VariablesService,
|
||||
private readonly tagRepository: TagRepository,
|
||||
instanceSettings: InstanceSettings,
|
||||
) {
|
||||
const userFolder = UserSettings.getUserN8nFolderPath();
|
||||
this.gitFolder = path.join(userFolder, SOURCE_CONTROL_GIT_FOLDER);
|
||||
this.gitFolder = path.join(instanceSettings.n8nFolder, SOURCE_CONTROL_GIT_FOLDER);
|
||||
this.workflowExportFolder = path.join(this.gitFolder, SOURCE_CONTROL_WORKFLOW_EXPORT_FOLDER);
|
||||
this.credentialExportFolder = path.join(
|
||||
this.gitFolder,
|
||||
@@ -248,12 +248,11 @@ export class SourceControlExportService {
|
||||
(remote) => foundCredentialIds.findIndex((local) => local === remote) === -1,
|
||||
);
|
||||
}
|
||||
const encryptionKey = await UserSettings.getEncryptionKey();
|
||||
await Promise.all(
|
||||
credentialsToBeExported.map(async (sharedCredential) => {
|
||||
const { name, type, nodesAccess, data, id } = sharedCredential.credentials;
|
||||
const credentialObject = new Credentials({ id, name }, type, nodesAccess, data);
|
||||
const plainData = credentialObject.getData(encryptionKey);
|
||||
const plainData = credentialObject.getData();
|
||||
const sanitizedData = this.replaceCredentialData(plainData);
|
||||
const fileName = this.getCredentialsPath(sharedCredential.credentials.id);
|
||||
const sanitizedCredential: ExportableCredential = {
|
||||
|
||||
@@ -11,7 +11,7 @@ import * as Db from '@/Db';
|
||||
import glob from 'fast-glob';
|
||||
import { LoggerProxy, jsonParse } from 'n8n-workflow';
|
||||
import { readFile as fsReadFile } from 'fs/promises';
|
||||
import { Credentials, UserSettings } from 'n8n-core';
|
||||
import { Credentials, InstanceSettings } from 'n8n-core';
|
||||
import type { IWorkflowToImport } from '@/Interfaces';
|
||||
import type { ExportableCredential } from './types/exportableCredential';
|
||||
import type { Variables } from '@db/entities/Variables';
|
||||
@@ -41,9 +41,9 @@ export class SourceControlImportService {
|
||||
private readonly variablesService: VariablesService,
|
||||
private readonly activeWorkflowRunner: ActiveWorkflowRunner,
|
||||
private readonly tagRepository: TagRepository,
|
||||
instanceSettings: InstanceSettings,
|
||||
) {
|
||||
const userFolder = UserSettings.getUserN8nFolderPath();
|
||||
this.gitFolder = path.join(userFolder, SOURCE_CONTROL_GIT_FOLDER);
|
||||
this.gitFolder = path.join(instanceSettings.n8nFolder, SOURCE_CONTROL_GIT_FOLDER);
|
||||
this.workflowExportFolder = path.join(this.gitFolder, SOURCE_CONTROL_WORKFLOW_EXPORT_FOLDER);
|
||||
this.credentialExportFolder = path.join(
|
||||
this.gitFolder,
|
||||
@@ -81,69 +81,6 @@ export class SourceControlImportService {
|
||||
return workflowOwnerRole;
|
||||
}
|
||||
|
||||
private async importCredentialsFromFiles(
|
||||
userId: string,
|
||||
): Promise<Array<{ id: string; name: string; type: string }>> {
|
||||
const credentialFiles = await glob('*.json', {
|
||||
cwd: this.credentialExportFolder,
|
||||
absolute: true,
|
||||
});
|
||||
const existingCredentials = await Db.collections.Credentials.find();
|
||||
const ownerCredentialRole = await this.getCredentialOwnerRole();
|
||||
const ownerGlobalRole = await this.getOwnerGlobalRole();
|
||||
const encryptionKey = await UserSettings.getEncryptionKey();
|
||||
let importCredentialsResult: Array<{ id: string; name: string; type: string }> = [];
|
||||
importCredentialsResult = await Promise.all(
|
||||
credentialFiles.map(async (file) => {
|
||||
LoggerProxy.debug(`Importing credentials file ${file}`);
|
||||
const credential = jsonParse<ExportableCredential>(
|
||||
await fsReadFile(file, { encoding: 'utf8' }),
|
||||
);
|
||||
const existingCredential = existingCredentials.find(
|
||||
(e) => e.id === credential.id && e.type === credential.type,
|
||||
);
|
||||
const sharedOwner = await Db.collections.SharedCredentials.findOne({
|
||||
select: ['userId'],
|
||||
where: {
|
||||
credentialsId: credential.id,
|
||||
roleId: In([ownerCredentialRole.id, ownerGlobalRole.id]),
|
||||
},
|
||||
});
|
||||
|
||||
const { name, type, data, id, nodesAccess } = credential;
|
||||
const newCredentialObject = new Credentials({ id, name }, type, []);
|
||||
if (existingCredential?.data) {
|
||||
newCredentialObject.data = existingCredential.data;
|
||||
} else {
|
||||
newCredentialObject.setData(data, encryptionKey);
|
||||
}
|
||||
newCredentialObject.nodesAccess = nodesAccess || existingCredential?.nodesAccess || [];
|
||||
|
||||
LoggerProxy.debug(`Updating credential id ${newCredentialObject.id as string}`);
|
||||
await Db.collections.Credentials.upsert(newCredentialObject, ['id']);
|
||||
|
||||
if (!sharedOwner) {
|
||||
const newSharedCredential = new SharedCredentials();
|
||||
newSharedCredential.credentialsId = newCredentialObject.id as string;
|
||||
newSharedCredential.userId = userId;
|
||||
newSharedCredential.roleId = ownerGlobalRole.id;
|
||||
|
||||
await Db.collections.SharedCredentials.upsert({ ...newSharedCredential }, [
|
||||
'credentialsId',
|
||||
'userId',
|
||||
]);
|
||||
}
|
||||
|
||||
return {
|
||||
id: newCredentialObject.id as string,
|
||||
name: newCredentialObject.name,
|
||||
type: newCredentialObject.type,
|
||||
};
|
||||
}),
|
||||
);
|
||||
return importCredentialsResult.filter((e) => e !== undefined);
|
||||
}
|
||||
|
||||
public async getRemoteVersionIdsFromFiles(): Promise<SourceControlWorkflowVersionId[]> {
|
||||
const remoteWorkflowFiles = await glob('*.json', {
|
||||
cwd: this.workflowExportFolder,
|
||||
@@ -407,7 +344,6 @@ export class SourceControlImportService {
|
||||
roleId: In([ownerCredentialRole.id, ownerGlobalRole.id]),
|
||||
},
|
||||
});
|
||||
const encryptionKey = await UserSettings.getEncryptionKey();
|
||||
let importCredentialsResult: Array<{ id: string; name: string; type: string }> = [];
|
||||
importCredentialsResult = await Promise.all(
|
||||
candidates.map(async (candidate) => {
|
||||
@@ -427,7 +363,7 @@ export class SourceControlImportService {
|
||||
if (existingCredential?.data) {
|
||||
newCredentialObject.data = existingCredential.data;
|
||||
} else {
|
||||
newCredentialObject.setData(data, encryptionKey);
|
||||
newCredentialObject.setData(data);
|
||||
}
|
||||
newCredentialObject.nodesAccess = nodesAccess || existingCredential?.nodesAccess || [];
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
isSourceControlLicensed,
|
||||
sourceControlFoldersExistCheck,
|
||||
} from './sourceControlHelper.ee';
|
||||
import { UserSettings } from 'n8n-core';
|
||||
import { InstanceSettings } from 'n8n-core';
|
||||
import { LoggerProxy, jsonParse } from 'n8n-workflow';
|
||||
import * as Db from '@/Db';
|
||||
import {
|
||||
@@ -26,16 +26,15 @@ import config from '@/config';
|
||||
export class SourceControlPreferencesService {
|
||||
private _sourceControlPreferences: SourceControlPreferences = new SourceControlPreferences();
|
||||
|
||||
private sshKeyName: string;
|
||||
readonly sshKeyName: string;
|
||||
|
||||
private sshFolder: string;
|
||||
readonly sshFolder: string;
|
||||
|
||||
private gitFolder: string;
|
||||
readonly gitFolder: string;
|
||||
|
||||
constructor() {
|
||||
const userFolder = UserSettings.getUserN8nFolderPath();
|
||||
this.sshFolder = path.join(userFolder, SOURCE_CONTROL_SSH_FOLDER);
|
||||
this.gitFolder = path.join(userFolder, SOURCE_CONTROL_GIT_FOLDER);
|
||||
constructor(instanceSettings: InstanceSettings) {
|
||||
this.sshFolder = path.join(instanceSettings.n8nFolder, SOURCE_CONTROL_SSH_FOLDER);
|
||||
this.gitFolder = path.join(instanceSettings.n8nFolder, SOURCE_CONTROL_GIT_FOLDER);
|
||||
this.sshKeyName = path.join(this.sshFolder, SOURCE_CONTROL_SSH_KEY_NAME);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user