@tsmx/secure-config-tool
Advanced tools
Comparing version 1.1.2 to 1.2.0
const crypt = require('../utils/crypt'); | ||
module.exports = function (options) { | ||
console.log(crypt.genkey(options && options.base64)); | ||
module.exports = function () { | ||
console.log(crypt.genkey()); | ||
}; |
{ | ||
"name": "@tsmx/secure-config-tool", | ||
"version": "1.1.2", | ||
"version": "1.2.0", | ||
"description": "Tool for generating encrypted secure-config entries.", | ||
@@ -25,2 +25,3 @@ "main": "secure-config-tool.js", | ||
"dependencies": { | ||
"@tsmx/json-traverse": "^1.0.2", | ||
"@tsmx/string-crypto": "^1.0.2", | ||
@@ -27,0 +28,0 @@ "commander": "^6.0.0", |
@@ -1,2 +0,2 @@ | ||
# [**secure-config-tool**](https://github.com/tsmx/secure-config-tool) | ||
# [**@tsmx/secure-config-tool**](https://github.com/tsmx/secure-config-tool) | ||
@@ -9,13 +9,12 @@ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) | ||
> Supporting command-line tool for [secure-config](https://www.npmjs.com/package/@tsmx/secure-config). | ||
> Supporting command-line tool for [@tsmx/secure-config](https://www.npmjs.com/package/@tsmx/secure-config). | ||
Features: | ||
- generating keys | ||
- encrypting secrets | ||
- decrypting secrets (for validation/testing purposes) | ||
- encrypting values in existing configuration files | ||
- encrypting single secrets | ||
- decrypting single secrets (for validation/testing purposes) | ||
## Usage | ||
## Installation | ||
### Installation | ||
``` | ||
@@ -27,3 +26,3 @@ [tsmx@localhost ]$ npm i -g @tsmx/secure-config-tool | ||
### Key generation | ||
## Key generation | ||
@@ -36,5 +35,25 @@ ``` | ||
### Encrypt values | ||
## Encrypt files | ||
Reads an existing JSON configuration file and encrypts the values according to specified key-patterns. The result is printed to stdout, so use `>` to save it in a new file. | ||
### Using standard encryption patterns | ||
``` | ||
[tsmx@localhost ]$ secure-config-tool create-file ./config.json > config-production.json | ||
``` | ||
If no patterns are specified using the `-p` / `--patterns` option, the standard patterns are used: `'user', 'pass', 'token'`. For each pattern a case-insensitive match is tested for each key of the JSON file to be encrypted. If the match succeeds, the value of the key is encrypted. | ||
### Using custom encryption patterns | ||
``` | ||
[tsmx@localhost ]$ secure-config-tool create-file -p "Username,Password" ./config.json > config-production.json | ||
``` | ||
Same as above, but your custom patterns are used. In the example every key is tested case-insensitive against the two regex expressions `/Username/` and `/Password/`. | ||
## Encrypt values | ||
``` | ||
[tsmx@localhost ]$ secure-config-tool create --secret MySecret | ||
@@ -44,4 +63,6 @@ ENCRYPTED|82da1c22e867d68007d66a23b7b748b3|452a2ed1105ec5607576b820b90aa49f | ||
### Decrypt values | ||
Encrypts a single value string for copy & paste to a JSON configuration file. | ||
## Decrypt values | ||
``` | ||
@@ -52,2 +73,4 @@ [tsmx@localhost ]$ secure-config-tool decrypt "ENCRYPTED|82da1c22e867d68007d66a23b7b748b3|452a2ed1105ec5607576b820b90aa49f" | ||
Decrypts a single vaule string for testing purposes. | ||
## Test | ||
@@ -54,0 +77,0 @@ |
#!/usr/bin/env node | ||
var program = require('commander'); | ||
const createFile = require('./functions/create-file'); | ||
const createSecret = require('./functions/create-secret'); | ||
@@ -10,3 +11,3 @@ const createKey = require('./functions/create-key'); | ||
.command('create') | ||
.description('creates an encrypted entry for secure-config') | ||
.description('creates an encrypted entry for a secure-config configuration') | ||
.option('-s, --secret <secret>', 'the secret value to be encrypted, asked if not provided') | ||
@@ -23,11 +24,15 @@ .option('-v, --verbose', 'verbose output') | ||
program | ||
.command('genkey') | ||
.description('generates a 32 byte AES key for encrypting/decrypting values for secure-config and returns the hex string') | ||
.option('-b, --base64', 'the generated key is a base64 string') | ||
.action(createKey).on('--help', function () { | ||
.command('create-file <config-file>') | ||
.description('creates an encrypted configuration out of an existing JSON configuration file') | ||
.option('-p, --patterns <pattern-list>', 'a comma-separated list of key-patterns that should be encrypted') | ||
.action(createFile).on('--help', function () { | ||
console.log(''); | ||
console.log('If no patterns are specified with the -p option then the default patterns are used: \'user\',\'pass\',\'token\'.') | ||
console.log('For every supplied pattern a case-insensitive regex match will be done for every key of the original JSON.'); | ||
console.log('If the match succeeds, the value of the key will be encrypted.') | ||
console.log(''); | ||
console.log('Examples:'); | ||
console.log(''); | ||
console.log(' $ secure-config-tool genkey'); | ||
console.log(' $ secure-config-tool genkey --base64'); | ||
console.log(' $ secure-config-tool create-file config.json > config-production.json'); | ||
console.log(' $ secure-config-tool create-file -p "user,api,url" config.json > config-production.json'); | ||
}); | ||
@@ -47,2 +52,12 @@ | ||
program | ||
.command('genkey') | ||
.description('generates a 32 byte AES key for encrypting/decrypting values for secure-config and returns the hex string') | ||
.action(createKey).on('--help', function () { | ||
console.log(''); | ||
console.log('Examples:'); | ||
console.log(''); | ||
console.log(' $ secure-config-tool genkey'); | ||
}); | ||
program.parse(process.argv); |
@@ -6,2 +6,3 @@ describe('secure-config-tool test suite', () => { | ||
const testConsoleLog = (output) => { testOutput.push(output) }; | ||
const hexReg = new RegExp('^[0-9A-F]*$', 'i'); | ||
@@ -67,3 +68,3 @@ const TEST_KEY = 'iC771qNLe+OGVcduw8fqpDIIK7lK0T5p'; | ||
it('tests a failed decryption - illegal secret DATA', async (done) => { | ||
it('tests a failed decryption - illegal secret data', async (done) => { | ||
expect(() => { | ||
@@ -88,11 +89,2 @@ const crypt = require('../utils/crypt'); | ||
it('tests a successful key generation with base64', async (done) => { | ||
const crypt = require('../utils/crypt'); | ||
const key = crypt.genkey(true); | ||
expect(key).toBeDefined(); | ||
expect(key.length).toBe(32); | ||
expect(Buffer.from(key).length).toBe(32); | ||
done(); | ||
}); | ||
it('tests a successful key retrieval', async (done) => { | ||
@@ -152,11 +144,2 @@ process.env['CONFIG_ENCRYPTION_KEY'] = TEST_KEY; | ||
it('tests a successful command line key generation with base64', async (done) => { | ||
const createKey = require('../functions/create-key'); | ||
createKey({ base64: true }); | ||
expect(testOutput.length).toBe(1); | ||
expect(testOutput[0].length).toBe(32); | ||
expect(Buffer.from(testOutput[0]).length).toBe(32); | ||
done(); | ||
}); | ||
it('tests a successful command line secret encryption', async (done) => { | ||
@@ -243,2 +226,63 @@ process.env['CONFIG_ENCRYPTION_KEY'] = TEST_KEY; | ||
it('tests a successful command line file encryption with default patterns', async (done) => { | ||
process.env['CONFIG_ENCRYPTION_KEY'] = TEST_KEY; | ||
const createFile = require('../functions/create-file'); | ||
createFile('./test/testfiles/config.json'); | ||
expect(testOutput.length).toBe(1); | ||
let encryptedJson = JSON.parse(testOutput[0]); | ||
expect(encryptedJson).toBeDefined(); | ||
expect(encryptedJson.database).toBeDefined(); | ||
expect(encryptedJson.database.host).toBeDefined(); | ||
expect(encryptedJson.database.host).toBe('127.0.0.1'); | ||
expect(encryptedJson.database.username).toBeDefined(); | ||
expect(encryptedJson.database.username).not.toBe('SecretDbUser'); | ||
let usenameParts = encryptedJson.database.username.split('|'); | ||
expect(usenameParts.length).toBe(3); | ||
expect(usenameParts[0]).toBe('ENCRYPTED'); | ||
expect(hexReg.test(usenameParts[1])).toBeTruthy(); | ||
expect(hexReg.test(usenameParts[2])).toBeTruthy(); | ||
expect(encryptedJson.database.password).toBeDefined(); | ||
expect(encryptedJson.database.password).not.toBe('SecretDbPassword'); | ||
let passwordParts = encryptedJson.database.password.split('|'); | ||
expect(passwordParts.length).toBe(3); | ||
expect(passwordParts[0]).toBe('ENCRYPTED'); | ||
expect(hexReg.test(passwordParts[1])).toBeTruthy(); | ||
expect(hexReg.test(passwordParts[2])).toBeTruthy(); | ||
done(); | ||
}); | ||
it('tests a successful command line file encryption with custom patterns', async (done) => { | ||
process.env['CONFIG_ENCRYPTION_KEY'] = TEST_KEY; | ||
const createFile = require('../functions/create-file'); | ||
createFile('./test/testfiles/config.json', { patterns: 'Password,test123' }); | ||
expect(testOutput.length).toBe(1); | ||
let encryptedJson = JSON.parse(testOutput[0]); | ||
expect(encryptedJson).toBeDefined(); | ||
expect(encryptedJson.database).toBeDefined(); | ||
expect(encryptedJson.database.host).toBeDefined(); | ||
expect(encryptedJson.database.host).toBe('127.0.0.1'); | ||
expect(encryptedJson.database.username).toBeDefined(); | ||
expect(encryptedJson.database.username).toBe('SecretDbUser'); | ||
expect(encryptedJson.database.password).toBeDefined(); | ||
expect(encryptedJson.database.password).not.toBe('SecretDbPassword'); | ||
let passwordParts = encryptedJson.database.password.split('|'); | ||
expect(passwordParts.length).toBe(3); | ||
expect(passwordParts[0]).toBe('ENCRYPTED'); | ||
expect(hexReg.test(passwordParts[1])).toBeTruthy(); | ||
expect(hexReg.test(passwordParts[2])).toBeTruthy(); | ||
done(); | ||
}); | ||
it('tests a failed command line file encryption because of a missing key', async (done) => { | ||
const mockExit = jest.spyOn(process, 'exit') | ||
.mockImplementation((number) => { throw new Error('process.exit: ' + number); }); | ||
const createFile = require('../functions/create-file'); | ||
expect(() => { | ||
createFile('./test/testfiles/config.json'); | ||
}).toThrow(); | ||
expect(mockExit).toHaveBeenCalledWith(-1); | ||
mockExit.mockRestore(); | ||
done(); | ||
}); | ||
}); |
@@ -6,3 +6,3 @@ const crypto = require('crypto'); | ||
module.exports.retrieveKey = function (verbose) { | ||
module.exports.retrieveKey = function (verbose = false) { | ||
const hexReg = new RegExp('^[0-9A-F]{64}$', 'i'); | ||
@@ -44,11 +44,5 @@ let result = null; | ||
module.exports.genkey = function (base64 = false) { | ||
let result = null; | ||
if (base64) { | ||
result = crypto.randomBytes(24).toString('base64'); | ||
} | ||
else { | ||
result = crypto.randomBytes(32).toString('hex'); | ||
} | ||
return result; | ||
module.exports.genkey = function () { | ||
return crypto.randomBytes(32).toString('hex'); | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
24686
11
441
76
4
18
+ Added@tsmx/json-traverse@^1.0.2
+ Added@tsmx/json-traverse@1.0.8(transitive)