2015-10-19 23:24:32 +02:00
|
|
|
'use strict';
|
|
|
|
|
2016-02-15 22:06:11 +01:00
|
|
|
var kdbxweb = require('kdbxweb'),
|
|
|
|
phonetic = require('./phonetic');
|
2015-10-19 23:24:32 +02:00
|
|
|
|
|
|
|
var PasswordGenerator = {
|
|
|
|
charRanges: {
|
|
|
|
upper: 'ABCDEFGHJKLMNPQRSTUVWXYZ',
|
|
|
|
lower: 'abcdefghijkmnpqrstuvwxyz',
|
2015-10-20 19:17:15 +02:00
|
|
|
digits: '123456789',
|
2015-10-19 23:24:32 +02:00
|
|
|
special: '!@#$%^&*_+-=,./?;:`"~\'\\',
|
2015-10-20 19:17:15 +02:00
|
|
|
brackets: '(){}[]<>',
|
2015-10-19 23:24:32 +02:00
|
|
|
high: '¡¢£¤¥¦§©ª«¬®¯°±²³´µ¶¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ',
|
2015-10-20 19:17:15 +02:00
|
|
|
ambiguous: 'O0oIl'
|
2015-10-19 23:24:32 +02:00
|
|
|
},
|
2016-02-15 22:06:11 +01:00
|
|
|
|
2015-10-19 23:24:32 +02:00
|
|
|
generate: function(opts) {
|
|
|
|
if (!opts || typeof opts.length !== 'number' || opts.length < 0) {
|
|
|
|
return '';
|
|
|
|
}
|
2016-02-15 22:06:11 +01:00
|
|
|
switch (opts.name) {
|
|
|
|
case 'Pronounceable':
|
|
|
|
return this.generatePronounceable(opts);
|
|
|
|
case 'Hash128':
|
|
|
|
return this.generateHash(32);
|
|
|
|
case 'Hash256':
|
|
|
|
return this.generateHash(64);
|
|
|
|
case 'Mac':
|
|
|
|
return this.generateMac();
|
|
|
|
}
|
2015-10-19 23:24:32 +02:00
|
|
|
var ranges = Object.keys(this.charRanges)
|
2016-07-17 13:30:38 +02:00
|
|
|
.filter(r => opts[r])
|
2015-10-19 23:24:32 +02:00
|
|
|
.map(function(r) { return this.charRanges[r]; }, this);
|
2016-08-14 18:18:51 +02:00
|
|
|
if (opts.include && opts.include.length) {
|
|
|
|
ranges.push(opts.include);
|
|
|
|
}
|
2015-10-19 23:24:32 +02:00
|
|
|
if (!ranges.length) {
|
|
|
|
return '';
|
|
|
|
}
|
2015-10-20 19:17:15 +02:00
|
|
|
var randomBytes = kdbxweb.Random.getBytes(opts.length);
|
|
|
|
var chars = [];
|
|
|
|
for (var i = 0; i < opts.length; i++) {
|
|
|
|
var range = ranges[i % ranges.length];
|
|
|
|
var rand = Math.round(Math.random() * 1000) + randomBytes[i];
|
|
|
|
chars.push(range[rand % range.length]);
|
2015-10-19 23:24:32 +02:00
|
|
|
}
|
2015-10-20 19:17:15 +02:00
|
|
|
return _.shuffle(chars).join('');
|
2015-10-25 10:44:19 +01:00
|
|
|
},
|
2016-02-15 22:06:11 +01:00
|
|
|
|
|
|
|
generateMac: function() {
|
|
|
|
var segmentsCount = 6;
|
|
|
|
var randomBytes = kdbxweb.Random.getBytes(segmentsCount);
|
|
|
|
var result = '';
|
|
|
|
for (var i = 0; i < segmentsCount; i++) {
|
|
|
|
var segment = randomBytes[i].toString(16).toUpperCase();
|
|
|
|
if (segment.length < 2) {
|
|
|
|
segment = '0' + segment;
|
|
|
|
}
|
|
|
|
result += (result ? '-' : '') + segment;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
},
|
|
|
|
|
|
|
|
generateHash: function(length) {
|
|
|
|
var randomBytes = kdbxweb.Random.getBytes(length);
|
|
|
|
var result = '';
|
|
|
|
for (var i = 0; i < length; i++) {
|
|
|
|
result += randomBytes[i].toString(16)[0];
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
},
|
|
|
|
|
|
|
|
generatePronounceable: function(opts) {
|
|
|
|
var pass = phonetic.generate({ length: opts.length });
|
|
|
|
var result = '';
|
|
|
|
var upper = [];
|
|
|
|
var i;
|
|
|
|
if (opts.upper) {
|
|
|
|
for (i = 0; i < pass.length; i += 8) {
|
|
|
|
upper.push(Math.floor(Math.random() * opts.length));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (i = 0; i < pass.length; i++) {
|
|
|
|
var ch = pass[i];
|
|
|
|
if (upper.indexOf(i) >= 0) {
|
|
|
|
ch = ch.toUpperCase();
|
|
|
|
}
|
|
|
|
result += ch;
|
|
|
|
}
|
|
|
|
return result.substr(0, opts.length);
|
|
|
|
},
|
|
|
|
|
|
|
|
deriveOpts: function(password) {
|
|
|
|
var opts = {};
|
|
|
|
var length = 0;
|
|
|
|
if (password) {
|
|
|
|
var charRanges = this.charRanges;
|
2016-07-17 13:30:38 +02:00
|
|
|
password.forEachChar(ch => {
|
2016-02-15 22:06:11 +01:00
|
|
|
length++;
|
|
|
|
ch = String.fromCharCode(ch);
|
2016-07-17 13:30:38 +02:00
|
|
|
_.forEach(charRanges, (chars, range) => {
|
2016-02-15 22:06:11 +01:00
|
|
|
if (chars.indexOf(ch) >= 0) {
|
|
|
|
opts[range] = true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
opts.length = length;
|
|
|
|
return opts;
|
|
|
|
},
|
|
|
|
|
2015-10-25 10:44:19 +01:00
|
|
|
present: function(length) {
|
|
|
|
return new Array(length + 1).join('•');
|
2015-10-19 23:24:32 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = PasswordGenerator;
|