You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					165 lines
				
				6.7 KiB
			
		
		
			
		
	
	
					165 lines
				
				6.7 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								var assert = require('chai').assert,
							 | 
						||
| 
								 | 
							
									_ = require('underscore');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// We use a different require path for code coverage.
							 | 
						||
| 
								 | 
							
								var generator = process.env.JSCOV ? require('../src-cov/generate') : require('../main');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								describe('generate-password', function() {
							 | 
						||
| 
								 | 
							
									describe('generate()', function() {
							 | 
						||
| 
								 | 
							
										it('should accept to be called without the options parameter', function() {
							 | 
						||
| 
								 | 
							
											assert.doesNotThrow(function () {
							 | 
						||
| 
								 | 
							
												generator.generate();
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
										it('should give password of correct length', function() {
							 | 
						||
| 
								 | 
							
											var length = 12;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											var password = generator.generate({length: length});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											assert.equal(password.length, length);
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										it('should generate strict random sequence that is correct length', function() {
							 | 
						||
| 
								 | 
							
											var length = 12;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											var password = generator.generate({length: length, strict: true});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											assert.equal(password.length, length);
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										it('should remove possible similar characters from the sequences', function() {
							 | 
						||
| 
								 | 
							
											var password = generator.generate({length: 10000, excludeSimilarCharacters: true});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											assert.notMatch(password, /[ilLI|`oO0]/, 'password does not contain similar characters');
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										describe('strict mode', function() {
							 | 
						||
| 
								 | 
							
											// Testing randomly generated passwords and entropy isn't perfect,
							 | 
						||
| 
								 | 
							
											// thus in order to get a good sample of whether or not a rule
							 | 
						||
| 
								 | 
							
											// is passing correctly, we generate lots of passwords and check
							 | 
						||
| 
								 | 
							
											// each individually. If we're seeing spotty tests, this number should
							 | 
						||
| 
								 | 
							
											// be increased accordingly.
							 | 
						||
| 
								 | 
							
											var amountToGenerate = 500;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											it('should generate strict random sequence that has strictly at least one number', function() {
							 | 
						||
| 
								 | 
							
												var passwords = generator.generateMultiple(amountToGenerate, {length: 4, strict: true, uppercase: false, numbers: true});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												passwords.forEach(function(password) {
							 | 
						||
| 
								 | 
							
													assert.match(password, /[0-9]/, 'password has a number');
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
												assert.equal(passwords.length, amountToGenerate);
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											it('should generate strict random sequence that has strictly at least one lowercase letter', function() {
							 | 
						||
| 
								 | 
							
												var passwords = generator.generateMultiple(amountToGenerate, {length: 4, strict: true, uppercase: false});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												passwords.forEach(function(password) {
							 | 
						||
| 
								 | 
							
													assert.match(password, /[a-z]/, 'password has a lowercase letter');
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
												assert.equal(passwords.length, amountToGenerate);
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											it('should generate strict random sequence that has strictly at least one uppercase letter', function() {
							 | 
						||
| 
								 | 
							
												var passwords = generator.generateMultiple(amountToGenerate, {length: 4, strict: true, uppercase: true});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												passwords.forEach(function(password) {
							 | 
						||
| 
								 | 
							
													assert.match(password, /[A-Z]/, 'password has an uppercase letter');
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
												assert.equal(passwords.length, amountToGenerate);
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											it('should generate strict random sequence that has strictly at least one special symbol', function() {
							 | 
						||
| 
								 | 
							
												var passwords = generator.generateMultiple(amountToGenerate, {length: 4, strict: true, symbols: true});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												passwords.forEach(function(password) {
							 | 
						||
| 
								 | 
							
													assert.match(password, /[!@#$%^&*()+_\-=}{[\]|:;"/?.><,`~]/, 'password has a symbol');
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
												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 generate strict random sequence that has has no lowercase letter', function () {
							 | 
						||
| 
								 | 
							
												var passwords = generator.generateMultiple(amountToGenerate, { length: 10, strict: true, lowercase: false });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												passwords.forEach(function (password) {
							 | 
						||
| 
								 | 
							
													assert.notMatch(password, /[a-z]/, 'password has no lowercase letters');
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
												assert.equal(passwords.length, amountToGenerate);
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											it('should generate strict random sequence that has strictly at least one lowercase, one symbol, and one uppercase letter', function () {
							 | 
						||
| 
								 | 
							
												var passwords = generator.generateMultiple(amountToGenerate, { length: 10, strict: true, uppercase: true, lowercase: true, symbols: true, numbers: true });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												passwords.forEach(function (password) {
							 | 
						||
| 
								 | 
							
													assert.match(password, /[a-z]/, 'password has a lowercase letter');
							 | 
						||
| 
								 | 
							
													assert.match(password, /[A-Z]/, 'password has a uppercase letter');
							 | 
						||
| 
								 | 
							
													assert.match(password, /[!@#$%^&*()+_\-=}{[\]|:;"/?.><,`~]/, 'password has a symbol');
							 | 
						||
| 
								 | 
							
													assert.match(password, /[0-9]/, 'password has a number');
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
												assert.equal(passwords.length, amountToGenerate);
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											it('should respect explicit list of symbols when provided', function() {
							 | 
						||
| 
								 | 
							
												var passwords = generator.generateMultiple(amountToGenerate, { length: 10, strict: true, symbols: '!', lowercase: true });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												passwords.forEach(function (password) {
							 | 
						||
| 
								 | 
							
													assert.notMatch(password, /[@#$%^&*()+_\-=}{[\]|:;"/?.><,`~]/, 'password does not have default symbols');
							 | 
						||
| 
								 | 
							
													assert.match(password, /[!]/, 'password has provided symbol');
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
												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});
							 | 
						||
| 
								 | 
							
												}, TypeError, 'Length must correlate with strict guidelines');
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											it('should throw an error if no rules are applied', function() {
							 | 
						||
| 
								 | 
							
												assert.throws(function() {
							 | 
						||
| 
								 | 
							
													generator.generate({ length: 10,  uppercase: false, lowercase: false, symbols: false, numbers: false });
							 | 
						||
| 
								 | 
							
												}, TypeError, 'At least one rule for pools must be true');
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											it('should generate short strict passwords without stack overflow', function(){
							 | 
						||
| 
								 | 
							
												assert.doesNotThrow(function() {
							 | 
						||
| 
								 | 
							
													generator.generate({length: 4, strict: true, uppercase: true, numbers: true, symbols: true});
							 | 
						||
| 
								 | 
							
												}, Error);
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
									});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									describe('generateMultiple()', function() {
							 | 
						||
| 
								 | 
							
										it('should accept to be called without the options parameter', function() {
							 | 
						||
| 
								 | 
							
											assert.doesNotThrow(function () {
							 | 
						||
| 
								 | 
							
												generator.generateMultiple(1);
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
										// should give right amount
							 | 
						||
| 
								 | 
							
										it('should give right amount of passwords', function() {
							 | 
						||
| 
								 | 
							
											var amount = 34;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											var passwords = generator.generateMultiple(amount);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											assert.equal(passwords.length, amount);
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// shouldn't give duplicates in pool of 250 (extremely rare)
							 | 
						||
| 
								 | 
							
										it('should not give duplicates in pool', function() {
							 | 
						||
| 
								 | 
							
											var passwords = generator.generateMultiple(250, {length: 10, numbers: true, symbols: true});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											var unique = _.uniq(passwords);
							 | 
						||
| 
								 | 
							
											assert.equal(unique.length, passwords.length);
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
									});
							 | 
						||
| 
								 | 
							
								});
							 |