1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-11 05:53:42 +00:00

[PM-18721] add ChangePasswordDelegation flow to InputPasswordComponent

This commit is contained in:
rr-bw
2025-05-04 20:20:47 -07:00
parent c20b99730b
commit 1e22cb51a3
5 changed files with 68 additions and 32 deletions

View File

@@ -9,7 +9,7 @@
"emergencyAccessLoggedOutWarning" | i18n: dialogData.grantorName
}}</bit-callout>
<auth-change-password></auth-change-password>
<auth-change-password [inputPasswordFlow]="inputPasswordFlow"></auth-change-password>
</div>
<ng-container bitDialogFooter>

View File

@@ -1,7 +1,7 @@
import { CommonModule } from "@angular/common";
import { Component, Inject } from "@angular/core";
import { ChangePasswordComponent } from "@bitwarden/auth/angular";
import { ChangePasswordComponent, InputPasswordFlow } from "@bitwarden/auth/angular";
import {
ButtonModule,
CalloutModule,
@@ -46,6 +46,8 @@ export enum EmergencyAccessTakeoverDialogResultType {
],
})
export class EmergencyAccessTakeoverDialogComponent {
inputPasswordFlow = InputPasswordFlow.ChangePasswordDelegation;
constructor(@Inject(DIALOG_DATA) protected dialogData: EmergencyAccessTakeoverDialogData) {}
/**

View File

@@ -42,7 +42,7 @@
bitPasswordInputToggle
[(toggled)]="showPassword"
></button>
<bit-hint>
<bit-hint *ngIf="flow !== InputPasswordFlow.ChangePasswordDelegation">
<span class="tw-font-bold">{{ "important" | i18n }} </span>
{{ "masterPassImportant" | i18n }}
{{ minPasswordLengthMsg }}.
@@ -74,26 +74,32 @@
></button>
</bit-form-field>
<bit-form-field>
<bit-label>{{ "masterPassHintLabel" | i18n }}</bit-label>
<input id="input-password-form_new-password-hint" bitInput formControlName="newPasswordHint" />
<bit-hint>
{{
"masterPassHintText"
| i18n: formGroup.value.newPasswordHint.length : maxHintLength.toString()
}}
</bit-hint>
</bit-form-field>
<ng-container *ngIf="flow !== InputPasswordFlow.ChangePasswordDelegation">
<bit-form-field>
<bit-label>{{ "masterPassHintLabel" | i18n }}</bit-label>
<input
id="input-password-form_new-password-hint"
bitInput
formControlName="newPasswordHint"
/>
<bit-hint>
{{
"masterPassHintText"
| i18n: formGroup.value.newPasswordHint.length : maxHintLength.toString()
}}
</bit-hint>
</bit-form-field>
<bit-form-control>
<input
id="input-password-form_check-for-breaches"
type="checkbox"
bitCheckbox
formControlName="checkForBreaches"
/>
<bit-label>{{ "checkForBreaches" | i18n }}</bit-label>
</bit-form-control>
<bit-form-control>
<input
id="input-password-form_check-for-breaches"
type="checkbox"
bitCheckbox
formControlName="checkForBreaches"
/>
<bit-label>{{ "checkForBreaches" | i18n }}</bit-label>
</bit-form-control>
</ng-container>
<bit-form-control *ngIf="flow === InputPasswordFlow.ChangePasswordWithOptionalUserKeyRotation">
<input

View File

@@ -56,6 +56,10 @@ export enum InputPasswordFlow {
* Form elements displayed:
* - [Input] New password
* - [Input] New password confirm
*/
ChangePasswordDelegation,
/**
* All form elements above, plus:
* - [Input] New password hint
* - [Checkbox] Check for breaches
*/
@@ -74,9 +78,9 @@ export enum InputPasswordFlow {
interface InputPasswordForm {
newPassword: FormControl<string>;
newPasswordConfirm: FormControl<string>;
newPasswordHint: FormControl<string>;
checkForBreaches: FormControl<boolean>;
newPasswordHint?: FormControl<string>;
checkForBreaches?: FormControl<boolean>;
currentPassword?: FormControl<string>;
rotateUserKey?: FormControl<boolean>;
}
@@ -147,12 +151,6 @@ export class InputPasswordComponent implements OnInit {
"newPasswordConfirm",
this.i18nService.t("masterPassDoesntMatch"),
),
compareInputs(
ValidationGoal.InputsShouldNotMatch,
"newPassword",
"newPasswordHint",
this.i18nService.t("hintEqualsPassword"),
),
],
},
);
@@ -188,6 +186,26 @@ export class InputPasswordComponent implements OnInit {
}
private addFormFieldsIfNecessary() {
if (this.flow !== InputPasswordFlow.ChangePasswordDelegation) {
this.formGroup.addControl(
"newPasswordHint",
new FormControl("", [
Validators.minLength(this.minHintLength),
Validators.maxLength(this.maxHintLength),
]) as FormControl<string>,
);
this.formGroup.addControl("checkForBreaches", new FormControl(true) as FormControl<boolean>);
this.formGroup.addValidators([
compareInputs(
ValidationGoal.InputsShouldNotMatch,
"newPassword",
"newPasswordHint",
this.i18nService.t("hintEqualsPassword"),
),
]);
}
if (
this.flow === InputPasswordFlow.ChangePassword ||
this.flow === InputPasswordFlow.ChangePasswordWithOptionalUserKeyRotation
@@ -244,8 +262,8 @@ export class InputPasswordComponent implements OnInit {
const currentPassword = this.formGroup.controls.currentPassword?.value ?? "";
const newPassword = this.formGroup.controls.newPassword.value;
const newPasswordHint = this.formGroup.controls.newPasswordHint.value;
const checkForBreaches = this.formGroup.controls.checkForBreaches.value;
const newPasswordHint = this.formGroup.controls.newPasswordHint?.value ?? "";
const checkForBreaches = this.formGroup.controls.checkForBreaches?.value ?? true;
// 1. Determine kdfConfig
if (this.flow === InputPasswordFlow.AccountRegistration) {

View File

@@ -130,6 +130,7 @@ export default {
],
args: {
InputPasswordFlow: {
ChangePasswordDelegation: InputPasswordFlow.ChangePasswordDelegation,
AccountRegistration: InputPasswordFlow.AccountRegistration,
SetInitialPasswordAuthedUser: InputPasswordFlow.SetInitialPasswordAuthedUser,
ChangePassword: InputPasswordFlow.ChangePassword,
@@ -154,6 +155,15 @@ export default {
type Story = StoryObj<InputPasswordComponent>;
export const ChangePasswordDelegation: Story = {
render: (args) => ({
props: args,
template: `
<auth-input-password [flow]="InputPasswordFlow.ChangePasswordDelegation"></auth-input-password>
`,
}),
};
export const AccountRegistration: Story = {
render: (args) => ({
props: args,