├── .gitattributes ├── index.js ├── .gitignore ├── bin └── password-generator ├── .travis.yml ├── index.d.ts ├── bower.json ├── test ├── browser.html ├── browser-dist.html └── password-generator.test.js ├── Makefile ├── LICENSE ├── dist ├── password-generator.min.js └── password-generator.js ├── package.json ├── lib ├── cli.js └── password-generator.js ├── Gruntfile.js └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | test/*.html linguist-vendored -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/password-generator'); -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | npm-debug.log 4 | lib-cov 5 | test/coverage.html -------------------------------------------------------------------------------- /bin/password-generator: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var path = require('path'), 4 | fs = require('fs'), 5 | lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib'); 6 | 7 | require(lib + '/cli').run(); 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | sudo: false 3 | node_js: 4 | - 14 5 | - 13 6 | - 12 7 | - 10 8 | - 8 9 | branches: 10 | only: 11 | - master 12 | notifications: 13 | email: 14 | - bermi@bermilabs.com -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | // Usage: import * as generatePassword from 'password-generator'; 2 | // generatePassword(); 3 | 4 | declare namespace generatePassword { 5 | } 6 | 7 | declare function generatePassword(length?: number, memorable?: boolean, pattern?: RegExp, prefix?: string): string; 8 | 9 | export = generatePassword; 10 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "password-generator", 3 | "description": "Memorable password generator. For the command line, Node.js and browsers.", 4 | "version": "2.0.6", 5 | "main": "lib/password-generator.js", 6 | "license": "MIT", 7 | "keywords": [ 8 | "password", 9 | "generator", 10 | "pass", 11 | "random", 12 | "browser", 13 | "crypto", 14 | "security" 15 | ], 16 | "authors": [ 17 | "Bermi Ferrer " 18 | ], 19 | "repository": { 20 | "type": "git", 21 | "url": "git@github.com:bermi/password-generator.git" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/browser.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Password Generator Tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/browser-dist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Password Generator Tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | test: 2 | @NODE_ENV=test \ 3 | ./node_modules/.bin/mocha \ 4 | --reporter spec \ 5 | $(TESTFLAGS) 6 | 7 | test-instrument: 8 | jscoverage lib lib-cov 9 | 10 | test-clean-instrument: 11 | rm -rf lib-cov 12 | 13 | test-coverage-report: 14 | @NODE_ENV=coverage \ 15 | ./node_modules/.bin/mocha \ 16 | --reporter html-cov > test/coverage.html && \ 17 | open test/coverage.html 18 | 19 | test-coverage: test-clean-instrument test-instrument test-coverage-report 20 | 21 | test-watch: 22 | @TESTFLAGS=--watch $(MAKE) test 23 | 24 | test-browser: 25 | open test/browser.html 26 | 27 | dev: 28 | ./node_modules/.bin/grunt watch 29 | 30 | dev-test: 31 | make dev & \ 32 | make test-watch 33 | 34 | all: 35 | ./node_modules/.bin/grunt 36 | 37 | lint: 38 | ./node_modules/.bin/grunt jshint 39 | 40 | build: 41 | ./node_modules/.bin/grunt build 42 | 43 | docclean: 44 | rm -f docs/*.{1,html} 45 | 46 | 47 | clean: docclean test-clean-instrument test-watch test 48 | 49 | .PHONY: test build lint test-cov docclean dev -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Bermi Ferrer 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /dist/password-generator.min.js: -------------------------------------------------------------------------------- 1 | /*! password-generator - v2.3.1 (2020-06-04) 2 | * ----------------- 3 | * Copyright(c) 2011-2020 Bermi Ferrer 4 | * https://github.com/bermi/password-generator 5 | * MIT Licensed 6 | */ 7 | !function(t){var i=/[aeiou]$/i,l=/[bcdfghjklmnpqrstvwxyz]$/i,e=t.localPasswordGeneratorLibraryName||"generatePassword",o=function(e,r,t,o){var n,a,s="",u=[];if(null==e&&(e=10),null==r&&(r=!0),null==t&&(t=/\w/),null==o&&(o=""),!r){for(a=33;a<=126;a+=1)(s=String.fromCharCode(a)).match(t)&&u.push(s);if(!u.length)throw new Error("Could not find characters that match the password pattern "+t+". Patterns must match individual characters, not the password as a whole.")}for(;o.length", 6 | "keywords": [ 7 | "password", 8 | "generator", 9 | "pass", 10 | "random", 11 | "browser", 12 | "crypto", 13 | "security" 14 | ], 15 | "bugs": { 16 | "web": "http://github.com/bermi/password-generator/issues" 17 | }, 18 | "licenses": [ 19 | { 20 | "type": "MIT", 21 | "url": "http://opensource.org/licenses/mit-license.php" 22 | } 23 | ], 24 | "repository": { 25 | "type": "git", 26 | "url": "git://github.com/bermi/password-generator.git" 27 | }, 28 | "dependencies": {}, 29 | "devDependencies": { 30 | "expect.js": "^0.3.1", 31 | "grunt": "^1.4.1", 32 | "grunt-contrib-concat": "^1.0.1", 33 | "grunt-contrib-jshint": "^3.0.0", 34 | "grunt-contrib-uglify": "^5.0.1", 35 | "grunt-contrib-watch": "^1.1.0", 36 | "mocha": "9.1.1" 37 | }, 38 | "scripts": { 39 | "test": "make test", 40 | "precommit": "grunt build && git add dist/*" 41 | }, 42 | "release-it": { 43 | "hooks": { 44 | "before:bump": "npm run precommit" 45 | } 46 | }, 47 | "files": [ 48 | "/lib", 49 | "/index.js", 50 | "/index.d.ts", 51 | "/bin/password-generator" 52 | ], 53 | "typings": "index.d.ts", 54 | "main": "index", 55 | "bin": "./bin/password-generator", 56 | "directories": { 57 | "lib": "./lib" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /lib/cli.js: -------------------------------------------------------------------------------- 1 | var argv = process.argv.slice(2).reduce( 2 | function parseArg(memo, arg, idx, rawArgs) { 3 | var nextArg = rawArgs[idx + 1] || true; 4 | if (arg[0] === '-') { 5 | var equalIdx = arg.indexOf('='); 6 | if (equalIdx === -1) { 7 | memo[arg[1]] = nextArg && nextArg[0] === '-' ? true : nextArg; 8 | } else { 9 | memo[arg[1]] = arg.slice(equalIdx + 1).trim(); 10 | } 11 | } 12 | return memo; 13 | }, {}); 14 | 15 | var puts = console.log; 16 | 17 | var options = { 18 | l: { 19 | description: 'Password length [default: null]' 20 | }, 21 | c: { 22 | description: 'Generates a non memorable password [default: "memorable"]' 23 | }, 24 | p: { 25 | description: 'Pattern to match for the generated password' 26 | }, 27 | h: { 28 | description: 'Displays this help' 29 | } 30 | }; 31 | 32 | this.showHelp = function () { 33 | puts('Generates a memorable password\r\n'); 34 | puts('Options:'); 35 | var keys = Object.keys(options); 36 | 37 | keys.forEach(function (key) { 38 | puts(' -' + key + ': ' + options[key].description); 39 | }); 40 | }; 41 | 42 | this.run = function () { 43 | var MEMORABLE, generatePassword, memorable, pattern; 44 | MEMORABLE = 'memorable'; 45 | generatePassword = require('./password-generator'); 46 | pattern = argv.p || null; 47 | if (argv.h) { 48 | return this.showHelp(); 49 | } 50 | memorable = argv.c || MEMORABLE; 51 | 52 | if (pattern) { 53 | pattern = new RegExp(pattern); 54 | memorable = false; 55 | } 56 | puts(generatePassword(argv.l, memorable === MEMORABLE, pattern)); 57 | }; 58 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | 3 | var pkg = require("./package.json"); 4 | 5 | var banner = "/*! " + pkg.name + " - v" + pkg.version + " " + 6 | '(<%= grunt.template.today("yyyy-mm-dd") %>)' + 7 | "\n* -----------------\n" + 8 | "* Copyright(c) 2011-" + new Date().getFullYear() + 9 | " Bermi Ferrer \n" + 10 | "* https://github.com/bermi/password-generator \n" + 11 | "* MIT Licensed\n*/"; 12 | 13 | // Project configuration. 14 | grunt.initConfig({ 15 | watch: { 16 | files: ['Gruntfile', 'index.js', 'lib/*.js', 'test/*.js', 'bin/*'], 17 | tasks: 'jshint' 18 | }, 19 | jshint: { 20 | all: ['Gruntfile', 'index.js', 'lib/*.js', 'test/*.js', 'bin/*'], 21 | options: { 22 | strict: false, 23 | bitwise: true, 24 | curly: true, 25 | eqeqeq: true, 26 | forin: true, 27 | immed: true, 28 | latedef: true, 29 | newcap: true, 30 | noarg: true, 31 | nonew: true, 32 | plusplus: true, 33 | regexp: true, 34 | noempty: true, 35 | sub: true, 36 | undef: true, 37 | trailing: true, 38 | eqnull: true, 39 | browser: true, 40 | node: true, 41 | indent: 2, 42 | onevar: true, 43 | white: true, 44 | globals: { 45 | describe: true, 46 | expect: true, 47 | it: true, 48 | before: true, 49 | ender: true 50 | } 51 | } 52 | }, 53 | pkg: '', 54 | meta: { 55 | banner: banner 56 | }, 57 | concat: { 58 | dist: { 59 | src: ['lib/password-generator.js'], 60 | dest: 'dist/password-generator.js' 61 | } 62 | }, 63 | uglify: { 64 | dist: { 65 | src: ['', 'dist/password-generator.js'], 66 | dest: 'dist/password-generator.min.js' 67 | }, 68 | options: { 69 | banner: banner 70 | } 71 | } 72 | }); 73 | 74 | grunt.loadNpmTasks('grunt-contrib-concat'); 75 | grunt.loadNpmTasks('grunt-contrib-jshint'); 76 | grunt.loadNpmTasks('grunt-contrib-uglify'); 77 | grunt.loadNpmTasks('grunt-contrib-watch'); 78 | 79 | // Default task. 80 | grunt.registerTask('default', ['jshint']); 81 | 82 | // Build task. 83 | grunt.registerTask('build', ['jshint', 'concat', 'uglify']); 84 | 85 | }; -------------------------------------------------------------------------------- /test/password-generator.test.js: -------------------------------------------------------------------------------- 1 | (function (root) { 2 | 3 | var expect = root.expect || require('expect.js'), 4 | generatePassword; 5 | 6 | // This test is meant to run in both, the browser and the CLI 7 | if (typeof require !== 'undefined') { 8 | generatePassword = require('../'); 9 | } else { 10 | generatePassword = root.generatePassword; 11 | } 12 | 13 | 14 | describe("When using the password generator, it:", function () { 15 | 16 | it('should generate a 10 chararacter memorable password', function () { 17 | expect(generatePassword()).to.match(/([bcdfghjklmnpqrstvwxyz][aeiou]){5}/); 18 | }); 19 | 20 | 21 | it('should generate a 6 chararacter memorable password', function () { 22 | expect(generatePassword()).to.match(/([bcdfghjklmnpqrstvwxyz][aeiou]){3}/); 23 | }); 24 | 25 | 26 | it('should generate a 1000 chararacter non memorable password', function () { 27 | var pass = generatePassword(1000, false); 28 | expect(pass).to.match(/[bcdfghjklmnpqrstvwxyz]{4}/ig); 29 | expect(pass.length).to.be(1000); 30 | }); 31 | 32 | 33 | it('should generate passwords matching regex pattern', function () { 34 | var pass = generatePassword(5, false, /\d/); 35 | expect(pass).to.match(/^\d{5}$/); 36 | }); 37 | 38 | 39 | it('should generate passwords with a given preffix', function () { 40 | var pass = generatePassword(7, false, /\d/, 'foo-'); 41 | expect(pass).to.match(/^foo\-\d{3}$/); 42 | }); 43 | 44 | 45 | it('should generate long passwords without throwing call stack limit exceptions', function () { 46 | var pass = generatePassword(1200, false, /\d/); 47 | expect(pass).to.match(/^\d{1200}$/); 48 | }); 49 | 50 | 51 | it('should generate passwords with a very short /(t|e|s|t)/ pattern', function () { 52 | var pass = generatePassword(11, false, /(t|e|s|t)/); 53 | expect(pass.length).to.be(11); 54 | expect(pass).to.match(/(t|e|s|t)/); 55 | }); 56 | 57 | 58 | it('should prevent using invalid patterns', function () { 59 | expect(function () { 60 | generatePassword(11, false, /test/); 61 | }).to.throwException(/Could not find characters that match the password pattern/); 62 | }); 63 | 64 | it('should include the lower ASCII characters issue #25', function () { 65 | var pass = generatePassword(100, false, /[Aa]/); 66 | expect(pass.length).to.be(100); 67 | expect(pass).to.match(/A/); 68 | expect(pass).to.match(/a/); 69 | }); 70 | 71 | it('should allow ~ character', function () { 72 | var pass = generatePassword(2, false, /[~]/); 73 | expect(pass.length).to.be(2); 74 | expect(pass).to.be('~~'); 75 | }); 76 | }); 77 | 78 | }(this)); -------------------------------------------------------------------------------- /dist/password-generator.js: -------------------------------------------------------------------------------- 1 | /* 2 | * password-generator 3 | * Copyright(c) 2011-2020 Bermi Ferrer 4 | * MIT Licensed 5 | */ 6 | (function (root) { 7 | 8 | var localName, consonant, letter, password, vowel, rand, getRandomValues; 9 | letter = /[a-z]$/i; 10 | vowel = /[aeiou]$/i; 11 | consonant = /[bcdfghjklmnpqrstvwxyz]$/i; 12 | 13 | 14 | // Defines the name of the local variable the passwordGenerator library will use 15 | // this is specially useful if window.passwordGenerator is already being used 16 | // by your application and you want a different name. For example: 17 | // // Declare before including the passwordGenerator library 18 | // var localPasswordGeneratorLibraryName = 'pass'; 19 | localName = root.localPasswordGeneratorLibraryName || "generatePassword"; 20 | 21 | password = function (length, memorable, pattern, prefix) { 22 | var char = "", n, i, validChars = []; 23 | if (length === null || typeof(length) === "undefined") { 24 | length = 10; 25 | } 26 | if (memorable === null || typeof(memorable) === "undefined") { 27 | memorable = true; 28 | } 29 | if (pattern === null || typeof(pattern) === "undefined") { 30 | pattern = /\w/; 31 | } 32 | if (prefix === null || typeof(prefix) === "undefined") { 33 | prefix = ''; 34 | } 35 | 36 | // Non memorable passwords will pick characters from a pre-generated 37 | // list of characters 38 | if (!memorable) { 39 | for (i = 33; i <= 126; i += 1) { 40 | char = String.fromCharCode(i); 41 | if (char.match(pattern)) { 42 | validChars.push(char); 43 | } 44 | } 45 | 46 | if (!validChars.length) { 47 | throw new Error("Could not find characters that match the " + 48 | "password pattern " + pattern + ". Patterns must match individual " + 49 | "characters, not the password as a whole."); 50 | } 51 | } 52 | 53 | 54 | while (prefix.length < length) { 55 | if (memorable) { 56 | if (prefix.match(consonant)) { 57 | pattern = vowel; 58 | } else { 59 | pattern = consonant; 60 | } 61 | n = rand(33, 126); 62 | char = String.fromCharCode(n); 63 | } else { 64 | char = validChars[rand(0, validChars.length)]; 65 | } 66 | 67 | if (memorable) { 68 | char = char.toLowerCase(); 69 | } 70 | if (char.match(pattern)) { 71 | prefix = "" + prefix + char; 72 | } 73 | } 74 | return prefix; 75 | }; 76 | 77 | 78 | rand = function (min, max) { 79 | var key, value, arr = new Uint8Array(max); 80 | getRandomValues(arr); 81 | for (key in arr) { 82 | if (arr.hasOwnProperty(key)) { 83 | value = arr[key]; 84 | if (value >= min && value < max) { 85 | return value; 86 | } 87 | } 88 | } 89 | return rand(min, max); 90 | }; 91 | 92 | 93 | getRandomValues = function (buf) { 94 | if (root.crypto && root.crypto.getRandomValues) { 95 | root.crypto.getRandomValues(buf); 96 | } else if (typeof root.msCrypto === "object" && typeof root.msCrypto.getRandomValues === 'function') { 97 | root.msCrypto.getRandomValues(buf); 98 | } else if (module.exports === password && typeof require !== "undefined") { 99 | var bytes = require("crypto").randomBytes(buf.length); 100 | buf.set(bytes); 101 | } else { 102 | throw new Error("No secure random number generator available."); 103 | } 104 | }; 105 | 106 | 107 | ((typeof exports !== 'undefined') ? exports : root)[localName] = password; 108 | if (typeof exports !== 'undefined') { 109 | if (typeof module !== 'undefined' && module.exports) { 110 | module.exports = password; 111 | } 112 | } 113 | 114 | // Establish the root object, `window` in the browser, or `global` on the server. 115 | }(this)); 116 | -------------------------------------------------------------------------------- /lib/password-generator.js: -------------------------------------------------------------------------------- 1 | /* 2 | * password-generator 3 | * Copyright(c) 2011-2020 Bermi Ferrer 4 | * MIT Licensed 5 | */ 6 | (function (root) { 7 | 8 | var localName, consonant, letter, password, vowel, rand, getRandomValues; 9 | letter = /[a-z]$/i; 10 | vowel = /[aeiou]$/i; 11 | consonant = /[bcdfghjklmnpqrstvwxyz]$/i; 12 | 13 | 14 | // Defines the name of the local variable the passwordGenerator library will use 15 | // this is specially useful if window.passwordGenerator is already being used 16 | // by your application and you want a different name. For example: 17 | // // Declare before including the passwordGenerator library 18 | // var localPasswordGeneratorLibraryName = 'pass'; 19 | localName = root.localPasswordGeneratorLibraryName || "generatePassword"; 20 | 21 | password = function (length, memorable, pattern, prefix) { 22 | var char = "", n, i, validChars = []; 23 | if (length === null || typeof(length) === "undefined") { 24 | length = 10; 25 | } 26 | if (memorable === null || typeof(memorable) === "undefined") { 27 | memorable = true; 28 | } 29 | if (pattern === null || typeof(pattern) === "undefined") { 30 | pattern = /\w/; 31 | } 32 | if (prefix === null || typeof(prefix) === "undefined") { 33 | prefix = ''; 34 | } 35 | 36 | // Non memorable passwords will pick characters from a pre-generated 37 | // list of characters 38 | if (!memorable) { 39 | for (i = 33; i <= 126; i += 1) { 40 | char = String.fromCharCode(i); 41 | if (char.match(pattern)) { 42 | validChars.push(char); 43 | } 44 | } 45 | 46 | if (!validChars.length) { 47 | throw new Error("Could not find characters that match the " + 48 | "password pattern " + pattern + ". Patterns must match individual " + 49 | "characters, not the password as a whole."); 50 | } 51 | } 52 | 53 | 54 | while (prefix.length < length) { 55 | if (memorable) { 56 | if (prefix.match(consonant)) { 57 | pattern = vowel; 58 | } else { 59 | pattern = consonant; 60 | } 61 | n = rand(33, 126); 62 | char = String.fromCharCode(n); 63 | } else { 64 | char = validChars[rand(0, validChars.length)]; 65 | } 66 | 67 | if (memorable) { 68 | char = char.toLowerCase(); 69 | } 70 | if (char.match(pattern)) { 71 | prefix = "" + prefix + char; 72 | } 73 | } 74 | return prefix; 75 | }; 76 | 77 | 78 | rand = function (min, max) { 79 | var key, value, arr = new Uint8Array(max); 80 | getRandomValues(arr); 81 | for (key in arr) { 82 | if (arr.hasOwnProperty(key)) { 83 | value = arr[key]; 84 | if (value >= min && value < max) { 85 | return value; 86 | } 87 | } 88 | } 89 | return rand(min, max); 90 | }; 91 | 92 | 93 | getRandomValues = function (buf) { 94 | if (root.crypto && root.crypto.getRandomValues) { 95 | root.crypto.getRandomValues(buf); 96 | } else if (typeof root.msCrypto === "object" && typeof root.msCrypto.getRandomValues === 'function') { 97 | root.msCrypto.getRandomValues(buf); 98 | } else if (module.exports === password && typeof require !== "undefined") { 99 | var bytes = require("crypto").randomBytes(buf.length); 100 | buf.set(bytes); 101 | } else { 102 | throw new Error("No secure random number generator available."); 103 | } 104 | }; 105 | 106 | 107 | ((typeof exports !== 'undefined') ? exports : root)[localName] = password; 108 | if (typeof exports !== 'undefined') { 109 | if (typeof module !== 'undefined' && module.exports) { 110 | module.exports = password; 111 | } 112 | } 113 | 114 | // Establish the root object, `window` in the browser, or `global` on the server. 115 | }(this)); 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # password-generator 2 | 3 | Memorable password generator. For the command line, Node.js and browsers. 4 | 5 | 6 | [![Build Status](https://api.travis-ci.org/bermi/password-generator.svg)](http://travis-ci.org/bermi/password-generator) [![Dependency Status](https://david-dm.org/bermi/password-generator.svg)](https://david-dm.org/bermi/password-generator) [![](http://img.shields.io/npm/v/password-generator.svg) ![](http://img.shields.io/npm/dm/password-generator.svg)](https://www.npmjs.org/package/password-generator) 7 | 8 | 9 | ## Installation 10 | 11 | $ npm install password-generator -g 12 | 13 | ## Usage 14 | 15 | ### From the CLI 16 | 17 | password-generator -h 18 | 19 | Displays this help 20 | 21 | Generates a memorable password 22 | 23 | Options: 24 | -l Password length 25 | -c Generates a non memorable password [default: false] 26 | -p Pattern to match for the generated password 27 | -h Displays this help 28 | 29 | Simple memorable pass 30 | 31 | password-generator 32 | => maqetaxaku 33 | 34 | Custom length 35 | 36 | password-generator -l 30 37 | => nugiferagiraqadamedewubaqirali 38 | 39 | Non memorable 40 | 41 | password-generator -c 42 | => QPnb3gl7_0 43 | 44 | Customize the pattern to match for each password character 45 | 46 | password-generator -p "[\d\W\w\p]" 47 | => Je;VgG?{Yd 48 | 49 | Any number or letter 50 | 51 | password-generator -p "[\w]" 52 | => 3NHPqzjIAq 53 | 54 | Combine multiple strategies 6 memorable and 3 numbers 55 | 56 | echo "`password-generator -l 6``password-generator -p "[0-9]" -l 3`" 57 | => wazawe351 58 | 59 | 60 | ### From Node.js 61 | 62 | var generatePassword = require('password-generator'); 63 | 64 | ### From the browser 65 | 66 | 67 | 68 | 69 | ### Browser support 70 | 71 | Since v2.0.0 this library relies on cryptographic random values generated via [`crypto.getRandomValues`](https://developer.mozilla.org/en/docs/Web/API/RandomSource/getRandomValues). IE11 was the first IE version to include this method. Check [caniuse.com](http://caniuse.com/#feat=getrandomvalues) for details. 72 | 73 | ### Usage 74 | 75 | #### Default settings (memorable 10 letters) 76 | 77 | generatePassword() // -> xexeyimahi 78 | 79 | #### Custom length not memorable 80 | 81 | generatePassword(12, false) // -> 76PAGEaq6i5c 82 | 83 | #### Characters should match a pattern 84 | 85 | generatePassword(12, false, /\d/) // -> 252667390298 86 | 87 | #### Customize the password prefix 88 | 89 | generatePassword(12, false, /\d/, 'foo-') // -> foo-67390298 90 | 91 | #### Example with custom validation rules 92 | 93 | Given the pattern regexp can only match a single character 94 | you can build a function that generates multiple passwords until you 95 | hit one that complies with your rules. 96 | 97 | The following example will generate a password with the following requirements 98 | 99 | * Must contain at least two numbers 100 | * Must contain at least three uppercase letters 101 | * Must contain at least three lowercase letters 102 | * Must contain at least two special characters 103 | * Must NOT contain sequences of two or more repeated characters 104 | 105 | 106 | ```javascript 107 | var generatePassword = require("password-generator"); 108 | 109 | var maxLength = 18; 110 | var minLength = 12; 111 | var uppercaseMinCount = 3; 112 | var lowercaseMinCount = 3; 113 | var numberMinCount = 2; 114 | var specialMinCount = 2; 115 | var UPPERCASE_RE = /([A-Z])/g; 116 | var LOWERCASE_RE = /([a-z])/g; 117 | var NUMBER_RE = /([\d])/g; 118 | var SPECIAL_CHAR_RE = /([\?\-])/g; 119 | var NON_REPEATING_CHAR_RE = /([\W\w\d\?\-])\1{2,}/g; 120 | 121 | function isStrongEnough(password) { 122 | var uc = password.match(UPPERCASE_RE); 123 | var lc = password.match(LOWERCASE_RE); 124 | var n = password.match(NUMBER_RE); 125 | var sc = password.match(SPECIAL_CHAR_RE); 126 | var nr = password.match(NON_REPEATING_CHAR_RE); 127 | return password.length >= minLength && 128 | !nr && 129 | uc && uc.length >= uppercaseMinCount && 130 | lc && lc.length >= lowercaseMinCount && 131 | n && n.length >= numberMinCount && 132 | sc && sc.length >= specialMinCount; 133 | } 134 | 135 | function customPassword() { 136 | var password = ""; 137 | var randomLength = Math.floor(Math.random() * (maxLength - minLength)) + minLength; 138 | while (!isStrongEnough(password)) { 139 | password = generatePassword(randomLength, false, /[\w\d\?\-]/); 140 | } 141 | return password; 142 | } 143 | 144 | console.log(customPassword()); // => 2hP5v?1KJNx7_a-W 145 | ``` 146 | 147 | 148 | ## Running tests 149 | 150 | npm install 151 | make test 152 | 153 | ## Building 154 | 155 | npm install 156 | make all 157 | 158 | ## License 159 | 160 | (The MIT License) 161 | 162 | Copyright (c) 2011-2020 Bermi Ferrer <bermi@bermilabs.com> 163 | 164 | Permission is hereby granted, free of charge, to any person obtaining 165 | a copy of this software and associated documentation files (the 166 | 'Software'), to deal in the Software without restriction, including 167 | without limitation the rights to use, copy, modify, merge, publish, 168 | distribute, sublicense, and/or sell copies of the Software, and to 169 | permit persons to whom the Software is furnished to do so, subject to 170 | the following conditions: 171 | 172 | The above copyright notice and this permission notice shall be 173 | included in all copies or substantial portions of the Software. 174 | 175 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 176 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 177 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 178 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 179 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 180 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 181 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 182 | --------------------------------------------------------------------------------