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:
@@ -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>
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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"),
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user