mirror of
https://github.com/bitwarden/browser
synced 2025-12-11 22:03:36 +00:00
[PM-252] fix inconsistent generator configuration behavior (#6755)
* decompose password generator policy enforcement * integrate new logic with UI * improve UX of minimum password length * improve password generator policy options documentation * initialize min length to default minimum length boundary * reset form value on input to prevent UI desync from model --------- Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { Directive, EventEmitter, Input, OnInit, Output } from "@angular/core";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { first } from "rxjs/operators";
|
||||
import { BehaviorSubject } from "rxjs";
|
||||
import { debounceTime, first, map } from "rxjs/operators";
|
||||
|
||||
import { PasswordGeneratorPolicyOptions } from "@bitwarden/common/admin-console/models/domain/password-generator-policy-options";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
@@ -12,6 +13,7 @@ import {
|
||||
PasswordGenerationServiceAbstraction,
|
||||
PasswordGeneratorOptions,
|
||||
} from "@bitwarden/common/tools/generator/password";
|
||||
import { DefaultBoundaries } from "@bitwarden/common/tools/generator/password/password-generator-options-evaluator";
|
||||
import {
|
||||
UsernameGenerationServiceAbstraction,
|
||||
UsernameGeneratorOptions,
|
||||
@@ -40,6 +42,16 @@ export class GeneratorComponent implements OnInit {
|
||||
enforcedPasswordPolicyOptions: PasswordGeneratorPolicyOptions;
|
||||
usernameWebsite: string = null;
|
||||
|
||||
// update screen reader minimum password length with 500ms debounce
|
||||
// so that the user isn't flooded with status updates
|
||||
private _passwordOptionsMinLengthForReader = new BehaviorSubject<number>(
|
||||
DefaultBoundaries.length.min,
|
||||
);
|
||||
protected passwordOptionsMinLengthForReader$ = this._passwordOptionsMinLengthForReader.pipe(
|
||||
map((val) => val || DefaultBoundaries.length.min),
|
||||
debounceTime(500),
|
||||
);
|
||||
|
||||
constructor(
|
||||
protected passwordGenerationService: PasswordGenerationServiceAbstraction,
|
||||
protected usernameGenerationService: UsernameGenerationServiceAbstraction,
|
||||
@@ -144,6 +156,44 @@ export class GeneratorComponent implements OnInit {
|
||||
await this.passwordGenerationService.addHistory(this.password);
|
||||
}
|
||||
|
||||
async onPasswordOptionsMinNumberInput($event: Event) {
|
||||
// `savePasswordOptions()` replaces the null
|
||||
this.passwordOptions.number = null;
|
||||
|
||||
await this.savePasswordOptions();
|
||||
|
||||
// fixes UI desync that occurs when minNumber has a fixed value
|
||||
// that is reset through normalization
|
||||
($event.target as HTMLInputElement).value = `${this.passwordOptions.minNumber}`;
|
||||
}
|
||||
|
||||
async setPasswordOptionsNumber($event: boolean) {
|
||||
this.passwordOptions.number = $event;
|
||||
// `savePasswordOptions()` replaces the null
|
||||
this.passwordOptions.minNumber = null;
|
||||
|
||||
await this.savePasswordOptions();
|
||||
}
|
||||
|
||||
async onPasswordOptionsMinSpecialInput($event: Event) {
|
||||
// `savePasswordOptions()` replaces the null
|
||||
this.passwordOptions.special = null;
|
||||
|
||||
await this.savePasswordOptions();
|
||||
|
||||
// fixes UI desync that occurs when minSpecial has a fixed value
|
||||
// that is reset through normalization
|
||||
($event.target as HTMLInputElement).value = `${this.passwordOptions.minSpecial}`;
|
||||
}
|
||||
|
||||
async setPasswordOptionsSpecial($event: boolean) {
|
||||
this.passwordOptions.special = $event;
|
||||
// `savePasswordOptions()` replaces the null
|
||||
this.passwordOptions.minSpecial = null;
|
||||
|
||||
await this.savePasswordOptions();
|
||||
}
|
||||
|
||||
async sliderInput() {
|
||||
this.normalizePasswordOptions();
|
||||
this.password = await this.passwordGenerationService.generatePassword(this.passwordOptions);
|
||||
@@ -240,6 +290,8 @@ export class GeneratorComponent implements OnInit {
|
||||
this.passwordOptions,
|
||||
this.enforcedPasswordPolicyOptions,
|
||||
);
|
||||
|
||||
this._passwordOptionsMinLengthForReader.next(this.passwordOptions.minLength);
|
||||
}
|
||||
|
||||
private async initForwardOptions() {
|
||||
|
||||
Reference in New Issue
Block a user