import { Directive } from "@angular/core"; 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 { SyncService } from "jslib-common/abstractions/sync.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 { SymmetricCryptoKey } from "jslib-common/models/domain/symmetricCryptoKey"; import { UpdateTempPasswordRequest } from "jslib-common/models/request/updateTempPasswordRequest"; @Directive() export class UpdateTempPasswordComponent extends BaseChangePasswordComponent { hint: string; key: string; enforcedPolicyOptions: MasterPasswordPolicyOptions; showPassword: boolean = false; onSuccessfulChangePassword: () => Promise; constructor( i18nService: I18nService, platformUtilsService: PlatformUtilsService, passwordGenerationService: PasswordGenerationService, policyService: PolicyService, cryptoService: CryptoService, messagingService: MessagingService, private apiService: ApiService, stateService: StateService, private syncService: SyncService, private logService: LogService ) { super( i18nService, cryptoService, messagingService, passwordGenerationService, platformUtilsService, policyService, stateService ); } async ngOnInit() { await this.syncService.fullSync(true); super.ngOnInit(); } togglePassword(confirmField: boolean) { this.showPassword = !this.showPassword; document.getElementById(confirmField ? "masterPasswordRetype" : "masterPassword").focus(); } async setupSubmitActions(): Promise { this.enforcedPolicyOptions = await this.policyService.getMasterPasswordPolicyOptions(); this.email = await this.stateService.getEmail(); this.kdf = await this.stateService.getKdfType(); this.kdfIterations = await this.stateService.getKdfIterations(); return true; } async submit() { // Validation if (!(await this.strongPassword())) { return; } if (!(await this.setupSubmitActions())) { return; } try { // Create new key and hash new password const newKey = await this.cryptoService.makeKey( this.masterPassword, this.email.trim().toLowerCase(), this.kdf, this.kdfIterations ); const newPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, newKey); // Grab user's current enc key const userEncKey = await this.cryptoService.getEncKey(); // Create new encKey for the User const newEncKey = await this.cryptoService.remakeEncKey(newKey, userEncKey); await this.performSubmitActions(newPasswordHash, newKey, newEncKey); } catch (e) { this.logService.error(e); } } async performSubmitActions( masterPasswordHash: string, key: SymmetricCryptoKey, encKey: [SymmetricCryptoKey, EncString] ) { try { // Create request const request = new UpdateTempPasswordRequest(); request.key = encKey[1].encryptedString; request.newMasterPasswordHash = masterPasswordHash; request.masterPasswordHint = this.hint; // Update user's password this.formPromise = this.apiService.putUpdateTempPassword(request); await this.formPromise; this.platformUtilsService.showToast( "success", null, this.i18nService.t("updatedMasterPassword") ); if (this.onSuccessfulChangePassword != null) { this.onSuccessfulChangePassword(); } else { this.messagingService.send("logout"); } } catch (e) { this.logService.error(e); } } }