mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 00:33:44 +00:00
[PM-13876] replace angular validation with html constraints validation (#11816)
* rough-in passphrase validation failure handling * trigger valid change from settings * fix `max` constraint enforcement * add taps for generator validation monitoring/debugging * HTML constraints validation rises like a phoenix * remove min/max boundaries to fix chrome display issue * bind settings components as view children of options components * remove defunct `okSettings$` * extend validationless generator to passwords * extend validationless generator to catchall emails * extend validationless generator to forwarder emails * extend validationless generator to subaddress emails * extend validationless generator to usernames * fix observable cycle * disable generate button when no algorithm is selected * prevent duplicate algorithm emissions * add constraints that assign email address defaults
This commit is contained in:
@@ -22,11 +22,11 @@ import { Option } from "@bitwarden/components/src/select/option";
|
||||
import {
|
||||
CredentialGeneratorService,
|
||||
Generators,
|
||||
PasswordAlgorithm,
|
||||
GeneratedCredential,
|
||||
CredentialAlgorithm,
|
||||
isPasswordAlgorithm,
|
||||
AlgorithmInfo,
|
||||
isSameAlgorithm,
|
||||
} from "@bitwarden/generator-core";
|
||||
import { GeneratorHistoryService } from "@bitwarden/generator-history";
|
||||
|
||||
@@ -57,7 +57,7 @@ export class PasswordGeneratorComponent implements OnInit, OnDestroy {
|
||||
@Input({ transform: coerceBooleanProperty }) disableMargin = false;
|
||||
|
||||
/** tracks the currently selected credential type */
|
||||
protected credentialType$ = new BehaviorSubject<PasswordAlgorithm>(null);
|
||||
protected credentialType$ = new BehaviorSubject<CredentialAlgorithm>(null);
|
||||
|
||||
/** Emits the last generated value. */
|
||||
protected readonly value$ = new BehaviorSubject<string>("");
|
||||
@@ -72,14 +72,14 @@ export class PasswordGeneratorComponent implements OnInit, OnDestroy {
|
||||
* @param requestor a label used to trace generation request
|
||||
* origin in the debugger.
|
||||
*/
|
||||
protected generate(requestor: string) {
|
||||
protected async generate(requestor: string) {
|
||||
this.generate$.next(requestor);
|
||||
}
|
||||
|
||||
/** Tracks changes to the selected credential type
|
||||
* @param type the new credential type
|
||||
*/
|
||||
protected onCredentialTypeChanged(type: PasswordAlgorithm) {
|
||||
protected onCredentialTypeChanged(type: CredentialAlgorithm) {
|
||||
// break subscription cycle
|
||||
if (this.credentialType$.value !== type) {
|
||||
this.zone.run(() => {
|
||||
@@ -169,29 +169,34 @@ export class PasswordGeneratorComponent implements OnInit, OnDestroy {
|
||||
preferences.next(preference);
|
||||
});
|
||||
|
||||
// populate the form with the user's preferences to kick off interactivity
|
||||
preferences.pipe(takeUntil(this.destroyed)).subscribe(({ password }) => {
|
||||
// update navigation
|
||||
this.onCredentialTypeChanged(password.algorithm);
|
||||
|
||||
// load algorithm metadata
|
||||
const algorithm = this.generatorService.algorithm(password.algorithm);
|
||||
|
||||
// update subjects within the angular zone so that the
|
||||
// template bindings refresh immediately
|
||||
this.zone.run(() => {
|
||||
this.algorithm$.next(algorithm);
|
||||
});
|
||||
});
|
||||
|
||||
// generate on load unless the generator prohibits it
|
||||
this.algorithm$
|
||||
// update active algorithm
|
||||
preferences
|
||||
.pipe(
|
||||
distinctUntilChanged((prev, next) => prev.id === next.id),
|
||||
filter((a) => !a.onlyOnRequest),
|
||||
map(({ password }) => this.generatorService.algorithm(password.algorithm)),
|
||||
distinctUntilChanged((prev, next) => isSameAlgorithm(prev?.id, next?.id)),
|
||||
takeUntil(this.destroyed),
|
||||
)
|
||||
.subscribe(() => this.generate("autogenerate"));
|
||||
.subscribe((algorithm) => {
|
||||
// update navigation
|
||||
this.onCredentialTypeChanged(algorithm.id);
|
||||
|
||||
// update subjects within the angular zone so that the
|
||||
// template bindings refresh immediately
|
||||
this.zone.run(() => {
|
||||
this.algorithm$.next(algorithm);
|
||||
});
|
||||
});
|
||||
|
||||
// generate on load unless the generator prohibits it
|
||||
this.algorithm$.pipe(takeUntil(this.destroyed)).subscribe((a) => {
|
||||
this.zone.run(() => {
|
||||
if (!a || a.onlyOnRequest) {
|
||||
this.value$.next("-");
|
||||
} else {
|
||||
this.generate("autogenerate").catch((e: unknown) => this.logService.error(e));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private typeToGenerator$(type: CredentialAlgorithm) {
|
||||
|
||||
Reference in New Issue
Block a user