1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-17 16:53:34 +00:00

[PM-2135] feat: allow user verification to show invalid password error

This commit is contained in:
Andreas Coroiu
2023-05-05 14:30:41 +02:00
parent 1b6722feee
commit f69b42a622
6 changed files with 45 additions and 14 deletions

View File

@@ -3,7 +3,10 @@
<span bitDialogTitle>{{ modalTitle | i18n }}</span> <span bitDialogTitle>{{ modalTitle | i18n }}</span>
<ng-container bitDialogContent> <ng-container bitDialogContent>
<p bitTypography="body1">{{ confirmDescription | i18n }}</p> <p bitTypography="body1">{{ confirmDescription | i18n }}</p>
<app-user-verification formControlName="secret"> </app-user-verification> <app-user-verification
[(invalidSecret)]="invalidSecret"
formControlName="secret"
></app-user-verification>
</ng-container> </ng-container>
<ng-container bitDialogFooter> <ng-container bitDialogFooter>
<button type="submit" bitButton bitFormButton buttonType="primary">Save</button> <button type="submit" bitButton bitFormButton buttonType="primary">Save</button>

View File

@@ -8,7 +8,6 @@ import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
import { DialogServiceAbstraction } from "../../../../../../libs/angular/src/services/dialog"; import { DialogServiceAbstraction } from "../../../../../../libs/angular/src/services/dialog";
export interface UserVerificationPromptParams { export interface UserVerificationPromptParams {

View File

@@ -2658,6 +2658,12 @@
"failedLogin2fa": { "failedLogin2fa": {
"message": "Login attempt failed with incorrect two-step login." "message": "Login attempt failed with incorrect two-step login."
}, },
"incorrectPassword": {
"message": "Incorrect password"
},
"incorrectCode": {
"message": "Incorrect code"
},
"exportedVault": { "exportedVault": {
"message": "Vault exported" "message": "Vault exported"
}, },

View File

@@ -22,6 +22,8 @@ export class UserVerificationPromptComponent {
secret: this.formBuilder.control<Verification | null>(null), secret: this.formBuilder.control<Verification | null>(null),
}); });
protected invalidSecret = false;
constructor( constructor(
private modalRef: ModalRef, private modalRef: ModalRef,
protected config: ModalConfig, protected config: ModalConfig,
@@ -45,7 +47,9 @@ export class UserVerificationPromptComponent {
try { try {
//Incorrect secret will throw an invalid password error. //Incorrect secret will throw an invalid password error.
await this.userVerificationService.verifyUser(this.secret.value); await this.userVerificationService.verifyUser(this.secret.value);
this.invalidSecret = false;
} catch (e) { } catch (e) {
this.invalidSecret = true;
this.platformUtilsService.showToast( this.platformUtilsService.showToast(
"error", "error",
this.i18nService.t("error"), this.i18nService.t("error"),

View File

@@ -1,6 +1,7 @@
import { Directive, OnInit } from "@angular/core"; import { Directive, EventEmitter, Input, OnInit, Output } from "@angular/core";
import { ControlValueAccessor, FormControl, Validators } from "@angular/forms"; import { ControlValueAccessor, FormControl, Validators } from "@angular/forms";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service"; import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service";
import { VerificationType } from "@bitwarden/common/auth/enums/verification-type"; import { VerificationType } from "@bitwarden/common/auth/enums/verification-type";
@@ -18,17 +19,39 @@ import { Verification } from "@bitwarden/common/types/verification";
}) })
// eslint-disable-next-line rxjs-angular/prefer-takeuntil // eslint-disable-next-line rxjs-angular/prefer-takeuntil
export class UserVerificationComponent implements ControlValueAccessor, OnInit { export class UserVerificationComponent implements ControlValueAccessor, OnInit {
private _invalidSecret = false;
@Input()
get invalidSecret() {
return this._invalidSecret;
}
set invalidSecret(value: boolean) {
this._invalidSecret = value;
this.invalidSecretChange.emit(value);
this.secret.updateValueAndValidity({ emitEvent: false });
}
@Output() invalidSecretChange = new EventEmitter<boolean>();
usesKeyConnector = false; usesKeyConnector = false;
disableRequestOTP = false; disableRequestOTP = false;
sentCode = false; sentCode = false;
secret = new FormControl("", [Validators.required]); secret = new FormControl("", [
Validators.required,
() => {
if (this.invalidSecret) {
return {
invalidSecret: { message: this.i18nService.t("incorrectPassword") },
};
}
},
]);
private onChange: (value: Verification) => void; private onChange: (value: Verification) => void;
constructor( constructor(
private keyConnectorService: KeyConnectorService, private keyConnectorService: KeyConnectorService,
private userVerificationService: UserVerificationService private userVerificationService: UserVerificationService,
private i18nService: I18nService
) {} ) {}
async ngOnInit() { async ngOnInit() {
@@ -72,7 +95,9 @@ export class UserVerificationComponent implements ControlValueAccessor, OnInit {
} }
} }
private processChanges(secret: string) { protected processChanges(secret: string) {
this.invalidSecret = false;
if (this.onChange == null) { if (this.onChange == null) {
return; return;
} }

View File

@@ -78,15 +78,9 @@ export class BitInputDirective implements BitFormFieldControl {
return this.id; return this.id;
} }
private isActive = true;
@HostListener("blur")
onBlur() {
this.isActive = true;
}
@HostListener("input") @HostListener("input")
onInput() { onInput() {
this.isActive = false; this.ngControl?.control?.markAsUntouched();
} }
get hasError() { get hasError() {
@@ -97,7 +91,7 @@ export class BitInputDirective implements BitFormFieldControl {
this.ngControl?.errors != null this.ngControl?.errors != null
); );
} else { } else {
return this.ngControl?.status === "INVALID" && this.ngControl?.touched && this.isActive; return this.ngControl?.status === "INVALID" && this.ngControl?.touched;
} }
} }