Skip to content

Commit

Permalink
Merge pull request #7 from kuzzleio/1.0.2-proposal
Browse files Browse the repository at this point in the history
Release 1.0.2
  • Loading branch information
rolljee authored Jan 30, 2020
2 parents b9c447e + 19b50ad commit 74bbe4e
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 5 deletions.
73 changes: 68 additions & 5 deletions lib/vault.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,16 @@ class Vault {
* @param {string|null} secretsFile - file containing the encrypted secrets
*/
encrypt (outputFile = null, replaceFileIfExist = false) {
if (!outputFile && !this._encryptedSecretsFile) {
const file = outputFile || this._encryptedSecretsFile;

if (!file) {
const error = new Error('No outputFile or encryptedSecretsFile specified.');

error.name = 'PreconditionError';
throw error;
}

const fileExists = fs.existsSync(this._encryptedSecretsFile);
const fileExists = fs.existsSync(file);
if (fileExists && !replaceFileIfExist) {
const error = new Error('Output file already exists.');

Expand All @@ -81,7 +83,68 @@ class Vault {

const secrets = JSON.parse(fs.readFileSync(this._secretsFile, 'utf-8'));
const encryptedSecrets = this._encryptObject(secrets);
fs.writeFileSync(outputFile || this._encryptedSecretsFile, JSON.stringify(encryptedSecrets, null, 2));
fs.writeFileSync(file, JSON.stringify(encryptedSecrets, null, 2));
}

/**
* Adds a new key inside an already existing encrypted secrets file.
* Create the file if it didn't exists.
*
* @param {String} path - key path (lodash style)
* @param {String} value - key value
* @param {String} outputFile - encrypted secrets file
*/
encryptKey (path, value, outputFile = null) {
const file = outputFile || this._encryptedSecretsFile;

if (!file) {
const error = new Error('No outputFile or encryptedSecretsFile specified.');

error.name = 'PreconditionError';
throw error;
}

let content = {};

if (fs.existsSync(file)) {
content = JSON.parse(fs.readFileSync(file, 'utf-8'));
}

_.set(content, path, this._encryptData(value));

fs.writeFileSync(file, JSON.stringify(content, null, 2));
}

/**
* Print the content of a key in an encrypted secrets file
*
* @param {String} path - key path (lodash style)
* @param {String} inputFile - file containing the encrypted secrets
*
* @returns {String} decrypted value
*/
decryptKey (path, inputFile = null) {
const file = inputFile || this._encryptedSecretsFile;

if (!file) {
const error = new Error('No inputFile or encryptedSecretsFile specified.');

error.name = 'PreconditionError';
throw error;
}

if (!fs.existsSync(file)) {
const error = new Error(`File ${file} does not exists.`);

error.name = 'PreconditionError';
throw error;
}

const content = JSON.parse(fs.readFileSync(file, 'utf-8'));

const encryptedValue = _.get(content, path);

return this._decryptData(encryptedValue);
}

/**
Expand All @@ -93,7 +156,7 @@ class Vault {
_decryptObject (encryptedSecrets) {
if (!this._vaultKey) {
const error = new Error('Vault key not found.');

error.name = 'PreconditionError';
throw error;
}
Expand All @@ -120,7 +183,7 @@ class Vault {
_encryptObject (secrets) {
if (!this._vaultKey) {
const error = new Error('Vault key not found.');

error.name = 'PreconditionError';
throw error;
}
Expand Down
72 changes: 72 additions & 0 deletions test/vault.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ const
sinon = require('sinon'),
mockRequire = require('mock-require');

require('should-sinon');

describe('Test: vault core component', () => {
let
fsMock,
Expand Down Expand Up @@ -173,4 +175,74 @@ describe('Test: vault core component', () => {
sinon.assert.calledOnce(fsMock.writeFileSync);
});
});

describe('#encryptKey', () => {
it('add an encrypted key in existing file', () => {
fsMock.existsSync.returns(true);
fsMock.readFileSync.returns('{ "s4": "hcmc" }');

vault.encryptKey('aws.s3', 'thao dien', 'file.json');

should(fsMock.writeFileSync).be.calledOnce();
const
[file, rawJson] = fsMock.writeFileSync.getCall(0).args,
json = JSON.parse(rawJson);

should(file).be.eql('file.json');
should(json.aws.s3).not.be.undefined();
});

it('create the file if not exists', () => {
fsMock.existsSync.returns(false);

vault.encryptKey('aws.s3', 'thao dien', 'file.json');

should(fsMock.writeFileSync).be.calledOnce();
const
[file, rawJson] = fsMock.writeFileSync.getCall(0).args,
json = JSON.parse(rawJson);

should(file).be.eql('file.json');
should(json.aws.s3).not.be.undefined();
});

it('throw if file are passed in argument or in constructor', () => {
fsMock.existsSync.returns(false);
vault = new Vault('the spoon does not exists');

should(() => {
vault.encryptKey('aws.s3', 'thao dien');
}).throw();
});

});

describe('#decryptKey', () => {
it('decrypt a key in file', () => {
fsMock.readFileSync.returns('{ "aws": { "s3": "thao dien" } }');
vault._decryptData = sinon.stub().returns('decrypted');

const result = vault.decryptKey('aws.s3', 'file.json');

should(result).be.eql('decrypted');
should(vault._decryptData).be.calledWith('thao dien');
});

it('throw if file are passed in argument or in constructor', () => {
fsMock.existsSync.returns(false);
vault = new Vault('the spoon does not exists');

should(() => {
vault.decryptKey('aws.s3');
}).throw();
});

it('throw if file does not exists', () => {
fsMock.existsSync.returns(false);

should(() => {
vault.decryptKey('aws.s3', 'file.json');
}).throw();
});
});
});

0 comments on commit 74bbe4e

Please sign in to comment.