config_okay
Advanced tools
Comparing version 0.0.3 to 1.0.0
/*global require module */ | ||
var fs = require('fs') | ||
var path = require('path') | ||
var rootdir = path.normalize(__dirname) | ||
var default_config_file = rootdir+'/config.json' | ||
const fs = require('fs') | ||
const path = require('path') | ||
const rootdir = path.normalize(__dirname) | ||
const default_config_file = rootdir+'/config.json' | ||
// promise wraps fs.readFile | ||
function statfile(f) { | ||
return new Promise( (resolve,reject) => { | ||
fs.stat(f,(e,s)=>{ | ||
if(e){ | ||
reject(e) | ||
} | ||
resolve(s) | ||
return null | ||
}); | ||
}); | ||
} | ||
var config_okay = function(f,cb){ | ||
if(!cb && typeof f === 'function'){ | ||
cb = f | ||
f=default_config_file | ||
} | ||
if(!f){ | ||
f=default_config_file | ||
} | ||
if(! /\.js(on)?$/.test(f)){ | ||
return cb('config_okay requires file to end in .json or .js') | ||
} | ||
fs.stat(f,function(err,stats){ | ||
if(err) return cb(err) | ||
if(!stats) return cb('no stats') | ||
if(stats.mode.toString(8) != '100600'){ | ||
return cb('mode of '+f+' must be 0600') | ||
function config_okay(f) { | ||
return new Promise( (resolve,reject) => { | ||
let stats; | ||
if(!f){ | ||
f=default_config_file | ||
} | ||
var config = require(f) | ||
return cb(null,config) | ||
if(! /\.js(on)?$/.test(f)){ | ||
return reject ('config_okay requires file to end in .json or .js') | ||
} | ||
statfile(f) | ||
.then( stats => { | ||
if(!stats){ | ||
return reject ('no stats') | ||
} | ||
if(stats.mode.toString(8) != '100600'){ | ||
return reject ('mode of '+f+' must be 0600') | ||
} | ||
const config = require(f) | ||
return resolve(config) | ||
}) | ||
.catch (e => { | ||
throw (e) | ||
}) | ||
return null | ||
}) | ||
return null | ||
} | ||
module.exports=config_okay |
{ | ||
"name": "config_okay", | ||
"version": "0.0.3", | ||
"version": "1.0.0", | ||
"description": "Make sure config files are mode 0600 before you use it", | ||
@@ -10,3 +10,3 @@ "main": "config_okay.js", | ||
"scripts": { | ||
"test": "mocha" | ||
"test": "tap test/**/test*.js" | ||
}, | ||
@@ -27,4 +27,5 @@ "repository": { | ||
"devDependencies": { | ||
"should": "~3.1.3" | ||
"denodeify": "^1.2.1", | ||
"tap": "^10.3.2" | ||
} | ||
} |
@@ -28,2 +28,5 @@ # config okay | ||
The older version you would do this: | ||
``` javascript | ||
@@ -42,4 +45,24 @@ | ||
Personally, I sometimes stick this in something like an | ||
async.waterfall as the first function in the sequence, so that if it | ||
fails, the whole cascade will abort. | ||
Now that isn't true anymore because as of May 2017 I've switched to | ||
using promises. | ||
So now the usage is | ||
``` javascript | ||
const config_okay = require('config_okay') | ||
const configfile = 'config.json' // or pull from the command line or something | ||
config_okay(configfile) | ||
.then(config => { | ||
return do_something(config) | ||
}) | ||
.catch( e => { | ||
return handleError(e) | ||
}) | ||
``` | ||
Look at the test file to see what I mean. |
/* global require console process it describe after before __dirname */ | ||
var config_okay = require('../.') | ||
const config_okay = require('../.') | ||
var should = require('should') | ||
var fs = require('fs') | ||
const fs = require('fs') | ||
const denodeify = require('denodeify') | ||
const readFile = denodeify(fs.readFile); | ||
const writeFile = denodeify(fs.writeFile); | ||
const statFile = denodeify(fs.stat); | ||
var path = require('path') | ||
var rootdir = path.normalize(__dirname) | ||
const tap = require('tap') | ||
var good_file = rootdir+'/test.good.config.json' | ||
var bad_file = rootdir+'/test.bad.config.json' | ||
const path = require('path') | ||
const rootdir = path.normalize(__dirname) | ||
before(function(done){ | ||
const good_file = rootdir+'/test.good.config.json' | ||
const bad_file = rootdir+'/test.bad.config.json' | ||
const good_config = {'foo':'bar' | ||
,'baz':'bat' | ||
,'another':2 | ||
}; | ||
const bad_config = {'foo':'barf' | ||
,'baz':'batch' | ||
,'another':false | ||
}; | ||
function before(){ | ||
// create a config file | ||
var good_config = {'foo':'bar' | ||
,'baz':'bat' | ||
,'another':2 | ||
} | ||
var bad_config = {'foo':'barf' | ||
,'baz':'batch' | ||
,'another':false | ||
} | ||
fs.writeFile(good_file | ||
,JSON.stringify(good_config) | ||
,{'encoding':'utf8' | ||
,'mode':'0600' | ||
} | ||
,function(err){ | ||
if(err) throw err | ||
} | ||
fs.writeFile(bad_file | ||
,JSON.stringify(bad_config) | ||
,{'encoding':'utf8' | ||
,'mode':'0700' | ||
} | ||
,function(err){ | ||
if(err) throw err | ||
return done() | ||
}) | ||
return null | ||
}) | ||
return null | ||
tap.plan(3) | ||
tap.test('bad file settings',function (t) { | ||
return writeFile(bad_file,JSON.stringify(bad_config) | ||
, {'enconding':'utf8' | ||
,'mode':'0700'}) | ||
.then( () => { | ||
return config_okay(bad_file) | ||
.then ( result => { | ||
t.fail( 'did not reject bad file') | ||
t.end() | ||
}) | ||
.catch ( err => { | ||
t.match(err,/^mode of.*must be 0600$/,'complaint looks good') | ||
t.pass('did not process file with wrong chmod') | ||
t.end() | ||
}) | ||
}) | ||
.then( () => { | ||
return fs.unlinkSync(bad_file) | ||
}) | ||
.catch(console.log.bind(console)) | ||
}) | ||
after(function(done){ | ||
if( !fs.unlinkSync(good_file) && !fs.unlinkSync(bad_file) ) | ||
return done() | ||
console.log('error unlinking?') | ||
return null | ||
tap.test('skip .txt files', function (t) { | ||
return config_okay('file.txt') | ||
.then ( result => { | ||
t.fail( 'did not reject .txt file') | ||
return null | ||
}) | ||
.catch( err => { | ||
t.match(err,/^config_okay requires file to end in/,'complaint looks good') | ||
t.pass('did not process .txt file') | ||
t.end() | ||
return null | ||
}) | ||
}) | ||
describe('config_okay',function(){ | ||
it('should error out on a file in without mode 0600' | ||
,function(done){ | ||
config_okay(bad_file,function(e,c){ | ||
should.exist(e) | ||
should.not.exist(c) | ||
e.should.match(/^mode of.*must be 0600$/) | ||
return done() | ||
}) | ||
}) | ||
it('should error out on a file ending in .txt' | ||
,function(done){ | ||
config_okay('file.txt',function(e,c){ | ||
should.exist(e) | ||
should.not.exist(c) | ||
e.should.match(/^config_okay requires file to end in/) | ||
return done() | ||
}) | ||
}) | ||
it('should parse okay a file in with mode 0600' | ||
,function(done){ | ||
config_okay(good_file,function(err,c){ | ||
should.not.exist(err) | ||
should.exist(c) | ||
c.should.have.keys('foo','baz','another') | ||
c.foo.should.eql('bar') | ||
c.baz.should.eql('bat') | ||
c.another.should.eql(2) | ||
return done() | ||
}) | ||
}) | ||
tap.test('read valid json file', function (t) { | ||
return writeFile(good_file,JSON.stringify(good_config) | ||
, {'enconding':'utf8' | ||
,'mode':'0600'}) | ||
.then( () => { | ||
return config_okay(good_file) | ||
.then( result => { | ||
t.ok(result) | ||
t.same(result, good_config, 'read back what was put in to config file') | ||
t.end() | ||
return null | ||
}) | ||
.catch( e =>{ | ||
t.fail('did not process valid json file') | ||
t.end() | ||
return null | ||
}) | ||
}) | ||
.then( () => { | ||
return fs.unlinkSync(good_file) | ||
}) | ||
.catch(console.log.bind(console)) | ||
}) | ||
tap.end() |
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
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
7033
8
126
0
67
2