mirror of
https://github.com/bitwarden/web
synced 2025-12-11 13:53:17 +00:00
Compare commits
3 Commits
bug/ps-136
...
csa-2-pass
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a001ac72b5 | ||
|
|
356bd14bb4 | ||
|
|
66046660d1 |
2
jslib
2
jslib
Submodule jslib updated: e595c0548e...dc7efa4970
3
package-lock.json
generated
3
package-lock.json
generated
@@ -87,7 +87,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jslib/angular": {
|
"jslib/angular": {
|
||||||
"name": "@bitwarden/jslib-common",
|
"name": "@bitwarden/jslib-angular",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -113,6 +113,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jslib/common": {
|
"jslib/common": {
|
||||||
|
"name": "@bitwarden/jslib-common",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -171,6 +171,7 @@ import { EmergencyAccessViewComponent } from "./settings/emergency-access-view.c
|
|||||||
import { EmergencyAccessComponent } from "./settings/emergency-access.component";
|
import { EmergencyAccessComponent } from "./settings/emergency-access.component";
|
||||||
import { EmergencyAddEditComponent } from "./settings/emergency-add-edit.component";
|
import { EmergencyAddEditComponent } from "./settings/emergency-add-edit.component";
|
||||||
import { LinkSsoComponent } from "./settings/link-sso.component";
|
import { LinkSsoComponent } from "./settings/link-sso.component";
|
||||||
|
import { MasterPasswordEnrollmentComponent } from "./settings/master-password-enrollment.component";
|
||||||
import { OptionsComponent } from "./settings/options.component";
|
import { OptionsComponent } from "./settings/options.component";
|
||||||
import { OrganizationPlansComponent } from "./settings/organization-plans.component";
|
import { OrganizationPlansComponent } from "./settings/organization-plans.component";
|
||||||
import { OrganizationsComponent } from "./settings/organizations.component";
|
import { OrganizationsComponent } from "./settings/organizations.component";
|
||||||
@@ -335,6 +336,7 @@ registerLocaleData(localeZhTw, "zh-TW");
|
|||||||
LockComponent,
|
LockComponent,
|
||||||
LoginComponent,
|
LoginComponent,
|
||||||
MasterPasswordPolicyComponent,
|
MasterPasswordPolicyComponent,
|
||||||
|
MasterPasswordEnrollmentComponent,
|
||||||
NavbarComponent,
|
NavbarComponent,
|
||||||
NestedCheckboxComponent,
|
NestedCheckboxComponent,
|
||||||
OptionsComponent,
|
OptionsComponent,
|
||||||
|
|||||||
39
src/app/settings/master-password-enrollment.component.html
Normal file
39
src/app/settings/master-password-enrollment.component.html
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<div class="modal fade" role="dialog" aria-modal="true" aria-labelledby="passwordEnrollment">
|
||||||
|
<div class="modal-dialog modal-dialog-scrollable" role="document">
|
||||||
|
<form
|
||||||
|
class="modal-content"
|
||||||
|
#form
|
||||||
|
(ngSubmit)="submit()"
|
||||||
|
[appApiAction]="formPromise"
|
||||||
|
ngNativeValidate
|
||||||
|
>
|
||||||
|
<div class="modal-header">
|
||||||
|
<h2 class="modal-title" id="passwordEnrollmentTitle">
|
||||||
|
{{ passwordEnrollmentTitle | i18n }}
|
||||||
|
</h2>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="close"
|
||||||
|
data-dismiss="modal"
|
||||||
|
appA11yTitle="{{ 'close' | i18n }}"
|
||||||
|
>
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>{{ passwordEnrollmentDescription | i18n }}</p>
|
||||||
|
<app-verify-master-password [(ngModel)]="masterPassword" ngDefaultControl name="secret">
|
||||||
|
</app-verify-master-password>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="submit" class="btn btn-primary btn-submit">
|
||||||
|
<i class="fa fa-paper-plane" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
|
||||||
|
<span>{{ "submit" | i18n }}</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">
|
||||||
|
{{ "close" | i18n }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
37
src/app/settings/master-password-enrollment.component.ts
Normal file
37
src/app/settings/master-password-enrollment.component.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { Component, EventEmitter, Output } from "@angular/core";
|
||||||
|
|
||||||
|
import { LogService } from "jslib-common/abstractions/log.service";
|
||||||
|
import { UserVerificationService } from "jslib-common/abstractions/userVerification.service";
|
||||||
|
import { SecretVerificationRequest } from "jslib-common/models/request/secretVerificationRequest";
|
||||||
|
import { Verification } from "jslib-common/types/verification";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "master-password-enrollment",
|
||||||
|
templateUrl: "master-password-enrollment.component.html",
|
||||||
|
})
|
||||||
|
export class MasterPasswordEnrollmentComponent {
|
||||||
|
masterPassword: Verification;
|
||||||
|
formPromise: Promise<void | SecretVerificationRequest>;
|
||||||
|
passwordEnrollmentTitle: string;
|
||||||
|
passwordEnrollmentDescription: string;
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
requestBuilt = new EventEmitter<SecretVerificationRequest>();
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private userVerificationService: UserVerificationService,
|
||||||
|
private logService: LogService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async submit() {
|
||||||
|
try {
|
||||||
|
this.formPromise = this.userVerificationService
|
||||||
|
.buildRequest(this.masterPassword)
|
||||||
|
.then((request) => this.requestBuilt.emit(request));
|
||||||
|
|
||||||
|
return await this.formPromise;
|
||||||
|
} catch (e) {
|
||||||
|
this.logService.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -153,3 +153,4 @@
|
|||||||
</table>
|
</table>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
<ng-template #confirmMasterPassword></ng-template>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Component, Input, OnInit } from "@angular/core";
|
import { Component, Input, OnInit, ViewChild, ViewContainerRef } from "@angular/core";
|
||||||
|
|
||||||
|
import { ModalService } from "jslib-angular/services/modal.service";
|
||||||
import { ApiService } from "jslib-common/abstractions/api.service";
|
import { ApiService } from "jslib-common/abstractions/api.service";
|
||||||
import { CryptoService } from "jslib-common/abstractions/crypto.service";
|
import { CryptoService } from "jslib-common/abstractions/crypto.service";
|
||||||
import { I18nService } from "jslib-common/abstractions/i18n.service";
|
import { I18nService } from "jslib-common/abstractions/i18n.service";
|
||||||
@@ -14,12 +15,16 @@ import { Organization } from "jslib-common/models/domain/organization";
|
|||||||
import { Policy } from "jslib-common/models/domain/policy";
|
import { Policy } from "jslib-common/models/domain/policy";
|
||||||
import { OrganizationUserResetPasswordEnrollmentRequest } from "jslib-common/models/request/organizationUserResetPasswordEnrollmentRequest";
|
import { OrganizationUserResetPasswordEnrollmentRequest } from "jslib-common/models/request/organizationUserResetPasswordEnrollmentRequest";
|
||||||
|
|
||||||
|
import { MasterPasswordEnrollmentComponent } from "./master-password-enrollment.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-organizations",
|
selector: "app-organizations",
|
||||||
templateUrl: "organizations.component.html",
|
templateUrl: "organizations.component.html",
|
||||||
})
|
})
|
||||||
export class OrganizationsComponent implements OnInit {
|
export class OrganizationsComponent implements OnInit {
|
||||||
@Input() vault = false;
|
@Input() vault = false;
|
||||||
|
@ViewChild("confirmMasterPassword", { read: ViewContainerRef, static: true })
|
||||||
|
confirmMasterPasswordModalRef: ViewContainerRef;
|
||||||
|
|
||||||
organizations: Organization[];
|
organizations: Organization[];
|
||||||
policies: Policy[];
|
policies: Policy[];
|
||||||
@@ -34,7 +39,8 @@ export class OrganizationsComponent implements OnInit {
|
|||||||
private syncService: SyncService,
|
private syncService: SyncService,
|
||||||
private cryptoService: CryptoService,
|
private cryptoService: CryptoService,
|
||||||
private policyService: PolicyService,
|
private policyService: PolicyService,
|
||||||
private logService: LogService
|
private logService: LogService,
|
||||||
|
private modalService: ModalService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
@@ -157,11 +163,14 @@ export class OrganizationsComponent implements OnInit {
|
|||||||
// Create request and execute enrollment
|
// Create request and execute enrollment
|
||||||
const request = new OrganizationUserResetPasswordEnrollmentRequest();
|
const request = new OrganizationUserResetPasswordEnrollmentRequest();
|
||||||
request.resetPasswordKey = keyString;
|
request.resetPasswordKey = keyString;
|
||||||
return this.apiService.putOrganizationUserResetPasswordEnrollment(
|
request.masterPasswordHash = await this.getMasterPassword();
|
||||||
|
const res = this.apiService.putOrganizationUserResetPasswordEnrollment(
|
||||||
org.id,
|
org.id,
|
||||||
org.userId,
|
org.userId,
|
||||||
request
|
request
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return res;
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return this.syncService.fullSync(true);
|
return this.syncService.fullSync(true);
|
||||||
@@ -170,6 +179,7 @@ export class OrganizationsComponent implements OnInit {
|
|||||||
// Withdrawal
|
// Withdrawal
|
||||||
const request = new OrganizationUserResetPasswordEnrollmentRequest();
|
const request = new OrganizationUserResetPasswordEnrollmentRequest();
|
||||||
request.resetPasswordKey = keyString;
|
request.resetPasswordKey = keyString;
|
||||||
|
request.masterPasswordHash = await this.getMasterPassword();
|
||||||
this.actionPromise = this.apiService
|
this.actionPromise = this.apiService
|
||||||
.putOrganizationUserResetPasswordEnrollment(org.id, org.userId, request)
|
.putOrganizationUserResetPasswordEnrollment(org.id, org.userId, request)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -185,4 +195,23 @@ export class OrganizationsComponent implements OnInit {
|
|||||||
this.logService.error(e);
|
this.logService.error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async getMasterPassword(): Promise<string> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
(async () => {
|
||||||
|
const [modal] = await this.modalService.openViewRef(
|
||||||
|
MasterPasswordEnrollmentComponent,
|
||||||
|
this.confirmMasterPasswordModalRef,
|
||||||
|
(comp) => {
|
||||||
|
comp.passwordEnrollmentTitle = "passwordResetEnrollment";
|
||||||
|
comp.passwordEnrollmentDescription = "passwordResetEnrollmentDescription";
|
||||||
|
comp.requestBuilt.subscribe((val) => {
|
||||||
|
modal.close();
|
||||||
|
resolve(val.masterPasswordHash);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
})();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4876,5 +4876,11 @@
|
|||||||
},
|
},
|
||||||
"service": {
|
"service": {
|
||||||
"message": "Service"
|
"message": "Service"
|
||||||
|
},
|
||||||
|
"passwordResetEnrollment" : {
|
||||||
|
"message": "Password Reset Enrollment"
|
||||||
|
},
|
||||||
|
"passwordResetEnrollmentDescription": {
|
||||||
|
"message": "Enter your master password so we can enroll you in password reset"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user