Socket
Socket
Sign inDemoInstall

nconf

Package Overview
Dependencies
Maintainers
2
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nconf - npm Package Compare versions

Comparing version 0.7.2 to 0.8.0

test/fixtures/secure.json

86

CHANGELOG.md

@@ -0,2 +1,88 @@

v0.8.0 / Sun, 20 Sep 2015
=========================
* [0922563](https://github.com/indexzero/nconf/commit/0922563) [doc fix] Remove unused and outdated literate coding documentation. (`indexzero`)
* [4b5030d](https://github.com/indexzero/nconf/commit/4b5030d) [fix] Only merge actual objects, not `null` values. Fixes #150. (`indexzero`)
* [a3589fa](https://github.com/indexzero/nconf/commit/a3589fa) Fixing provider issue in source (`Rob Rodriguez`)
* [51653e6](https://github.com/indexzero/nconf/commit/51653e6) Passing the value parameter to the providers (`Rob Rodriguez`)
* [2030144](https://github.com/indexzero/nconf/commit/2030144) [test dist] Add `test/fixtures/secure.json`. (`indexzero`)
* [9dbed2d](https://github.com/indexzero/nconf/commit/9dbed2d) [doc minor] Update docs for secure information. (`indexzero`)
* [0358545](https://github.com/indexzero/nconf/commit/0358545) [test api] Make the format capable of sub-objects. (`indexzero`)
* [04c0f3a](https://github.com/indexzero/nconf/commit/04c0f3a) [api test] Encrypt individual keys instead of entire stringified contents. Added basic unit tests. (`indexzero`)
* [d2b3561](https://github.com/indexzero/nconf/commit/d2b3561) [dist] Update `.travis.yml`. (`indexzero`)
* [442d2b4](https://github.com/indexzero/nconf/commit/442d2b4) [api] Allow for `secure` to be simply a secret string. (`indexzero`)
* [2de2bc0](https://github.com/indexzero/nconf/commit/2de2bc0) [api] Allow for "secure" option to be passed to `nconf.stores.File` to perform content encryption / decryption with `crypto.createCipher`. (`indexzero`)
* [5d95f13](https://github.com/indexzero/nconf/commit/5d95f13) filter out undefined values (`Christian Murphy`)
* [7d6be32](https://github.com/indexzero/nconf/commit/7d6be32) [travis] fix yaml syntax (supposed to solve nvm bugs #182) (`Joseph Page`)
* [abeeca0](https://github.com/indexzero/nconf/commit/abeeca0) [travis] fix npm bugs for node 0.8 (recommended way) (`Joseph Page`)
* [59056fe](https://github.com/indexzero/nconf/commit/59056fe) Update Async and ini (`Christian Murphy`)
* [a2b812f](https://github.com/indexzero/nconf/commit/a2b812f) Add travis tests for iojs (`Joseph Page`)
* [32d560c](https://github.com/indexzero/nconf/commit/32d560c) Add tests for node 0.12 (`Joseph Page`)
* [8a21ef3](https://github.com/indexzero/nconf/commit/8a21ef3) env({lowerCase:true}) option to make it possible to get() keys in lower case (`Olivier Lalonde`)
* [89dff39](https://github.com/indexzero/nconf/commit/89dff39) Quick grammar fix (`Nick Heiner`)
* [339e59a](https://github.com/indexzero/nconf/commit/339e59a) fix random fails on tests that use child process (`Pierre Beaujeu`)
* [a65e1a3](https://github.com/indexzero/nconf/commit/a65e1a3) update async (`Christian Murphy`)
* [a82b539](https://github.com/indexzero/nconf/commit/a82b539) update badge and use container build (`Christian Murphy`)
* [e5b33ce](https://github.com/indexzero/nconf/commit/e5b33ce) Add license attribute (`Gilad Peleg`)
0.7.2 / Tue, 4 Aug 2015
=======================
* [c2b8b97](https://github.com/indexzero/nconf/commit/c2b8b97) [dist] Version bump. 0.7.2 (`indexzero`)
* [3c11ef5](https://github.com/indexzero/nconf/commit/3c11ef5) fix: env.match test (`Remy Sharp`)
* [372521b](https://github.com/indexzero/nconf/commit/372521b) [doc] Add the badges!. (`indexzero`)
* [80ec01b](https://github.com/indexzero/nconf/commit/80ec01b) replace optimist with yargs (`Christian Murphy`)
* [6d86950](https://github.com/indexzero/nconf/commit/6d86950) Grammar nit (`Nick Heiner`)
v0.7.1 / Wed, 26 Nov 2014
=========================
* [dc6aed2](https://github.com/indexzero/nconf/commit/dc6aed2) [dist] Version bump. 0.7.1 (`Jarrett Cruger`)
* [87a3b82](https://github.com/indexzero/nconf/commit/87a3b82) [fix] we shouldnt be reversing here fixes #127 (`Jarrett Cruger`)
* [6271cdb](https://github.com/indexzero/nconf/commit/6271cdb) Revert "fixing the tests" (`Jarrett Cruger`)
* [f0d5b6e](https://github.com/indexzero/nconf/commit/f0d5b6e) [dist] Fix travis. (`indexzero`)
v0.7.0 / Wed, 26 Nov 2014
=========================
* [a2a1321](https://github.com/indexzero/nconf/commit/a2a1321) [dist] Version bump. 0.7.0 (`indexzero`)
* [352f075](https://github.com/indexzero/nconf/commit/352f075) [dist] "Real" CHANGELOG.md again. (`indexzero`)
* [af0e9fb](https://github.com/indexzero/nconf/commit/af0e9fb) [dist fix] Cleanup some whitespace. (`indexzero`)
* [0934255](https://github.com/indexzero/nconf/commit/0934255) [fix] Fixed regression introduced by #98. (`indexzero`)
* [8d5fb25](https://github.com/indexzero/nconf/commit/8d5fb25) [fix] Fix my own sloppy coding fixing the sloppy coding from #76. (`indexzero`)
* [f07bc40](https://github.com/indexzero/nconf/commit/f07bc40) [fix] Fix inconsistent style from #98. (`indexzero`)
* [0b8aa90](https://github.com/indexzero/nconf/commit/0b8aa90) [fix test] Remove leftover `console.log()` from #79. (`indexzero`)
* [f771500](https://github.com/indexzero/nconf/commit/f771500) [dist] Semantic cleanup from sloppy coding in #76. (`indexzero`)
* [ffce2cb](https://github.com/indexzero/nconf/commit/ffce2cb) [dist] Update package.json versions. (`indexzero`)
* [6301d7d](https://github.com/indexzero/nconf/commit/6301d7d) Update Readme; multiple file() needs custom key (`Mitchell McKenna`)
* [f69e43a](https://github.com/indexzero/nconf/commit/f69e43a) fixing the tests (`Chris Manson`)
* [c8b6c98](https://github.com/indexzero/nconf/commit/c8b6c98) Adding helpful information in case parsing failed. (`Martin Heidegger`)
* [8105c76](https://github.com/indexzero/nconf/commit/8105c76) [fix] only reverse keys for "get" action to be safe. (`Christopher Jeffrey`)
* [2241a36](https://github.com/indexzero/nconf/commit/2241a36) [fix] have latter stores precede the former stores again. (`Christopher Jeffrey`)
* [0bb89ee](https://github.com/indexzero/nconf/commit/0bb89ee) [fix] have latter stores precede the former stores. (`Christopher Jeffrey`)
* [43505a5](https://github.com/indexzero/nconf/commit/43505a5) Use ~ for dependencies (`Gabe Gorelick`)
* [05d73de](https://github.com/indexzero/nconf/commit/05d73de) [fix] No need to test 0.6 anymore (`Jarrett Cruger`)
* [79b9b84](https://github.com/indexzero/nconf/commit/79b9b84) [doc] Add a Literal example to add() (`Tommy Stanton`)
* [3a7b788](https://github.com/indexzero/nconf/commit/3a7b788) [doc] The store for File is empty if non-existent (`Tommy Stanton`)
* [9891814](https://github.com/indexzero/nconf/commit/9891814) Delete CHANGELOG.md (`Alexey Simonenko`)
* [120f5f0](https://github.com/indexzero/nconf/commit/120f5f0) added documentation (`joaoafrmartins`)
* [681fd2f](https://github.com/indexzero/nconf/commit/681fd2f) added regexp filtering to nconf env store (`joaoafrmartins`)
* [039057c](https://github.com/indexzero/nconf/commit/039057c) allow different separator for memorystore (`José F. Romaniello`)
* [b73b0e1](https://github.com/indexzero/nconf/commit/b73b0e1) attach help and showHelp arguments to the argv store (`Johnny Domino`)
* [4894c8f](https://github.com/indexzero/nconf/commit/4894c8f) resolves #64 passing usage string to optimist (`Johnny Domino`)
v0.6.9 / Sun, 1 Dec 2013
========================
* [022b9bc](https://github.com/indexzero/nconf/commit/022b9bc) [dist] Version bump. 0.6.9 (`Jarrett Cruger`)
* [9aa33b5](https://github.com/indexzero/nconf/commit/9aa33b5) [dist] bump optimist version, fixes #89 (`Jarrett Cruger`)
* [92311c8](https://github.com/indexzero/nconf/commit/92311c8) [rm] kill pkginfo (`Jarrett Cruger`)
* [c713936](https://github.com/indexzero/nconf/commit/c713936) [dist] bump async (`Jarrett Cruger`)
v0.6.8 / Tue, 29 Oct 2013
=========================
* [cd81efa](https://github.com/indexzero/nconf/commit/cd81efa) [dist] Version bump. 0.6.8 (`Jarrett Cruger`)
* [6c1eb5e](https://github.com/indexzero/nconf/commit/6c1eb5e) fixed white spacing and added (embarrassing absent) variable declarations (`midknight41`)
* [5546469](https://github.com/indexzero/nconf/commit/5546469) updated .travis.yml as travis doesn't support node 0.4 or 0.9 (`midknight41`)
* [29f1ca2](https://github.com/indexzero/nconf/commit/29f1ca2) added support for BOM in load() and loadSync() (`midknight41`)
* [ada15db](https://github.com/indexzero/nconf/commit/ada15db) Test that invalid file name is indicated (`Marcin Floryan`)
* [0135d95](https://github.com/indexzero/nconf/commit/0135d95) Additional error information when JSON config file cannot be read (`Marcin Floryan`)
* [5d2ebfb](https://github.com/indexzero/nconf/commit/5d2ebfb) Added test to confirm merging an Object and null behaves as expected. (`Michael Schoonmaker`)
* [ed41c51](https://github.com/indexzero/nconf/commit/ed41c51) Updated Memory.merge to handle null values (`Michael Schoonmaker`)
v0.6.7 / Thu, 20 Dec 2012

@@ -3,0 +89,0 @@ =========================

8

lib/nconf.js

@@ -11,6 +11,10 @@ /*

common = require('./nconf/common'),
Provider = require('./nconf/provider').Provider,
nconf = module.exports = new Provider();
Provider = require('./nconf/provider').Provider;
//
// `nconf` is by default an instance of `nconf.Provider`.
//
var nconf = module.exports = new Provider();
//
// Expose the version from the package.json

@@ -17,0 +21,0 @@ //

@@ -213,2 +213,8 @@ /*

Provider.prototype.get = function (key, callback) {
if (typeof key === 'function') {
// Allow a * key call to be made
callback = key;
key = null;
}
//

@@ -248,3 +254,3 @@ // If there is no callback we can short-circuit into the default

// Merge objects if necessary
if (typeof response === 'object' && !Array.isArray(response)) {
if (response && typeof response === 'object' && !Array.isArray(response)) {
mergeObjs.push(response);

@@ -261,3 +267,3 @@ response = undefined;

// Merge objects if necessary
if (typeof response === 'object' && !Array.isArray(response)) {
if (response && typeof response === 'object' && !Array.isArray(response)) {
mergeObjs.push(response);

@@ -468,3 +474,3 @@ response = undefined;

if (store.save) {
return store.save(function (err, data) {
return store.save(value, function (err, data) {
if (err) {

@@ -471,0 +477,0 @@ return next(err);

@@ -61,3 +61,5 @@ /*

Object.keys(argv).forEach(function (key) {
self.set(key, argv[key]);
if (typeof argv[key] !== 'undefined') {
self.set(key, argv[key]);
}
});

@@ -64,0 +66,0 @@

@@ -26,2 +26,3 @@ /*

this.separator = options.separator || '';
this.lowerCase = options.lowerCase || false;

@@ -60,4 +61,12 @@ if (({}).toString.call(options.match) === '[object RegExp]'

var env = process.env;
if (this.lowerCase) {
Object.keys(env).forEach(function (key) {
env[key.toLowerCase()] = env[key];
});
}
this.readOnly = false;
Object.keys(process.env).filter(function (key) {
Object.keys(env).filter(function (key) {
if (self.match && self.whitelist.length) {

@@ -74,6 +83,6 @@ return key.match(self.match) || self.whitelist.indexOf(key) !== -1

if (self.separator) {
self.set(common.key.apply(common, key.split(self.separator)), process.env[key]);
self.set(common.key.apply(common, key.split(self.separator)), env[key]);
}
else {
self.set(key, process.env[key]);
self.set(key, env[key]);
}

@@ -80,0 +89,0 @@ });

@@ -8,3 +8,4 @@ /*

var fs = require('fs'),
var crypto = require('crypto'),
fs = require('fs'),
path = require('path'),

@@ -30,8 +31,26 @@ util = require('util'),

this.type = 'file';
this.file = options.file;
this.dir = options.dir || process.cwd();
this.format = options.format || formats.json;
this.json_spacing = options.json_spacing || 2;
this.type = 'file';
this.file = options.file;
this.dir = options.dir || process.cwd();
this.format = options.format || formats.json;
this.secure = options.secure;
this.spacing = options.json_spacing
|| options.spacing
|| 2;
if (this.secure) {
this.secure = typeof this.secure === 'string'
? { secret: this.secure }
: this.secure;
this.secure.alg = this.secure.alg || 'aes-256-ctr';
if (this.secure.secretPath) {
this.secret = fs.readFileSync(this.secure.secretPath, 'utf8');
}
if (!this.secure.secret) {
throw new Error('secure.secret option is required');
}
}
if (options.search) {

@@ -58,5 +77,3 @@ this.search(this.dir);

fs.writeFile(this.file, this.format.stringify(this.store, null, this.json_spacing), function (err) {
return err ? callback(err) : callback();
});
fs.writeFile(this.file, this.stringify(), callback);
};

@@ -72,8 +89,3 @@

File.prototype.saveSync = function (value) {
try {
fs.writeFileSync(this.file, this.format.stringify(this.store, null, this.json_spacing));
}
catch (ex) {
throw(ex);
}
fs.writeFileSync(this.file, this.stringify());
return this.store;

@@ -104,8 +116,9 @@ };

try {
//deals with string that include BOM
// Deals with string that include BOM
var stringData = data.toString();
if (stringData.charAt(0) === '\uFEFF') {
stringData = stringData.substr(1);
}
if (stringData.charAt(0) === '\uFEFF') stringData = stringData.substr(1);
self.store = self.format.parse(stringData);
self.store = self.parse(stringData);
}

@@ -127,29 +140,80 @@ catch (ex) {

File.prototype.loadSync = function () {
var data, self = this;
if (!existsSync(self.file)) {
self.store = {};
data = {};
if (!existsSync(this.file)) {
this.store = {};
return this.store;
}
else {
//
// Else, the path exists, read it from disk
//
try {
//deals with file that include BOM
var fileData = fs.readFileSync(this.file, 'utf8');
if (fileData.charAt(0) === '\uFEFF') fileData = fileData.substr(1);
data = this.format.parse(fileData);
this.store = data;
//
// Else, the path exists, read it from disk
//
try {
// Deals with file that include BOM
var fileData = fs.readFileSync(this.file, 'utf8');
if (fileData.charAt(0) === '\uFEFF') {
fileData = fileData.substr(1);
}
catch (ex) {
throw new Error("Error parsing your configuration file: [" + self.file + ']: ' + ex.message);
}
this.store = this.parse(fileData);
}
catch (ex) {
throw new Error("Error parsing your configuration file: [" + this.file + ']: ' + ex.message);
}
return data;
return this.store;
};
//
// ### function stringify ()
// Returns an encrypted version of the contents IIF
// `this.secure` is enabled
//
File.prototype.stringify = function () {
var data = this.store,
self = this;
if (this.secure) {
data = Object.keys(data).reduce(function (acc, key) {
var value = self.format.stringify(data[key]);
acc[key] = {
alg: self.secure.alg,
value: cipherConvert(value, {
alg: self.secure.alg,
secret: self.secure.secret,
encs: { input: 'utf8', output: 'hex' }
})
}
return acc;
}, {});
}
return this.format.stringify(data, null, this.spacing);
};
//
// ### function parse (contents)
// Returns a decrypted version of the contents IFF
// `this.secure` is enabled.
//
File.prototype.parse = function (contents) {
var parsed = this.format.parse(contents),
self = this;
if (!this.secure) {
return parsed;
}
return Object.keys(parsed).reduce(function (acc, key) {
var decrypted = cipherConvert(parsed[key].value, {
alg: parsed[key].alg || self.secure.alg,
secret: self.secure.secret,
encs: { input: 'hex', output: 'utf8' }
});
acc[key] = self.format.parse(decrypted);
return acc;
}, {});
};
//
// ### function search (base)

@@ -244,1 +308,13 @@ // #### @base {string} Base directory (or file) to begin searching for the target file.

};
//
// ### function cipherConvert (contents, opts)
// Returns the result of the cipher operation
// on the contents contents.
//
function cipherConvert(contents, opts) {
var encs = opts.encs;
var cipher = crypto.createCipher(opts.alg, opts.secret);
return cipher.update(contents, encs.input, encs.output)
+ cipher.final(encs.output);
}
{
"name": "nconf",
"description": "Hierarchical node.js configuration with files, environment variables, command-line arguments, and atomic object merging.",
"version": "0.7.2",
"version": "0.8.0",
"author": "Charlie Robbins <charlie.robbins@gmail.com>",

@@ -16,5 +16,5 @@ "repository": {

"dependencies": {
"async": "~0.9.0",
"ini": "1.x.x",
"yargs": "~3.15.0"
"async": "^1.4.0",
"ini": "^1.3.0",
"yargs": "^3.19.0"
},

@@ -30,3 +30,4 @@ "devDependencies": {

"node": ">= 0.4.0"
}
},
"license": "MIT"
}

@@ -23,4 +23,4 @@ # nconf

nconf.argv()
.env()
.file({ file: 'path/to/config.json' });
.env()
.file({ file: 'path/to/config.json' });

@@ -67,3 +67,3 @@ //

Configuration management can get complicated very quickly for even trivial applications running in production. `nconf` addresses this problem by enabling you to setup a hierarchy for different sources of configuration with no defaults. **The order in which you attach these configuration sources determines their priority in the hierarchy.** Lets take a look at the options available to you
Configuration management can get complicated very quickly for even trivial applications running in production. `nconf` addresses this problem by enabling you to setup a hierarchy for different sources of configuration with no defaults. **The order in which you attach these configuration sources determines their priority in the hierarchy.** Let's take a look at the options available to you

@@ -221,4 +221,6 @@ 1. **nconf.argv(options)** Loads `process.argv` using yargs. If `options` is supplied it is passed along to yargs.

### File
Based on the Memory store, but provides additional methods `.save()` and `.load()` which allow you to read your configuration to and from file. As with the Memory store, all method calls are synchronous with the exception of `.save()` and `.load()` which take callback functions. It is important to note that setting keys in the File engine will not be persisted to disk until a call to `.save()` is made. Note a custom key must be supplied as the first parameter for hierarchy to work if multiple files are used.
Based on the Memory store, but provides additional methods `.save()` and `.load()` which allow you to read your configuration to and from file. As with the Memory store, all method calls are synchronous with the exception of `.save()` and `.load()` which take callback functions.
It is important to note that setting keys in the File engine will not be persisted to disk until a call to `.save()` is made. Note a custom key must be supplied as the first parameter for hierarchy to work if multiple files are used.
``` js

@@ -235,2 +237,31 @@ nconf.file('path/to/your/config.json');

#### Encrypting file contents
As of `nconf@0.8.0` it is now possible to encrypt and decrypt file contents using the `secure` option:
``` js
nconf.file('secure-file', {
file: 'path/to/secure-file.json',
secure: {
secret: 'super-secretzzz-keyzz',
alg: 'aes-256-ctr'
}
})
```
This will encrypt each key using [`crypto.createCipher`](https://nodejs.org/api/crypto.html#crypto_crypto_createcipher_algorithm_password), defaulting to `aes-256-ctr`. The encrypted file contents will look like this:
```
{
"config-key-name": {
"alg": "aes-256-ctr", // cipher used
"value": "af07fbcf" // encrypted contents
},
"another-config-key": {
"alg": "aes-256-ctr", // cipher used
"value": "e310f6d94f13" // encrypted contents
},
}
```
### Redis

@@ -259,20 +290,6 @@ There is a separate Redis-based store available through [nconf-redis][0]. To install and use this store simply:

## Installation
### Installing npm (node package manager)
```
curl http://npmjs.org/install.sh | sh
npm install nconf --save
```
### Installing nconf
```
[sudo] npm install nconf
```
## More Documentation
There is more documentation available through docco. I haven't gotten around to making a gh-pages branch so in the meantime if you clone the repository you can view the docs:
```
open docs/nconf.html
```
## Run Tests

@@ -279,0 +296,0 @@ Tests are written in vows and give complete coverage of all APIs and storage engines.

@@ -137,2 +137,24 @@ /*

}
}).addBatch({
// Threw this in it's own batch to make sure it's run separately from the
// sync check
"When using env with lowerCase:true": {
topic: function () {
var that = this;
helpers.cp(complete, completeTest, function () {
nconf.env({ lowerCase: true });
that.callback();
});
},
"env vars": {
"keys also available as lower case": function () {
Object.keys(process.env).forEach(function (key) {
assert.equal(nconf.get(key.toLowerCase()), process.env[key]);
});
}
},
teardown: function () {
nconf.remove('env');
}
}
}).export(module);

@@ -65,3 +65,3 @@ /*

child.on('exit', function () {
child.on('close', function () {
fs.readFile(configFile, 'utf8', that.callback.bind(null, null, data));

@@ -94,3 +94,3 @@ });

child.on('exit', function() {
child.on('close', function() {
that.callback(null, data);

@@ -97,0 +97,0 @@ });

@@ -225,3 +225,38 @@ /*

}
}).addBatch({
"When using the nconf file store": {
topic: function () {
var secureStore = new nconf.File({
file: path.join(__dirname, '..', 'fixtures', 'secure.json'),
secure: 'super-secretzzz'
});
secureStore.store = data;
return secureStore;
},
"the stringify() method should encrypt properly": function (store) {
var contents = JSON.parse(store.stringify());
Object.keys(data).forEach(function (key) {
assert.isObject(contents[key]);
assert.isString(contents[key].value);
assert.equal(contents[key].alg, 'aes-256-ctr');
});
},
"the parse() method should decrypt properly": function (store) {
var contents = store.stringify();
var parsed = store.parse(contents);
assert.deepEqual(parsed, data);
},
"the load() method should decrypt properly": function (store) {
store.load(function (err, loaded) {
assert.isNull(err);
assert.deepEqual(loaded, data);
});
},
"the loadSync() method should decrypt properly": function (store) {
var loaded = store.loadSync()
assert.deepEqual(loaded, data);
}
}
}).export(module);

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc