From d5112cc8cba4121e689372246c59f6463bfbace1 Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Wed, 8 Jun 2022 14:56:26 -0500 Subject: [PATCH] [PS-616] [PS-795] Fix/withdraw master password reset without user verification (#2845) * Limit enroll MPR modal to enrolling * Withdraw from MPR directly from org options * [PS-795] Fix Automatic mpr enrollment. Add reset password key to the accept request * Linter * Specify params type in accept components --- .../accounts/accept-emergency.component.ts | 6 +- .../accounts/accept-organization.component.ts | 66 ++++++++----------- .../src/app/common/base.accept.component.ts | 6 +- ...nroll-master-password-reset.component.html | 4 +- .../enroll-master-password-reset.component.ts | 55 ++++++---------- .../organization-options.component.html | 6 +- .../organization-options.component.ts | 37 ++++++++--- .../accept-family-sponsorship.component.ts | 5 +- .../manage/accept-provider.component.ts | 6 +- .../setup/setup-provider.component.ts | 5 +- .../request/organizationUserAcceptRequest.ts | 2 + 11 files changed, 102 insertions(+), 96 deletions(-) diff --git a/apps/web/src/app/accounts/accept-emergency.component.ts b/apps/web/src/app/accounts/accept-emergency.component.ts index c790a924be..2083ebcac4 100644 --- a/apps/web/src/app/accounts/accept-emergency.component.ts +++ b/apps/web/src/app/accounts/accept-emergency.component.ts @@ -1,5 +1,5 @@ import { Component } from "@angular/core"; -import { ActivatedRoute, Router } from "@angular/router"; +import { ActivatedRoute, Params, Router } from "@angular/router"; import { ApiService } from "jslib-common/abstractions/api.service"; import { I18nService } from "jslib-common/abstractions/i18n.service"; @@ -31,7 +31,7 @@ export class AcceptEmergencyComponent extends BaseAcceptComponent { super(router, platformUtilsService, i18nService, route, stateService); } - async authedHandler(qParams: any): Promise { + async authedHandler(qParams: Params): Promise { const request = new EmergencyAccessAcceptRequest(); request.token = qParams.token; this.actionPromise = this.apiService.postEmergencyAccessAccept(qParams.id, request); @@ -45,7 +45,7 @@ export class AcceptEmergencyComponent extends BaseAcceptComponent { this.router.navigate(["/vault"]); } - async unauthedHandler(qParams: any): Promise { + async unauthedHandler(qParams: Params): Promise { this.name = qParams.name; if (this.name != null) { // Fix URL encoding of space issue with Angular diff --git a/apps/web/src/app/accounts/accept-organization.component.ts b/apps/web/src/app/accounts/accept-organization.component.ts index 0d59562a66..541ca37461 100644 --- a/apps/web/src/app/accounts/accept-organization.component.ts +++ b/apps/web/src/app/accounts/accept-organization.component.ts @@ -1,5 +1,5 @@ import { Component } from "@angular/core"; -import { ActivatedRoute, Router } from "@angular/router"; +import { ActivatedRoute, Params, Router } from "@angular/router"; import { ApiService } from "jslib-common/abstractions/api.service"; import { CryptoService } from "jslib-common/abstractions/crypto.service"; @@ -11,7 +11,6 @@ import { StateService } from "jslib-common/abstractions/state.service"; import { Utils } from "jslib-common/misc/utils"; import { Policy } from "jslib-common/models/domain/policy"; import { OrganizationUserAcceptRequest } from "jslib-common/models/request/organizationUserAcceptRequest"; -import { OrganizationUserResetPasswordEnrollmentRequest } from "jslib-common/models/request/organizationUserResetPasswordEnrollmentRequest"; import { BaseAcceptComponent } from "../common/base.accept.component"; @@ -38,44 +37,14 @@ export class AcceptOrganizationComponent extends BaseAcceptComponent { super(router, platformUtilsService, i18nService, route, stateService); } - async authedHandler(qParams: any): Promise { - const request = new OrganizationUserAcceptRequest(); - request.token = qParams.token; - if (await this.performResetPasswordAutoEnroll(qParams)) { - this.actionPromise = this.apiService - .postOrganizationUserAccept(qParams.organizationId, qParams.organizationUserId, request) - .then(() => { - // Retrieve Public Key - return this.apiService.getOrganizationKeys(qParams.organizationId); - }) - .then(async (response) => { - if (response == null) { - throw new Error(this.i18nService.t("resetPasswordOrgKeysError")); - } - - const publicKey = Utils.fromB64ToArray(response.publicKey); - - // RSA Encrypt user's encKey.key with organization public key - const encKey = await this.cryptoService.getEncKey(); - const encryptedKey = await this.cryptoService.rsaEncrypt(encKey.key, publicKey.buffer); - - // Create request and execute enrollment - const resetRequest = new OrganizationUserResetPasswordEnrollmentRequest(); - resetRequest.resetPasswordKey = encryptedKey.encryptedString; - - return this.apiService.putOrganizationUserResetPasswordEnrollment( - qParams.organizationId, - await this.stateService.getUserId(), - resetRequest - ); - }); - } else { - this.actionPromise = this.apiService.postOrganizationUserAccept( + async authedHandler(qParams: Params): Promise { + this.actionPromise = this.prepareAcceptRequest(qParams).then(async (request) => { + await this.apiService.postOrganizationUserAccept( qParams.organizationId, qParams.organizationUserId, request ); - } + }); await this.actionPromise; this.platformUtilService.showToast( @@ -89,7 +58,7 @@ export class AcceptOrganizationComponent extends BaseAcceptComponent { this.router.navigate(["/vault"]); } - async unauthedHandler(qParams: any): Promise { + async unauthedHandler(qParams: Params): Promise { this.orgName = qParams.organizationName; if (this.orgName != null) { // Fix URL encoding of space issue with Angular @@ -98,6 +67,29 @@ export class AcceptOrganizationComponent extends BaseAcceptComponent { await this.stateService.setOrganizationInvitation(qParams); } + private async prepareAcceptRequest(qParams: Params): Promise { + const request = new OrganizationUserAcceptRequest(); + request.token = qParams.token; + + if (await this.performResetPasswordAutoEnroll(qParams)) { + const response = await this.apiService.getOrganizationKeys(qParams.organizationId); + + if (response == null) { + throw new Error(this.i18nService.t("resetPasswordOrgKeysError")); + } + + const publicKey = Utils.fromB64ToArray(response.publicKey); + + // RSA Encrypt user's encKey.key with organization public key + const encKey = await this.cryptoService.getEncKey(); + const encryptedKey = await this.cryptoService.rsaEncrypt(encKey.key, publicKey.buffer); + + // Add reset password key to accept request + request.resetPasswordKey = encryptedKey.encryptedString; + } + return request; + } + private async performResetPasswordAutoEnroll(qParams: any): Promise { let policyList: Policy[] = null; try { diff --git a/apps/web/src/app/common/base.accept.component.ts b/apps/web/src/app/common/base.accept.component.ts index 36375fbd1e..7d6d753673 100644 --- a/apps/web/src/app/common/base.accept.component.ts +++ b/apps/web/src/app/common/base.accept.component.ts @@ -1,5 +1,5 @@ import { Directive, OnInit } from "@angular/core"; -import { ActivatedRoute, Router } from "@angular/router"; +import { ActivatedRoute, Params, Router } from "@angular/router"; import { first } from "rxjs/operators"; import { I18nService } from "jslib-common/abstractions/i18n.service"; @@ -25,8 +25,8 @@ export abstract class BaseAcceptComponent implements OnInit { protected stateService: StateService ) {} - abstract authedHandler(qParams: any): Promise; - abstract unauthedHandler(qParams: any): Promise; + abstract authedHandler(qParams: Params): Promise; + abstract unauthedHandler(qParams: Params): Promise; ngOnInit() { this.route.queryParams.pipe(first()).subscribe(async (qParams) => { diff --git a/apps/web/src/app/modules/organizations/users/enroll-master-password-reset.component.html b/apps/web/src/app/modules/organizations/users/enroll-master-password-reset.component.html index c8d15a3956..e232a7987f 100644 --- a/apps/web/src/app/modules/organizations/users/enroll-master-password-reset.component.html +++ b/apps/web/src/app/modules/organizations/users/enroll-master-password-reset.component.html @@ -14,7 +14,7 @@ >