mirror of
https://github.com/bitwarden/browser
synced 2026-02-08 20:50:28 +00:00
fix(change-password-component): Change Password Update [18720] - Putting a pause on it for now while other work gets done so I can properly hook into it.
This commit is contained in:
@@ -39,6 +39,7 @@ import {
|
||||
TwoFactorAuthGuard,
|
||||
NewDeviceVerificationComponent,
|
||||
DeviceVerificationIcon,
|
||||
ChangePasswordComponent,
|
||||
} from "@bitwarden/auth/angular";
|
||||
import { LockComponent } from "@bitwarden/key-management-ui";
|
||||
import {
|
||||
@@ -63,8 +64,8 @@ import { AccountComponent } from "./auth/settings/account/account.component";
|
||||
import { EmergencyAccessComponent } from "./auth/settings/emergency-access/emergency-access.component";
|
||||
import { EmergencyAccessViewComponent } from "./auth/settings/emergency-access/view/emergency-access-view.component";
|
||||
import { SecurityRoutingModule } from "./auth/settings/security/security-routing.module";
|
||||
import { UpdatePasswordComponent } from "./auth/update-password.component";
|
||||
import { UpdateTempPasswordComponent } from "./auth/update-temp-password.component";
|
||||
// import { UpdatePasswordComponent } from "./auth/update-password.component";
|
||||
// import { UpdateTempPasswordComponent } from "./auth/update-temp-password.component";
|
||||
import { VerifyEmailTokenComponent } from "./auth/verify-email-token.component";
|
||||
import { VerifyRecoverDeleteComponent } from "./auth/verify-recover-delete.component";
|
||||
import { SponsoredFamiliesComponent } from "./billing/settings/sponsored-families.component";
|
||||
@@ -145,17 +146,62 @@ const routes: Routes = [
|
||||
data: { titleId: "deleteOrganization" },
|
||||
},
|
||||
{
|
||||
path: "update-temp-password",
|
||||
component: UpdateTempPasswordComponent,
|
||||
canActivate: [authGuard],
|
||||
data: { titleId: "updateTempPassword" } satisfies RouteDataProperties,
|
||||
path: "",
|
||||
component: AnonLayoutWrapperComponent,
|
||||
children: [
|
||||
{
|
||||
path: "update-temp-password",
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
component: ChangePasswordComponent,
|
||||
},
|
||||
],
|
||||
data: {
|
||||
pageIcon: undefined,
|
||||
hideFooter: true,
|
||||
} satisfies AnonLayoutWrapperData,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "update-password",
|
||||
component: UpdatePasswordComponent,
|
||||
canActivate: [authGuard],
|
||||
component: AnonLayoutWrapperComponent,
|
||||
path: "",
|
||||
children: [
|
||||
{
|
||||
path: "update-password",
|
||||
canActivate: [authGuard],
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
component: ChangePasswordComponent,
|
||||
},
|
||||
],
|
||||
data: {
|
||||
pageIcon: undefined,
|
||||
hideFooter: true,
|
||||
} satisfies AnonLayoutWrapperData,
|
||||
},
|
||||
],
|
||||
data: { titleId: "updatePassword" } satisfies RouteDataProperties,
|
||||
},
|
||||
// {
|
||||
// path: "update-temp-password",
|
||||
// component: ChangePasswordComponent,
|
||||
// data: {}
|
||||
// },
|
||||
// {
|
||||
// path: "update-temp-password",
|
||||
// component: UpdateTempPasswordComponent,
|
||||
// canActivate: [authGuard],
|
||||
// data: { titleId: "updateTempPassword" } satisfies RouteDataProperties,
|
||||
// },
|
||||
// {
|
||||
// path: "update-password",
|
||||
// component: UpdatePasswordComponent,
|
||||
// canActivate: [authGuard],
|
||||
// data: { titleId: "updatePassword" } satisfies RouteDataProperties,
|
||||
// },
|
||||
{
|
||||
path: "migrate-legacy-encryption",
|
||||
loadComponent: () =>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[showReadonlyHostname]="showReadonlyHostname"
|
||||
[maxWidth]="maxWidth"
|
||||
[titleAreaMaxWidth]="titleAreaMaxWidth"
|
||||
[hideFooter]="hideFooter"
|
||||
>
|
||||
<router-outlet></router-outlet>
|
||||
<router-outlet slot="secondary" name="secondary"></router-outlet>
|
||||
|
||||
@@ -39,6 +39,11 @@ export interface AnonLayoutWrapperData {
|
||||
* Optional flag to set the max-width of the title area. Defaults to null if not provided.
|
||||
*/
|
||||
titleAreaMaxWidth?: "md";
|
||||
|
||||
/**
|
||||
* Optional flag to hide the whole footer.
|
||||
*/
|
||||
hideFooter?: boolean;
|
||||
}
|
||||
|
||||
@Component({
|
||||
@@ -55,6 +60,7 @@ export class AnonLayoutWrapperComponent implements OnInit, OnDestroy {
|
||||
protected showReadonlyHostname: boolean;
|
||||
protected maxWidth: "md" | "3xl";
|
||||
protected titleAreaMaxWidth: "md";
|
||||
protected hideFooter: boolean;
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
@@ -106,6 +112,7 @@ export class AnonLayoutWrapperComponent implements OnInit, OnDestroy {
|
||||
this.showReadonlyHostname = Boolean(firstChildRouteData["showReadonlyHostname"]);
|
||||
this.maxWidth = firstChildRouteData["maxWidth"];
|
||||
this.titleAreaMaxWidth = firstChildRouteData["titleAreaMaxWidth"];
|
||||
this.hideFooter = Boolean(firstChildRouteData["hideFooter"]);
|
||||
}
|
||||
|
||||
private listenForServiceDataChanges() {
|
||||
|
||||
@@ -9,11 +9,13 @@
|
||||
<auth-input-password
|
||||
[flow]="inputPasswordFlow"
|
||||
[email]="email"
|
||||
[userId]="userId"
|
||||
[userId]="activeUserId"
|
||||
[masterPasswordPolicyOptions]="masterPasswordPolicyOptions"
|
||||
[inlineButtons]="true"
|
||||
[primaryButtonText]="{ key: 'changeMasterPassword' }"
|
||||
(onPasswordFormSubmit)="handlePasswordFormSubmit($event)"
|
||||
[secondaryButtonText]="secondaryButtonText"
|
||||
(onSecondaryButtonClick)="performSecondaryAction()"
|
||||
>
|
||||
</auth-input-password>
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { Component, Input, OnInit } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
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 { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { MasterPasswordApiService } from "@bitwarden/common/auth/abstractions/master-password-api.service.abstraction";
|
||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||
import { PasswordRequest } from "@bitwarden/common/auth/models/request/password.request";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction";
|
||||
@@ -15,9 +17,13 @@ import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||
import { SyncService } from "@bitwarden/common/platform/sync";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { UserKey } from "@bitwarden/common/types/key";
|
||||
import { ToastService } from "@bitwarden/components";
|
||||
import { DialogService, ToastService, Translation } from "@bitwarden/components";
|
||||
import { KeyService } from "@bitwarden/key-management";
|
||||
import { I18nPipe } from "@bitwarden/ui-common";
|
||||
// import {
|
||||
// AcceptOrganizationInviteService
|
||||
// } from "@bitwarden/web-vault/src/app/auth/organization-invite/accept-organization.service";
|
||||
// import { RouterService } from "@bitwarden/web-vault/src/app/core";
|
||||
|
||||
import {
|
||||
InputPasswordComponent,
|
||||
@@ -38,11 +44,13 @@ export class ChangePasswordComponent implements OnInit {
|
||||
|
||||
activeAccount: Account | null = null;
|
||||
email?: string;
|
||||
userId?: UserId;
|
||||
activeUserId?: UserId;
|
||||
masterPasswordPolicyOptions?: MasterPasswordPolicyOptions;
|
||||
initializing = true;
|
||||
userkeyRotationV2 = false;
|
||||
formPromise?: Promise<any>;
|
||||
secondaryButtonText?: Translation = undefined;
|
||||
forceSetPasswordReason: ForceSetPasswordReason = ForceSetPasswordReason.None;
|
||||
|
||||
constructor(
|
||||
private accountService: AccountService,
|
||||
@@ -56,26 +64,75 @@ export class ChangePasswordComponent implements OnInit {
|
||||
private policyService: PolicyService,
|
||||
private toastService: ToastService,
|
||||
private syncService: SyncService,
|
||||
// private routerService: RouterService,
|
||||
// private acceptOrganizationInviteService: AcceptOrganizationInviteService,
|
||||
private dialogService: DialogService,
|
||||
private router: Router,
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.userkeyRotationV2 = await this.configService.getFeatureFlag(FeatureFlag.UserKeyRotationV2);
|
||||
|
||||
this.activeAccount = await firstValueFrom(this.accountService.activeAccount$);
|
||||
this.userId = this.activeAccount?.id;
|
||||
this.activeUserId = this.activeAccount?.id;
|
||||
this.email = this.activeAccount?.email;
|
||||
|
||||
if (!this.userId) {
|
||||
if (!this.activeUserId) {
|
||||
throw new Error("userId not found");
|
||||
}
|
||||
|
||||
this.masterPasswordPolicyOptions = await firstValueFrom(
|
||||
this.policyService.masterPasswordPolicyOptions$(this.userId),
|
||||
this.policyService.masterPasswordPolicyOptions$(this.activeUserId),
|
||||
);
|
||||
|
||||
this.forceSetPasswordReason = await firstValueFrom(
|
||||
this.masterPasswordService.forceSetPasswordReason$(this.activeUserId),
|
||||
);
|
||||
|
||||
if (
|
||||
this.forceSetPasswordReason === ForceSetPasswordReason.AdminForcePasswordReset ||
|
||||
this.forceSetPasswordReason === ForceSetPasswordReason.WeakMasterPassword
|
||||
) {
|
||||
this.secondaryButtonText = { key: "cancel" };
|
||||
} else {
|
||||
this.secondaryButtonText = undefined;
|
||||
}
|
||||
|
||||
this.initializing = false;
|
||||
}
|
||||
|
||||
async performSecondaryAction() {
|
||||
if (
|
||||
this.forceSetPasswordReason === ForceSetPasswordReason.AdminForcePasswordReset ||
|
||||
this.forceSetPasswordReason === ForceSetPasswordReason.WeakMasterPassword
|
||||
) {
|
||||
await this.logOut();
|
||||
} else {
|
||||
await this.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
async logOut() {
|
||||
const confirmed = await this.dialogService.openSimpleDialog({
|
||||
title: { key: "logOut" },
|
||||
content: { key: "logOutConfirmation" },
|
||||
acceptButtonText: { key: "logOut" },
|
||||
type: "warning",
|
||||
});
|
||||
|
||||
if (confirmed) {
|
||||
this.messagingService.send("logout");
|
||||
}
|
||||
}
|
||||
|
||||
async cancel() {
|
||||
// clearing the login redirect url so that the user
|
||||
// does not join the organization if they cancel
|
||||
// await this.routerService.getAndClearLoginRedirectUrl();
|
||||
// await this.acceptOrganizationInviteService.clearOrganizationInvitation();
|
||||
// await this.router.navigate(["/vault"]);
|
||||
}
|
||||
|
||||
async handlePasswordFormSubmit(passwordInputResult: PasswordInputResult) {
|
||||
if (this.userkeyRotationV2) {
|
||||
await this.submitNew(passwordInputResult);
|
||||
@@ -104,11 +161,11 @@ export class ChangePasswordComponent implements OnInit {
|
||||
passwordInputResult.newPasswordHint,
|
||||
);
|
||||
} else {
|
||||
if (!this.userId) {
|
||||
if (!this.activeUserId) {
|
||||
throw new Error("userId not found");
|
||||
}
|
||||
|
||||
await this.changePasswordService.changePassword(passwordInputResult, this.userId);
|
||||
await this.changePasswordService.changePassword(passwordInputResult, this.activeUserId);
|
||||
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
@@ -128,7 +185,7 @@ export class ChangePasswordComponent implements OnInit {
|
||||
}
|
||||
|
||||
private async submitOld(passwordInputResult: PasswordInputResult) {
|
||||
if (!this.userId) {
|
||||
if (!this.activeUserId) {
|
||||
throw new Error("userId not found");
|
||||
}
|
||||
|
||||
@@ -165,11 +222,11 @@ export class ChangePasswordComponent implements OnInit {
|
||||
// we need to save this for local masterkey verification during rotation
|
||||
await this.masterPasswordService.setMasterKeyHash(
|
||||
passwordInputResult.newLocalMasterKeyHash,
|
||||
this.userId as UserId,
|
||||
this.activeUserId as UserId,
|
||||
);
|
||||
await this.masterPasswordService.setMasterKey(
|
||||
passwordInputResult.newMasterKey,
|
||||
this.userId as UserId,
|
||||
this.activeUserId as UserId,
|
||||
);
|
||||
return this.updateKey(passwordInputResult.newPassword);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user