fix #1774: password generator now includes all selected character ranges

This commit is contained in:
antelle 2021-04-01 21:54:42 +02:00
parent 68010076f9
commit 58a85eabdf
No known key found for this signature in database
GPG Key ID: 63C9777AAB7C563C
3 changed files with 41 additions and 4 deletions

View File

@ -1,5 +1,6 @@
import kdbxweb from 'kdbxweb';
import { phonetic } from 'util/generators/phonetic';
import { shuffle } from 'util/fn';
const CharRanges = {
upper: 'ABCDEFGHJKLMNPQRSTUVWXYZ',
@ -41,18 +42,33 @@ const PasswordGenerator = {
}
const rangesByPatternChar = {
...DefaultCharRangesByPattern,
'X': ranges.join(''),
'I': opts.include || ''
};
const pattern = opts.pattern || 'X';
const rangeIxRandomBytes = kdbxweb.Random.getBytes(opts.length);
const rangeCharRandomBytes = kdbxweb.Random.getBytes(opts.length);
const defaultRangeGeneratedChars = [];
for (let i = 0; i < opts.length; i++) {
const rangeIx = i < ranges.length ? i : rangeIxRandomBytes[i] % ranges.length;
const range = ranges[rangeIx];
const char = range[rangeCharRandomBytes[i] % range.length];
defaultRangeGeneratedChars.push(char);
}
shuffle(defaultRangeGeneratedChars);
const randomBytes = kdbxweb.Random.getBytes(opts.length);
const chars = [];
for (let i = 0; i < opts.length; i++) {
const rand = Math.round(Math.random() * 1000) + randomBytes[i];
const patternChar = pattern[i % pattern.length];
const range = rangesByPatternChar[patternChar];
const char = range ? range[rand % range.length] : patternChar;
chars.push(char);
if (patternChar === 'X') {
chars.push(defaultRangeGeneratedChars.pop());
} else {
const range = rangesByPatternChar[patternChar];
const char = range ? range[rand % range.length] : patternChar;
chars.push(char);
}
}
return chars.join('');
},

View File

@ -4,6 +4,7 @@ Release notes
`+` optimized memory consumption for large files
`+` option to use short-lived tokens in cloud storages
`+` opening XML and CSV files using the Open button
`*` password generator now includes all selected character ranges
`-` legacy auto-type removed
##### v1.17.5 (2021-03-27)

View File

@ -57,4 +57,24 @@ describe('PasswordGenerator', () => {
})
).to.match(/^([A-Z][a-z][0-9][0-9A-Z@#][@#]-){10}$/);
});
it('should include all groups of characters at least once', () => {
for (let i = 0; i < 10; i++) {
const password = PasswordGenerator.generate({
length: 6,
upper: true,
lower: true,
digits: true,
brackets: true,
special: true,
ambiguous: true
});
expect(password).to.match(/[A-Z]/);
expect(password).to.match(/[a-z]/);
expect(password).to.match(/[0-9]/);
expect(password).to.match(/[(){}[\]<>]/);
expect(password).to.match(/[!-\/:-@[-`~]/);
expect(password).to.match(/[O0oIl]/);
}
});
});