fix(core): Always derive instanceId from the encryption key (no-changlog) (#7501)

This was the expected behavior, until I changed it in
https://github.com/n8n-io/n8n/pull/7471
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™ 2023-10-24 09:55:57 +02:00 committed by GitHub
parent baecb93bef
commit a9fdd018f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 79 additions and 15 deletions

View file

@ -6,7 +6,6 @@ import { jsonParse } from 'n8n-workflow';
interface ReadOnlySettings {
encryptionKey: string;
instanceId: string;
}
interface WritableSettings {
@ -32,14 +31,12 @@ export class InstanceSettings {
private settings = this.loadOrCreate();
readonly instanceId = this.generateInstanceId();
get encryptionKey() {
return this.settings.encryptionKey;
}
get instanceId() {
return this.settings.instanceId;
}
get tunnelSubdomain() {
return this.settings.tunnelSubdomain;
}
@ -58,25 +55,31 @@ export class InstanceSettings {
}
private loadOrCreate(): Settings {
let settings: Settings;
const { settingsFile } = this;
if (existsSync(settingsFile)) {
const content = readFileSync(settingsFile, 'utf8');
return jsonParse(content, {
settings = jsonParse(content, {
errorMessage: `Error parsing n8n-config file "${settingsFile}". It does not seem to be valid JSON.`,
});
} else {
// If file doesn't exist, create new settings
const encryptionKey = process.env.N8N_ENCRYPTION_KEY ?? randomBytes(24).toString('base64');
settings = { encryptionKey };
mkdirSync(path.dirname(settingsFile));
this.save(settings);
// console.info(`UserSettings were generated and saved to: ${settingsFile}`);
}
// If file doesn't exist, create new settings
const encryptionKey = process.env.N8N_ENCRYPTION_KEY ?? randomBytes(24).toString('base64');
const instanceId = createHash('sha256')
const { encryptionKey, tunnelSubdomain } = settings;
return { encryptionKey, tunnelSubdomain };
}
private generateInstanceId() {
const { encryptionKey } = this;
return createHash('sha256')
.update(encryptionKey.slice(Math.round(encryptionKey.length / 2)))
.digest('hex');
const settings = { encryptionKey, instanceId };
mkdirSync(path.dirname(settingsFile));
this.save(settings);
console.log(`UserSettings were generated and saved to: ${settingsFile}`);
return settings;
}
private save(settings: Settings) {

View file

@ -0,0 +1,61 @@
import fs from 'fs';
import { InstanceSettings } from '@/InstanceSettings';
describe('InstanceSettings', () => {
process.env.N8N_USER_FOLDER = '/test';
describe('If the settings file exists', () => {
beforeEach(() => {
jest.spyOn(fs, 'existsSync').mockReturnValue(true);
});
it('should load settings from the file', () => {
jest.spyOn(fs, 'readFileSync').mockReturnValue(JSON.stringify({ encryptionKey: 'test_key' }));
const settings = new InstanceSettings();
expect(settings.encryptionKey).toEqual('test_key');
expect(settings.instanceId).toEqual(
'6ce26c63596f0cc4323563c529acfca0cccb0e57f6533d79a60a42c9ff862ae7',
);
});
it('should throw error if settings file is not valid JSON', () => {
jest.spyOn(fs, 'readFileSync').mockReturnValue('{"encryptionKey":"test_key"');
expect(() => new InstanceSettings()).toThrowError();
});
});
describe('If the settings file does not exist', () => {
it('should create a new settings file', () => {
jest.spyOn(fs, 'existsSync').mockReturnValue(false);
const mkdirSpy = jest.spyOn(fs, 'mkdirSync').mockReturnValue('');
const writeFileSpy = jest.spyOn(fs, 'writeFileSync').mockReturnValue();
const settings = new InstanceSettings();
expect(settings.encryptionKey).not.toEqual('test_key');
expect(mkdirSpy).toHaveBeenCalledWith('/test/.n8n');
expect(writeFileSpy).toHaveBeenCalledWith(
'/test/.n8n/config',
expect.stringContaining('"encryptionKey":'),
'utf-8',
);
});
it('should pick up the encryption key from env var N8N_ENCRYPTION_KEY', () => {
process.env.N8N_ENCRYPTION_KEY = 'env_key';
jest.spyOn(fs, 'existsSync').mockReturnValue(false);
const mkdirSpy = jest.spyOn(fs, 'mkdirSync').mockReturnValue('');
const writeFileSpy = jest.spyOn(fs, 'writeFileSync').mockReturnValue();
const settings = new InstanceSettings();
expect(settings.encryptionKey).toEqual('env_key');
expect(settings.instanceId).toEqual(
'2c70e12b7a0646f92279f427c7b38e7334d8e5389cff167a1dc30e73f826b683',
);
expect(settings.encryptionKey).not.toEqual('test_key');
expect(mkdirSpy).toHaveBeenCalledWith('/test/.n8n');
expect(writeFileSpy).toHaveBeenCalledWith(
'/test/.n8n/config',
expect.stringContaining('"encryptionKey":'),
'utf-8',
);
});
});
});