1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-07 12:13:45 +00:00

feat(change-password-component): Change Password Update [18720] - Pausing work for now while we wait for product to hear back.

This commit is contained in:
Patrick Pimentel
2025-05-23 14:30:46 -04:00
parent 913b7ec5d6
commit 0be93fa65f
8 changed files with 49 additions and 32 deletions

View File

@@ -1177,7 +1177,7 @@
"message": "After changing your password, you will need to log in with your new password. Active sessions on other devices will be logged out within one hour."
},
"accountRecoveryUpdateMasterPasswordSubtitle": {
"message": "Admins have recovered your account. Change you master password to continue."
"message": "Change your master password to complete account recovery."
},
"enableChangedPasswordNotification": {
"message": "Ask to update existing login"

View File

@@ -342,9 +342,6 @@ const routes: Routes = [
component: ChangePasswordComponent,
},
],
data: {
showBackButton: true,
} satisfies ExtensionAnonLayoutWrapperData,
},
],
},

View File

@@ -154,6 +154,9 @@ const routes: Routes = [
component: ChangePasswordComponent,
},
],
data: {
hideFooter: true,
} satisfies AnonLayoutWrapperData,
},
],
data: { titleId: "updatePassword" } satisfies RouteDataProperties,
@@ -164,7 +167,7 @@ const routes: Routes = [
canActivate: [
canAccessFeature(
FeatureFlag.PM16117_ChangeExistingPasswordRefactor,
false,
true,
"change-password",
false,
),

View File

@@ -6057,7 +6057,7 @@
"message": "Update master password"
},
"accountRecoveryUpdateMasterPasswordSubtitle": {
"message": "Admins have recovered your account. Change you master password to continue."
"message": "Change your master password to complete account recovery."
},
"updateMasterPasswordSubtitle": {
"message": "Your master password does not meet this organizations requirements. Change your master password to continue."

View File

@@ -10,13 +10,22 @@
[flow]="inputPasswordFlow"
[email]="email"
[userId]="activeUserId"
[forceSetPasswordReason]="forceSetPasswordReason"
[loading]="submitting"
[masterPasswordPolicyOptions]="masterPasswordPolicyOptions"
[inlineButtons]="true"
[primaryButtonText]="{ key: 'changeMasterPassword' }"
(onPasswordFormSubmit)="handlePasswordFormSubmit($event)"
[secondaryButtonText]="{ key: 'cancel' }"
[secondaryButtonText]="
this.forceSetPasswordReason === ForceSetPasswordReason.AdminForcePasswordReset ||
this.forceSetPasswordReason === ForceSetPasswordReason.WeakMasterPassword
? { key: 'logOut' }
: undefined
"
(onSecondaryButtonClick)="logOut()"
[showChangePasswordWarning]="
this.forceSetPasswordReason !== ForceSetPasswordReason.AdminForcePasswordReset
"
>
</auth-input-password>
}

View File

@@ -7,6 +7,7 @@ import { Account, AccountService } from "@bitwarden/common/auth/abstractions/acc
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { SyncService } from "@bitwarden/common/platform/sync";
import { UserId } from "@bitwarden/common/types/guid";
@@ -33,7 +34,7 @@ export class ChangePasswordComponent implements OnInit {
@Input() inputPasswordFlow: InputPasswordFlow = InputPasswordFlow.ChangePassword;
activeAccount: Account | null = null;
email?: string;
email!: string;
activeUserId?: UserId;
masterPasswordPolicyOptions?: MasterPasswordPolicyOptions;
initializing = true;
@@ -53,6 +54,7 @@ export class ChangePasswordComponent implements OnInit {
private toastService: ToastService,
private syncService: SyncService,
private dialogService: DialogService,
private logService: LogService,
) {}
async ngOnInit() {
@@ -83,8 +85,6 @@ export class ChangePasswordComponent implements OnInit {
pageIcon: LockIcon,
pageTitle: { key: "updateMasterPassword" },
pageSubtitle: { key: "accountRecoveryUpdateMasterPasswordSubtitle" },
hideFooter: true,
maxWidth: "lg",
});
} else if (this.forceSetPasswordReason === ForceSetPasswordReason.WeakMasterPassword) {
this.anonLayoutWrapperDataService.setAnonLayoutWrapperData({
@@ -153,7 +153,8 @@ export class ChangePasswordComponent implements OnInit {
this.messagingService.send("logout");
}
} catch {
} catch (error) {
this.logService.error(error);
this.toastService.showToast({
variant: "error",
title: "",
@@ -163,4 +164,6 @@ export class ChangePasswordComponent implements OnInit {
this.submitting = false;
}
}
protected readonly ForceSetPasswordReason = ForceSetPasswordReason;
}

View File

@@ -1,17 +1,14 @@
<form [formGroup]="formGroup" [bitSubmit]="submit">
<bit-callout type="warning">{{ "changePasswordWarning" | i18n }}</bit-callout>
<bit-callout *ngIf="showChangePasswordWarning" type="warning">{{
"changePasswordWarning" | i18n
}}</bit-callout>
<auth-password-callout
*ngIf="masterPasswordPolicyOptions"
[policy]="masterPasswordPolicyOptions"
></auth-password-callout>
<bit-form-field
*ngIf="
flow === InputPasswordFlow.ChangePassword ||
flow === InputPasswordFlow.ChangePasswordWithOptionalUserKeyRotation
"
>
<bit-form-field *ngIf="isChangePasswordFlow()">
<bit-label>{{ "currentMasterPass" | i18n }}</bit-label>
<input
id="input-password-form_current-password"

View File

@@ -1,5 +1,5 @@
import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core";
import { ReactiveFormsModule, FormBuilder, Validators, FormControl } from "@angular/forms";
import { FormBuilder, FormControl, ReactiveFormsModule, Validators } from "@angular/forms";
import { firstValueFrom } from "rxjs";
import { JslibModule } from "@bitwarden/angular/jslib.module";
@@ -10,6 +10,7 @@ import {
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
import { MasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@@ -66,6 +67,8 @@ export enum InputPasswordFlow {
ChangePassword,
/**
* All form elements above, plus: [Checkbox] Rotate account encryption key (as the last element in the UI)
*
* Consider changing this to an input.
*/
ChangePasswordWithOptionalUserKeyRotation,
}
@@ -108,7 +111,8 @@ export class InputPasswordComponent implements OnInit {
@Input() userId?: UserId;
@Input() loading = false;
@Input() masterPasswordPolicyOptions: MasterPasswordPolicyOptions | null = null;
@Input() masterPasswordPolicyOptions: MasterPasswordPolicyOptions | undefined = undefined;
@Input() forceSetPasswordReason?: ForceSetPasswordReason;
@Input() inlineButtons = false;
@Input() primaryButtonText?: Translation;
@@ -116,6 +120,8 @@ export class InputPasswordComponent implements OnInit {
@Input() secondaryButtonText?: Translation;
protected secondaryButtonTextStr: string = "";
@Input() showChangePasswordWarning: boolean = true;
protected InputPasswordFlow = InputPasswordFlow;
private kdfConfig: KdfConfig | null = null;
private minHintLength = 0;
@@ -188,10 +194,7 @@ export class InputPasswordComponent implements OnInit {
}
private addFormFieldsIfNecessary() {
if (
this.flow === InputPasswordFlow.ChangePassword ||
this.flow === InputPasswordFlow.ChangePasswordWithOptionalUserKeyRotation
) {
if (this.isChangePasswordFlow()) {
this.formGroup.addControl(
"currentPassword",
this.formBuilder.nonNullable.control("", Validators.required),
@@ -262,10 +265,7 @@ export class InputPasswordComponent implements OnInit {
}
// 2. Verify current password is correct (if necessary)
if (
this.flow === InputPasswordFlow.ChangePassword ||
this.flow === InputPasswordFlow.ChangePasswordWithOptionalUserKeyRotation
) {
if (this.isChangePasswordFlow()) {
const currentPasswordVerified = await this.verifyCurrentPassword(
currentPassword,
this.kdfConfig,
@@ -313,10 +313,7 @@ export class InputPasswordComponent implements OnInit {
kdfConfig: this.kdfConfig,
};
if (
this.flow === InputPasswordFlow.ChangePassword ||
this.flow === InputPasswordFlow.ChangePasswordWithOptionalUserKeyRotation
) {
if (this.isChangePasswordFlow()) {
const currentMasterKey = await this.keyService.makeMasterKey(
currentPassword,
this.email,
@@ -550,4 +547,15 @@ export class InputPasswordComponent implements OnInit {
protected getPasswordStrengthScore(score: PasswordStrengthScore) {
this.passwordStrengthScore = score;
}
/**
* Checks if the flow is either ChangePassword or ChangePasswordWithOptionalUserKeyRotation
* @private
*/
protected isChangePasswordFlow(): boolean {
return (
this.flow === InputPasswordFlow.ChangePassword ||
this.flow === InputPasswordFlow.ChangePasswordWithOptionalUserKeyRotation
);
}
}