Password Generator Sanitize Length (#89)
* Initial commit for length sanitization * Updated sanitize function * Updated type instantiation Co-authored-by: Vincent Salucci <vsalucci@bitwarden.com>
This commit is contained in:
parent
0a30c7eb1e
commit
3ad546c39f
|
@ -12,4 +12,5 @@ export abstract class PasswordGenerationService {
|
|||
addHistory: (password: string) => Promise<any>;
|
||||
clear: () => Promise<any>;
|
||||
passwordStrength: (password: string, userInputs?: string[]) => zxcvbn.ZXCVBNResult;
|
||||
normalizeOptions: (options: any, enforcedPolicyOptions: PasswordGeneratorPolicyOptions) => void;
|
||||
}
|
||||
|
|
|
@ -80,8 +80,7 @@ export class PasswordGeneratorComponent implements OnInit {
|
|||
}
|
||||
|
||||
private normalizeOptions() {
|
||||
this.options.minLowercase = 0;
|
||||
this.options.minUppercase = 0;
|
||||
// Application level normalize options depedent on class variables
|
||||
this.options.ambiguous = !this.avoidAmbiguous;
|
||||
|
||||
if (!this.options.uppercase && !this.options.lowercase && !this.options.number && !this.options.special) {
|
||||
|
@ -94,56 +93,6 @@ export class PasswordGeneratorComponent implements OnInit {
|
|||
}
|
||||
}
|
||||
|
||||
if (!this.options.length || this.options.length < 5) {
|
||||
this.options.length = 5;
|
||||
} else if (this.options.length > 128) {
|
||||
this.options.length = 128;
|
||||
}
|
||||
|
||||
if (this.options.length < this.enforcedPolicyOptions.minLength) {
|
||||
this.options.length = this.enforcedPolicyOptions.minLength;
|
||||
}
|
||||
|
||||
if (!this.options.minNumber) {
|
||||
this.options.minNumber = 0;
|
||||
} else if (this.options.minNumber > this.options.length) {
|
||||
this.options.minNumber = this.options.length;
|
||||
} else if (this.options.minNumber > 9) {
|
||||
this.options.minNumber = 9;
|
||||
}
|
||||
|
||||
if (this.options.minNumber < this.enforcedPolicyOptions.numberCount) {
|
||||
this.options.minNumber = this.enforcedPolicyOptions.numberCount;
|
||||
}
|
||||
|
||||
if (!this.options.minSpecial) {
|
||||
this.options.minSpecial = 0;
|
||||
} else if (this.options.minSpecial > this.options.length) {
|
||||
this.options.minSpecial = this.options.length;
|
||||
} else if (this.options.minSpecial > 9) {
|
||||
this.options.minSpecial = 9;
|
||||
}
|
||||
|
||||
if (this.options.minSpecial < this.enforcedPolicyOptions.specialCount) {
|
||||
this.options.minSpecial = this.enforcedPolicyOptions.specialCount;
|
||||
}
|
||||
|
||||
if (this.options.minSpecial + this.options.minNumber > this.options.length) {
|
||||
this.options.minSpecial = this.options.length - this.options.minNumber;
|
||||
}
|
||||
|
||||
if (this.options.numWords == null || this.options.length < 3) {
|
||||
this.options.numWords = 3;
|
||||
} else if (this.options.numWords > 20) {
|
||||
this.options.numWords = 20;
|
||||
}
|
||||
|
||||
if (this.options.numWords < this.enforcedPolicyOptions.minNumberWords) {
|
||||
this.options.numWords = this.enforcedPolicyOptions.minNumberWords;
|
||||
}
|
||||
|
||||
if (this.options.wordSeparator != null && this.options.wordSeparator.length > 1) {
|
||||
this.options.wordSeparator = this.options.wordSeparator[0];
|
||||
}
|
||||
this.passwordGenerationService.normalizeOptions(this.options, this.enforcedPolicyOptions);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,33 +57,7 @@ export class PasswordGenerationService implements PasswordGenerationServiceAbstr
|
|||
}
|
||||
|
||||
// sanitize
|
||||
if (o.uppercase && o.minUppercase <= 0) {
|
||||
o.minUppercase = 1;
|
||||
} else if (!o.uppercase) {
|
||||
o.minUppercase = 0;
|
||||
}
|
||||
|
||||
if (o.lowercase && o.minLowercase <= 0) {
|
||||
o.minLowercase = 1;
|
||||
} else if (!o.lowercase) {
|
||||
o.minLowercase = 0;
|
||||
}
|
||||
|
||||
if (o.number && o.minNumber <= 0) {
|
||||
o.minNumber = 1;
|
||||
} else if (!o.number) {
|
||||
o.minNumber = 0;
|
||||
}
|
||||
|
||||
if (o.special && o.minSpecial <= 0) {
|
||||
o.minSpecial = 1;
|
||||
} else if (!o.special) {
|
||||
o.minSpecial = 0;
|
||||
}
|
||||
|
||||
if (!o.length || o.length < 1) {
|
||||
o.length = 10;
|
||||
}
|
||||
this.sanitizePasswordLength(o, true);
|
||||
|
||||
const minLength: number = o.minUppercase + o.minLowercase + o.minNumber + o.minSpecial;
|
||||
if (o.length < minLength) {
|
||||
|
@ -419,6 +393,65 @@ export class PasswordGenerationService implements PasswordGenerationServiceAbstr
|
|||
return result;
|
||||
}
|
||||
|
||||
normalizeOptions(options: any, enforcedPolicyOptions: PasswordGeneratorPolicyOptions) {
|
||||
options.minLowercase = 0;
|
||||
options.minUppercase = 0;
|
||||
|
||||
if (!options.length || options.length < 5) {
|
||||
options.length = 5;
|
||||
} else if (options.length > 128) {
|
||||
options.length = 128;
|
||||
}
|
||||
|
||||
if (options.length < enforcedPolicyOptions.minLength) {
|
||||
options.length = enforcedPolicyOptions.minLength;
|
||||
}
|
||||
|
||||
if (!options.minNumber) {
|
||||
options.minNumber = 0;
|
||||
} else if (options.minNumber > options.length) {
|
||||
options.minNumber = options.length;
|
||||
} else if (options.minNumber > 9) {
|
||||
options.minNumber = 9;
|
||||
}
|
||||
|
||||
if (options.minNumber < enforcedPolicyOptions.numberCount) {
|
||||
options.minNumber = enforcedPolicyOptions.numberCount;
|
||||
}
|
||||
|
||||
if (!options.minSpecial) {
|
||||
options.minSpecial = 0;
|
||||
} else if (options.minSpecial > options.length) {
|
||||
options.minSpecial = options.length;
|
||||
} else if (options.minSpecial > 9) {
|
||||
options.minSpecial = 9;
|
||||
}
|
||||
|
||||
if (options.minSpecial < enforcedPolicyOptions.specialCount) {
|
||||
options.minSpecial = enforcedPolicyOptions.specialCount;
|
||||
}
|
||||
|
||||
if (options.minSpecial + options.minNumber > options.length) {
|
||||
options.minSpecial = options.length - options.minNumber;
|
||||
}
|
||||
|
||||
if (options.numWords == null || options.length < 3) {
|
||||
options.numWords = 3;
|
||||
} else if (options.numWords > 20) {
|
||||
options.numWords = 20;
|
||||
}
|
||||
|
||||
if (options.numWords < enforcedPolicyOptions.minNumberWords) {
|
||||
options.numWords = enforcedPolicyOptions.minNumberWords;
|
||||
}
|
||||
|
||||
if (options.wordSeparator != null && options.wordSeparator.length > 1) {
|
||||
options.wordSeparator = options.wordSeparator[0];
|
||||
}
|
||||
|
||||
this.sanitizePasswordLength(options, false);
|
||||
}
|
||||
|
||||
private capitalize(str: string) {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
}
|
||||
|
@ -473,4 +506,54 @@ export class PasswordGenerationService implements PasswordGenerationServiceAbstr
|
|||
[array[i], array[j]] = [array[j], array[i]];
|
||||
}
|
||||
}
|
||||
|
||||
private sanitizePasswordLength(options: any, forGeneration: boolean) {
|
||||
let minUppercaseCalc = 0;
|
||||
let minLowercaseCalc = 0;
|
||||
let minNumberCalc: number = options.minNumber;
|
||||
let minSpecialCalc: number = options.minSpecial;
|
||||
|
||||
if (options.uppercase && options.minUppercase <= 0) {
|
||||
minUppercaseCalc = 1;
|
||||
} else if (!options.uppercase) {
|
||||
minUppercaseCalc = 0;
|
||||
}
|
||||
|
||||
if (options.lowercase && options.minLowercase <= 0) {
|
||||
minLowercaseCalc = 1;
|
||||
} else if (!options.lowercase) {
|
||||
minLowercaseCalc = 0;
|
||||
}
|
||||
|
||||
if (options.number && options.minNumber <= 0) {
|
||||
minNumberCalc = 1;
|
||||
} else if (!options.number) {
|
||||
minNumberCalc = 0;
|
||||
}
|
||||
|
||||
if (options.special && options.minSpecial <= 0) {
|
||||
minSpecialCalc = 1;
|
||||
} else if (!options.special) {
|
||||
minSpecialCalc = 0;
|
||||
}
|
||||
|
||||
// This should never happen but is a final safety net
|
||||
if (!options.length || options.length < 1) {
|
||||
options.length = 10;
|
||||
}
|
||||
|
||||
const minLength: number = minUppercaseCalc + minLowercaseCalc + minNumberCalc + minSpecialCalc;
|
||||
// Normalize and Generation both require this modification
|
||||
if (options.length < minLength) {
|
||||
options.length = minLength;
|
||||
}
|
||||
|
||||
// Apply other changes if the options object passed in is for generation
|
||||
if (forGeneration) {
|
||||
options.minUppercase = minUppercaseCalc;
|
||||
options.minLowercase = minLowercaseCalc;
|
||||
options.minNumber = minNumberCalc;
|
||||
options.minSpecial = minSpecialCalc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue