@tsmx/secure-config-tool
Version:
Command-line tool for @tsmx/secure-config.
141 lines (127 loc) • 7.87 kB
JavaScript
const fs = require('fs');
const cryptUtils = require('../utils/crypt');
const oh = require('@tsmx/object-hmac');
describe('secure-config-tool rotate-key test suite', () => {
var testOutput = [];
const originalConsoleLog = console.log;
const testConsoleLog = (output) => { testOutput.push(output); };
const TEST_KEY_HEX_OLD = '9af7d400be4705147dc724db25bfd2513aa11d6013d7bf7bdb2bfe050593bd0f';
const TEST_KEY_HEX_OLD_WRONG = '9af7d400be4705147dc724db25bfd2513aa11d6013d7bf7bdb2bfe050593bdaa';
const TEST_KEY_HEX_NEW = '9af7d400be4705147dc724db25bfd2513aa11d6013d7bf7bdb2bfe050593b000';
beforeEach(() => {
delete process.env[cryptUtils.CONFIG_ENCRYPTION_KEY];
delete process.env[cryptUtils.CONFIG_ENCRYPTION_KEY_NEW];
jest.resetModules();
console.log = testConsoleLog;
testOutput = [];
});
afterEach(() => {
console.log = originalConsoleLog;
});
it('tests a failed key rotation because of a missing old key', () => {
const mockExit = jest.spyOn(process, 'exit')
.mockImplementation((number) => { throw new Error('process.exit: ' + number); });
const rotateKey = require('../functions/rotate-key');
expect(() => {
rotateKey('./test/testfiles/config-test.json');
}).toThrow();
expect(mockExit).toHaveBeenCalledWith(-1);
expect(testOutput.length).toEqual(1);
expect(testOutput[0]).toEqual(`Environment variable ${cryptUtils.CONFIG_ENCRYPTION_KEY} not set.`);
mockExit.mockRestore();
});
it('tests a failed key rotation because of a missing new key', () => {
process.env[cryptUtils.CONFIG_ENCRYPTION_KEY] = TEST_KEY_HEX_OLD;
const mockExit = jest.spyOn(process, 'exit')
.mockImplementation((number) => { throw new Error('process.exit: ' + number); });
const rotateKey = require('../functions/rotate-key');
expect(() => {
rotateKey('./test/testfiles/config-test.json');
}).toThrow();
expect(mockExit).toHaveBeenCalledWith(-1);
expect(testOutput.length).toEqual(1);
expect(testOutput[0]).toEqual(`Environment variable ${cryptUtils.CONFIG_ENCRYPTION_KEY_NEW} not set.`);
mockExit.mockRestore();
});
it('tests a successful key rotation', () => {
process.env[cryptUtils.CONFIG_ENCRYPTION_KEY] = TEST_KEY_HEX_OLD;
process.env[cryptUtils.CONFIG_ENCRYPTION_KEY_NEW] = TEST_KEY_HEX_NEW;
const rotateKey = require('../functions/rotate-key');
rotateKey('./test/testfiles/config-test.json');
expect(testOutput.length).toBe(1);
let updatedJson = JSON.parse(testOutput[0]);
const originalConfig = require('./testfiles/config-test-plain.json');
expect(updatedJson.database.host).toStrictEqual(originalConfig.database.host);
expect(updatedJson.database.username).toBeDefined();
expect(cryptUtils.decrypt(updatedJson.database.username, TEST_KEY_HEX_NEW)).toStrictEqual(originalConfig.database.username);
expect(updatedJson.database.password).toBeDefined();
expect(cryptUtils.decrypt(updatedJson.database.password, TEST_KEY_HEX_NEW)).toStrictEqual(originalConfig.database.password);
expect(updatedJson['__hmac']).toBeDefined();
expect(updatedJson['__hmac']).toStrictEqual(oh.calculateHmac(originalConfig, TEST_KEY_HEX_NEW));
});
it('tests a successful key rotation without HMAC', () => {
process.env[cryptUtils.CONFIG_ENCRYPTION_KEY] = TEST_KEY_HEX_OLD;
process.env[cryptUtils.CONFIG_ENCRYPTION_KEY_NEW] = TEST_KEY_HEX_NEW;
const rotateKey = require('../functions/rotate-key');
rotateKey('./test/testfiles/config-test-without-hmac.json');
expect(testOutput.length).toBe(1);
let updatedJson = JSON.parse(testOutput[0]);
const originalConfig = require('./testfiles/config-test-plain.json');
expect(updatedJson.database.host).toStrictEqual(originalConfig.database.host);
expect(updatedJson.database.username).toBeDefined();
expect(cryptUtils.decrypt(updatedJson.database.username, TEST_KEY_HEX_NEW)).toStrictEqual(originalConfig.database.username);
expect(updatedJson.database.password).toBeDefined();
expect(cryptUtils.decrypt(updatedJson.database.password, TEST_KEY_HEX_NEW)).toStrictEqual(originalConfig.database.password);
expect(updatedJson['__hmac']).toBeUndefined();
});
it('tests a successful key rotation with custom HMAC property name', () => {
process.env[cryptUtils.CONFIG_ENCRYPTION_KEY] = TEST_KEY_HEX_OLD;
process.env[cryptUtils.CONFIG_ENCRYPTION_KEY_NEW] = TEST_KEY_HEX_NEW;
const customHmacProp = '_signature';
const rotateKey = require('../functions/rotate-key');
rotateKey('./test/testfiles/config-test-hmacprop.json', { hmacProp: customHmacProp });
expect(testOutput.length).toBe(1);
let updatedJson = JSON.parse(testOutput[0]);
const originalConfig = require('./testfiles/config-test-plain.json');
expect(updatedJson.database.host).toStrictEqual(originalConfig.database.host);
expect(updatedJson.database.username).toBeDefined();
expect(cryptUtils.decrypt(updatedJson.database.username, TEST_KEY_HEX_NEW)).toStrictEqual(originalConfig.database.username);
expect(updatedJson.database.password).toBeDefined();
expect(cryptUtils.decrypt(updatedJson.database.password, TEST_KEY_HEX_NEW)).toStrictEqual(originalConfig.database.password);
expect(updatedJson[customHmacProp]).toBeDefined();
expect(updatedJson[customHmacProp]).toStrictEqual(oh.calculateHmac(originalConfig, TEST_KEY_HEX_NEW));
});
it('tests a successful key rotation with file overwriting', () => {
process.env[cryptUtils.CONFIG_ENCRYPTION_KEY] = TEST_KEY_HEX_OLD;
process.env[cryptUtils.CONFIG_ENCRYPTION_KEY_NEW] = TEST_KEY_HEX_NEW;
let resultFileName = null;
let updatedJson = null;
const mockFileWrite = jest.spyOn(fs, 'writeFileSync')
.mockImplementation((file, data) => { resultFileName = file; updatedJson = JSON.parse(data); });
const rotateKey = require('../functions/rotate-key');
rotateKey('./test/testfiles/config-test.json', { overwrite: true });
expect(mockFileWrite).toHaveBeenCalled();
mockFileWrite.mockRestore();
const originalConfig = require('./testfiles/config-test-plain.json');
expect(resultFileName).toStrictEqual('./test/testfiles/config-test.json');
expect(updatedJson.database.host).toStrictEqual(originalConfig.database.host);
expect(updatedJson.database.username).toBeDefined();
expect(cryptUtils.decrypt(updatedJson.database.username, TEST_KEY_HEX_NEW)).toStrictEqual(originalConfig.database.username);
expect(updatedJson.database.password).toBeDefined();
expect(cryptUtils.decrypt(updatedJson.database.password, TEST_KEY_HEX_NEW)).toStrictEqual(originalConfig.database.password);
expect(updatedJson['__hmac']).toBeDefined();
expect(updatedJson['__hmac']).toStrictEqual(oh.calculateHmac(originalConfig, TEST_KEY_HEX_NEW));
});
it('tests a failed key rotation because of wrong old key', () => {
process.env[cryptUtils.CONFIG_ENCRYPTION_KEY] = TEST_KEY_HEX_OLD_WRONG;
process.env[cryptUtils.CONFIG_ENCRYPTION_KEY_NEW] = TEST_KEY_HEX_NEW;
const mockExit = jest.spyOn(process, 'exit')
.mockImplementation((number) => { throw new Error('process.exit: ' + number); });
const rotateKey = require('../functions/rotate-key');
expect(() => {
rotateKey('./test/testfiles/config-test.json');
}).toThrow();
expect(mockExit).toHaveBeenCalledWith(-1);
mockExit.mockRestore();
});
});