[PM-2157] Migrate EnrollMasterPasswordReset to CL (#6277)

This commit is contained in:
Oscar Hinton 2023-09-29 15:54:07 +02:00 committed by GitHub
parent b607d1dcfa
commit ab0807072d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 74 additions and 100 deletions

View File

@ -1,52 +1,19 @@
<div
class="modal fade"
role="dialog"
aria-modal="true"
aria-labelledby="enrollMasterPasswordResetTitle"
>
<div class="modal-dialog modal-dialog-scrollable" role="document">
<form
class="modal-content"
#form
(ngSubmit)="submit()"
[appApiAction]="formPromise"
ngNativeValidate
>
<div class="modal-header">
<h1 class="modal-title" id="enrollMasterPasswordResetTitle">
{{ "enrollAccountRecovery" | i18n }}
</h1>
<button
type="button"
class="close"
data-dismiss="modal"
appA11yTitle="{{ 'close' | i18n }}"
>
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<app-callout type="warning">
{{ "resetPasswordEnrollmentWarning" | i18n }}
</app-callout>
<app-user-verification [(ngModel)]="verification" name="secret"> </app-user-verification>
</div>
<div class="modal-footer">
<button type="submit" buttonType="primary" bitButton [loading]="form.loading">
{{ "submit" | i18n }}
</button>
<button
bitButton
buttonType="secondary"
type="button"
data-dismiss="modal"
appA11yTitle="{{ 'close' | i18n }}"
>
<span>
{{ "cancel" | i18n }}
</span>
</button>
</div>
</form>
</div>
</div>
<form [formGroup]="formGroup" [bitSubmit]="submit">
<bit-dialog>
<span bitDialogTitle>{{ "enrollAccountRecovery" | i18n }}</span>
<div bitDialogContent>
<bit-callout type="warning">
{{ "resetPasswordEnrollmentWarning" | i18n }}
</bit-callout>
<app-user-verification formControlName="verification"></app-user-verification>
</div>
<ng-container bitDialogFooter>
<button bitButton buttonType="primary" bitFormButton type="submit">
{{ "submit" | i18n }}
</button>
<button type="button" bitButton buttonType="secondary" bitDialogClose>
{{ "cancel" | i18n }}
</button>
</ng-container>
</bit-dialog>
</form>

View File

@ -1,7 +1,7 @@
import { Component } from "@angular/core";
import { DIALOG_DATA, DialogRef } from "@angular/cdk/dialog";
import { Component, Inject } from "@angular/core";
import { FormControl, FormGroup, Validators } from "@angular/forms";
import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref";
import { ModalConfig } from "@bitwarden/angular/services/modal.service";
import { OrganizationUserService } from "@bitwarden/common/abstractions/organization-user/organization-user.service";
import { OrganizationUserResetPasswordEnrollmentRequest } from "@bitwarden/common/abstractions/organization-user/requests";
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
@ -14,71 +14,83 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { Verification } from "@bitwarden/common/types/verification";
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
import { DialogService } from "@bitwarden/components";
interface EnrollMasterPasswordResetData {
organization: Organization;
}
@Component({
selector: "app-enroll-master-password-reset",
templateUrl: "enroll-master-password-reset.component.html",
})
export class EnrollMasterPasswordReset {
organization: Organization;
protected organization: Organization;
verification: Verification;
formPromise: Promise<void>;
protected formGroup = new FormGroup({
verification: new FormControl<Verification>(null, Validators.required),
});
constructor(
private dialogRef: DialogRef,
@Inject(DIALOG_DATA) protected data: EnrollMasterPasswordResetData,
private userVerificationService: UserVerificationService,
private platformUtilsService: PlatformUtilsService,
private i18nService: I18nService,
private cryptoService: CryptoService,
private syncService: SyncService,
private logService: LogService,
private modalRef: ModalRef,
config: ModalConfig,
private organizationApiService: OrganizationApiServiceAbstraction,
private organizationUserService: OrganizationUserService
) {
this.organization = config.data.organization;
this.organization = data.organization;
}
async submit() {
submit = async () => {
let toastStringRef = "withdrawPasswordResetSuccess";
this.formPromise = this.userVerificationService
.buildRequest(this.verification, OrganizationUserResetPasswordEnrollmentRequest)
.then(async (request) => {
// Set variables
let keyString: string = null;
// Retrieve Public Key
const orgKeys = await this.organizationApiService.getKeys(this.organization.id);
if (orgKeys == null) {
throw new Error(this.i18nService.t("resetPasswordOrgKeysError"));
}
const publicKey = Utils.fromB64ToArray(orgKeys.publicKey);
// RSA Encrypt user's encKey.key with organization public key
const userKey = await this.cryptoService.getUserKey();
const encryptedKey = await this.cryptoService.rsaEncrypt(userKey.key, publicKey);
keyString = encryptedKey.encryptedString;
toastStringRef = "enrollPasswordResetSuccess";
// Create request and execute enrollment
request.resetPasswordKey = keyString;
await this.organizationUserService.putOrganizationUserResetPasswordEnrollment(
this.organization.id,
this.organization.userId,
request
);
await this.syncService.fullSync(true);
});
try {
await this.formPromise;
await this.userVerificationService
.buildRequest(
this.formGroup.value.verification,
OrganizationUserResetPasswordEnrollmentRequest
)
.then(async (request) => {
// Set variables
let keyString: string = null;
// Retrieve Public Key
const orgKeys = await this.organizationApiService.getKeys(this.organization.id);
if (orgKeys == null) {
throw new Error(this.i18nService.t("resetPasswordOrgKeysError"));
}
const publicKey = Utils.fromB64ToArray(orgKeys.publicKey);
// RSA Encrypt user's encKey.key with organization public key
const userKey = await this.cryptoService.getUserKey();
const encryptedKey = await this.cryptoService.rsaEncrypt(userKey.key, publicKey);
keyString = encryptedKey.encryptedString;
toastStringRef = "enrollPasswordResetSuccess";
// Create request and execute enrollment
request.resetPasswordKey = keyString;
await this.organizationUserService.putOrganizationUserResetPasswordEnrollment(
this.organization.id,
this.organization.userId,
request
);
await this.syncService.fullSync(true);
});
this.platformUtilsService.showToast("success", null, this.i18nService.t(toastStringRef));
this.modalRef.close();
this.dialogRef.close();
} catch (e) {
this.logService.error(e);
}
};
static open(dialogService: DialogService, data: EnrollMasterPasswordResetData) {
return dialogService.open(EnrollMasterPasswordReset, { data });
}
}

View File

@ -125,12 +125,7 @@ export class OrganizationOptionsComponent implements OnInit, OnDestroy {
async toggleResetPasswordEnrollment(org: Organization) {
if (!this.organization.resetPasswordEnrolled) {
this.modalService.open(EnrollMasterPasswordReset, {
allowMultipleModals: true,
data: {
organization: org,
},
});
EnrollMasterPasswordReset.open(this.dialogService, { organization: org });
} else {
// Remove reset password
const request = new OrganizationUserResetPasswordEnrollmentRequest();