From 38d4ae0b8d27db7f3fef897db30143aedc530f1f Mon Sep 17 00:00:00 2001 From: Michael Kimpton Date: Thu, 15 Dec 2016 16:15:08 +1100 Subject: [PATCH] add `exclude` option to restrict passwords (#15) This commit adds an option, `exclude`, through which one can pass a string of characters that will be removed from the password generation pool. For example, to remove some similar characters (without excludeSimilarCharacters), you can now pass { exclude: 'ilLI|' }. --- README.md | 1 + src/generate.js | 8 ++++++++ test/generator.js | 10 ++++++++++ 3 files changed, 19 insertions(+) diff --git a/README.md b/README.md index 8478dd7..f036f6c 100644 --- a/README.md +++ b/README.md @@ -55,4 +55,5 @@ Any of these can be passed into the options object for each function. | symbols | Boolean, put symbols in password. | false | | uppercase | Boolean, use uppercase letters in password. | true | | excludeSimilarCharacters | Boolean, exclude similar chars, like 'i' and 'l'. | false | +| exclude | String, characters to be excluded from password. | '' | | strict | Boolean, password must include at least one character from each pool. | false | diff --git a/src/generate.js b/src/generate.js index af318c2..8afd3ef 100644 --- a/src/generate.js +++ b/src/generate.js @@ -58,6 +58,7 @@ self.generate = function(options) { if (!options.hasOwnProperty('length')) options.length = 10; if (!options.hasOwnProperty('numbers')) options.numbers = false; if (!options.hasOwnProperty('symbols')) options.symbols = false; + if (!options.hasOwnProperty('exclude')) options.exclude = ''; if (!options.hasOwnProperty('uppercase')) options.uppercase = true; if (!options.hasOwnProperty('excludeSimilarCharacters')) options.excludeSimilarCharacters = false; if (!options.hasOwnProperty('strict')) options.strict = false; @@ -84,11 +85,18 @@ self.generate = function(options) { if (options.symbols) { pool += symbols; } + // similar characters if (options.excludeSimilarCharacters) { pool = pool.replace(similarCharacters, ''); } + // excludes characters from the pool + var i = options.exclude.length; + while (i--) { + pool = pool.replace(options.exclude[i], ''); + } + var password = generate(options, pool); return password; diff --git a/test/generator.js b/test/generator.js index 9f74a6c..20aebcc 100644 --- a/test/generator.js +++ b/test/generator.js @@ -77,6 +77,16 @@ describe('generate-password', function() { assert.equal(passwords.length, amountToGenerate); }); + it('should generate strict random sequence that avoids all excluded characters', function() { + var passwords = generator.generateMultiple(amountToGenerate, {length: 4, strict: true, symbols: true, exclude: 'abcdefg+_-=}{[]|:;"/?.><,`~'}); + + passwords.forEach(function(password) { + assert.match(password, /[!@#$%^&*()]/, 'password uses normal symbols'); + assert.notMatch(password, /[abcdefg+_\-=}{[\]|:;"/?.><,`~]/, 'password avoids excluded characters from the full pool'); + }); + assert.equal(passwords.length, amountToGenerate); + }); + it('should throw an error if rules don\'t correlate with length', function() { assert.throws(function() { generator.generate({length: 2, strict: true, symbols: true, numbers: true});