mirror of
https://github.com/bitwarden/browser.git
synced 2025-02-05 23:41:28 +01:00
Password Generator Passphrase Policy (#85)
* Initial commit for passphrase enforcement * Updated type implementation * Updated default type conditional * Added helper method to enforced options object Co-authored-by: Vincent Salucci <vsalucci@bitwarden.com>
This commit is contained in:
parent
44b86f5dd0
commit
ee8ca0beed
@ -19,7 +19,6 @@ export class PasswordGeneratorComponent implements OnInit {
|
||||
password: string = '-';
|
||||
showOptions = false;
|
||||
avoidAmbiguous = false;
|
||||
policyInEffect = false;
|
||||
enforcedPolicyOptions: PasswordGeneratorPolicyOptions;
|
||||
|
||||
constructor(protected passwordGenerationService: PasswordGenerationService,
|
||||
@ -30,14 +29,6 @@ export class PasswordGeneratorComponent implements OnInit {
|
||||
const optionsResponse = await this.passwordGenerationService.getOptions();
|
||||
this.options = optionsResponse[0];
|
||||
this.enforcedPolicyOptions = optionsResponse[1];
|
||||
this.policyInEffect = this.enforcedPolicyOptions != null && (
|
||||
this.enforcedPolicyOptions.minLength > 0 ||
|
||||
this.enforcedPolicyOptions.numberCount > 0 ||
|
||||
this.enforcedPolicyOptions.specialCount > 0 ||
|
||||
this.enforcedPolicyOptions.useUppercase ||
|
||||
this.enforcedPolicyOptions.useLowercase ||
|
||||
this.enforcedPolicyOptions.useNumbers ||
|
||||
this.enforcedPolicyOptions.useSpecial);
|
||||
this.avoidAmbiguous = !this.options.ambiguous;
|
||||
this.options.type = this.options.type === 'passphrase' ? 'passphrase' : 'password';
|
||||
this.password = await this.passwordGenerationService.generatePassword(this.options);
|
||||
@ -147,6 +138,10 @@ export class PasswordGeneratorComponent implements OnInit {
|
||||
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];
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import Domain from './domainBase';
|
||||
|
||||
export class PasswordGeneratorPolicyOptions extends Domain {
|
||||
defaultType: string = '';
|
||||
minLength: number = 0;
|
||||
useUppercase: boolean = false;
|
||||
useLowercase: boolean = false;
|
||||
@ -8,4 +9,21 @@ export class PasswordGeneratorPolicyOptions extends Domain {
|
||||
numberCount: number = 0;
|
||||
useSpecial: boolean = false;
|
||||
specialCount: number = 0;
|
||||
minNumberWords: number = 0;
|
||||
capitalize: boolean = false;
|
||||
includeNumber: boolean = false;
|
||||
|
||||
inEffect() {
|
||||
return this.defaultType !== '' ||
|
||||
this.minLength > 0 ||
|
||||
this.numberCount > 0 ||
|
||||
this.specialCount > 0 ||
|
||||
this.useUppercase ||
|
||||
this.useLowercase ||
|
||||
this.useNumbers ||
|
||||
this.useSpecial ||
|
||||
this.minNumberWords > 0 ||
|
||||
this.capitalize ||
|
||||
this.includeNumber;
|
||||
}
|
||||
}
|
||||
|
@ -262,6 +262,24 @@ export class PasswordGenerationService implements PasswordGenerationServiceAbstr
|
||||
if (options.minSpecial + options.minNumber > options.length) {
|
||||
options.minSpecial = options.length - options.minNumber;
|
||||
}
|
||||
|
||||
if (options.numWords < enforcedPolicyOptions.minNumberWords) {
|
||||
options.numWords = enforcedPolicyOptions.minNumberWords;
|
||||
}
|
||||
|
||||
if (enforcedPolicyOptions.capitalize) {
|
||||
options.capitalize = true;
|
||||
}
|
||||
|
||||
if (enforcedPolicyOptions.includeNumber) {
|
||||
options.includeNumber = true;
|
||||
}
|
||||
|
||||
// Force default type if password/passphrase selected via policy
|
||||
if (enforcedPolicyOptions.defaultType === 'password' ||
|
||||
enforcedPolicyOptions.defaultType === 'passphrase') {
|
||||
options.type = enforcedPolicyOptions.defaultType;
|
||||
}
|
||||
} else { // UI layer expects an instantiated object to prevent more explicit null checks
|
||||
enforcedPolicyOptions = new PasswordGeneratorPolicyOptions();
|
||||
}
|
||||
@ -285,6 +303,11 @@ export class PasswordGenerationService implements PasswordGenerationServiceAbstr
|
||||
enforcedOptions = new PasswordGeneratorPolicyOptions();
|
||||
}
|
||||
|
||||
// Password wins in multi-org collisions
|
||||
if (currentPolicy.data.defaultType != null && enforcedOptions.defaultType !== 'password') {
|
||||
enforcedOptions.defaultType = currentPolicy.data.defaultType;
|
||||
}
|
||||
|
||||
if (currentPolicy.data.minLength != null
|
||||
&& currentPolicy.data.minLength > enforcedOptions.minLength) {
|
||||
enforcedOptions.minLength = currentPolicy.data.minLength;
|
||||
@ -315,6 +338,19 @@ export class PasswordGenerationService implements PasswordGenerationServiceAbstr
|
||||
&& currentPolicy.data.minSpecial > enforcedOptions.specialCount) {
|
||||
enforcedOptions.specialCount = currentPolicy.data.minSpecial;
|
||||
}
|
||||
|
||||
if (currentPolicy.data.minNumberWords != null
|
||||
&& currentPolicy.data.minNumberWords > enforcedOptions.minNumberWords) {
|
||||
enforcedOptions.minNumberWords = currentPolicy.data.minNumberWords;
|
||||
}
|
||||
|
||||
if (currentPolicy.data.capitalize) {
|
||||
enforcedOptions.capitalize = true;
|
||||
}
|
||||
|
||||
if (currentPolicy.data.includeNumber) {
|
||||
enforcedOptions.includeNumber = true;
|
||||
}
|
||||
});
|
||||
|
||||
return enforcedOptions;
|
||||
|
Loading…
Reference in New Issue
Block a user