From ca5c6a9c3250f943d88e0766c9de314ca35b37dd Mon Sep 17 00:00:00 2001 From: Jake Fink Date: Wed, 2 Feb 2022 23:31:37 -0500 Subject: [PATCH] Master password policy is not checked when accepting invite from an existing account (#597) * create update-password component * linting and prettier --- .../components/update-password.component.ts | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 angular/src/components/update-password.component.ts diff --git a/angular/src/components/update-password.component.ts b/angular/src/components/update-password.component.ts new file mode 100644 index 0000000000..909831c502 --- /dev/null +++ b/angular/src/components/update-password.component.ts @@ -0,0 +1,130 @@ +import { Directive } from "@angular/core"; +import { Router } from "@angular/router"; + +import { ApiService } from "jslib-common/abstractions/api.service"; +import { CryptoService } from "jslib-common/abstractions/crypto.service"; +import { I18nService } from "jslib-common/abstractions/i18n.service"; +import { LogService } from "jslib-common/abstractions/log.service"; +import { MessagingService } from "jslib-common/abstractions/messaging.service"; +import { PasswordGenerationService } from "jslib-common/abstractions/passwordGeneration.service"; +import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service"; +import { PolicyService } from "jslib-common/abstractions/policy.service"; +import { StateService } from "jslib-common/abstractions/state.service"; +import { UserVerificationService } from "jslib-common/abstractions/userVerification.service"; + +import { ChangePasswordComponent as BaseChangePasswordComponent } from "./change-password.component"; + +import { EncString } from "jslib-common/models/domain/encString"; +import { MasterPasswordPolicyOptions } from "jslib-common/models/domain/masterPasswordPolicyOptions"; +import { PasswordRequest } from "jslib-common/models/request/passwordRequest"; + +import { VerificationType } from "jslib-common/enums/verificationType"; +import { Verification } from "jslib-common/types/verification"; + +import { SymmetricCryptoKey } from "jslib-common/models/domain/symmetricCryptoKey"; + +@Directive() +export class UpdatePasswordComponent extends BaseChangePasswordComponent { + hint: string; + key: string; + enforcedPolicyOptions: MasterPasswordPolicyOptions; + showPassword: boolean = false; + currentMasterPassword: string; + + onSuccessfulChangePassword: () => Promise; + + constructor( + protected router: Router, + i18nService: I18nService, + platformUtilsService: PlatformUtilsService, + passwordGenerationService: PasswordGenerationService, + policyService: PolicyService, + cryptoService: CryptoService, + messagingService: MessagingService, + private apiService: ApiService, + stateService: StateService, + private userVerificationService: UserVerificationService, + private logService: LogService + ) { + super( + i18nService, + cryptoService, + messagingService, + passwordGenerationService, + platformUtilsService, + policyService, + stateService + ); + } + + togglePassword(confirmField: boolean) { + this.showPassword = !this.showPassword; + document.getElementById(confirmField ? "masterPasswordRetype" : "masterPassword").focus(); + } + + async cancel() { + await this.stateService.setOrganizationInvitation(null); + await this.stateService.setLoginRedirect(null); + this.router.navigate(["/vault"]); + } + + async setupSubmitActions(): Promise { + if (this.currentMasterPassword == null || this.currentMasterPassword === "") { + this.platformUtilsService.showToast( + "error", + this.i18nService.t("errorOccurred"), + this.i18nService.t("masterPassRequired") + ); + return false; + } + + const secret: Verification = { + type: VerificationType.MasterPassword, + secret: this.currentMasterPassword, + }; + try { + await this.userVerificationService.verifyUser(secret); + } catch (e) { + this.platformUtilsService.showToast("error", this.i18nService.t("errorOccurred"), e.message); + return false; + } + + this.kdf = await this.stateService.getKdfType(); + this.kdfIterations = await this.stateService.getKdfIterations(); + return true; + } + + async performSubmitActions( + masterPasswordHash: string, + key: SymmetricCryptoKey, + encKey: [SymmetricCryptoKey, EncString] + ) { + try { + // Create Request + const request = new PasswordRequest(); + request.masterPasswordHash = await this.cryptoService.hashPassword( + this.currentMasterPassword, + null + ); + request.newMasterPasswordHash = masterPasswordHash; + request.key = encKey[1].encryptedString; + + // Update user's password + this.apiService.postPassword(request); + + this.platformUtilsService.showToast( + "success", + this.i18nService.t("masterPasswordChanged"), + this.i18nService.t("logBackIn") + ); + + if (this.onSuccessfulChangePassword != null) { + this.onSuccessfulChangePassword(); + } else { + this.messagingService.send("logout"); + } + } catch (e) { + this.logService.error(e); + } + } +}