Improved handling of grantor access to organizations after takeover (#820)

* Add emergency access warning for Owners of orgs

* Add master password policy enforcement

* Only show password policy if taking over an Owner

* Fix linting errors

* Fix code style and typos

* Fix implicit 'any' type

* Get grantor policies in separate api call

* Update jslib
This commit is contained in:
Thomas Rittson 2021-02-12 09:58:22 +10:00 committed by GitHub
parent 9d1b2b9f60
commit f239b0cd34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 43 additions and 4 deletions

2
jslib

@ -1 +1 @@
Subproject commit ee164bebc65aa56e41a122eb4ece8971eb23119b Subproject commit d376927e5e583d816e78a26168f870ac78b071c0

View File

@ -12,6 +12,25 @@
</div> </div>
<div class="modal-body"> <div class="modal-body">
<app-callout type="warning">{{'loggedOutWarning' | i18n}}</app-callout> <app-callout type="warning">{{'loggedOutWarning' | i18n}}</app-callout>
<app-callout type="info" *ngIf="enforcedPolicyOptions">
{{'masterPasswordPolicyInEffect' | i18n}}
<ul class="mb-0">
<li *ngIf="enforcedPolicyOptions?.minComplexity > 0">
{{'policyInEffectMinComplexity' | i18n : getPasswordScoreAlertDisplay()}}
</li>
<li *ngIf="enforcedPolicyOptions?.minLength > 0">
{{'policyInEffectMinLength' | i18n : enforcedPolicyOptions?.minLength.toString()}}
</li>
<li *ngIf="enforcedPolicyOptions?.requireUpper">
{{'policyInEffectUppercase' | i18n}}</li>
<li *ngIf="enforcedPolicyOptions?.requireLower">
{{'policyInEffectLowercase' | i18n}}</li>
<li *ngIf="enforcedPolicyOptions?.requireNumbers">
{{'policyInEffectNumbers' | i18n}}</li>
<li *ngIf="enforcedPolicyOptions?.requireSpecial">
{{'policyInEffectSpecial' | i18n : '!@#$%^&*'}}</li>
</ul>
</app-callout>
<div class="row"> <div class="row">
<div class="col-6"> <div class="col-6">
<div class="form-group"> <div class="form-group">

View File

@ -19,8 +19,13 @@ import { UserService } from 'jslib/abstractions/user.service';
import { ChangePasswordComponent } from 'jslib/angular/components/change-password.component'; import { ChangePasswordComponent } from 'jslib/angular/components/change-password.component';
import { KdfType } from 'jslib/enums/kdfType'; import { KdfType } from 'jslib/enums/kdfType';
import { PolicyData } from 'jslib/models/data/policyData';
import { Policy } from 'jslib/models/domain/policy';
import { SymmetricCryptoKey } from 'jslib/models/domain/symmetricCryptoKey'; import { SymmetricCryptoKey } from 'jslib/models/domain/symmetricCryptoKey';
import { EmergencyAccessPasswordRequest } from 'jslib/models/request/emergencyAccessPasswordRequest'; import { EmergencyAccessPasswordRequest } from 'jslib/models/request/emergencyAccessPasswordRequest';
import { ListResponse } from 'jslib/models/response';
import { EmergencyAccessTakeoverResponse } from 'jslib/models/response/emergencyAccessResponse';
import { PolicyResponse } from 'jslib/models/response/policyResponse';
@Component({ @Component({
selector: 'emergency-access-takeover', selector: 'emergency-access-takeover',
@ -45,8 +50,13 @@ export class EmergencyAccessTakeoverComponent extends ChangePasswordComponent im
platformUtilsService, policyService); platformUtilsService, policyService);
} }
// tslint:disable-next-line async ngOnInit() {
async ngOnInit() { } const response = await this.apiService.getEmergencyGrantorPolicies(this.emergencyAccessId);
if (response.data != null && response.data.length > 0) {
const policies = response.data.map((policyResponse: PolicyResponse) => new Policy(new PolicyData(policyResponse)));
this.enforcedPolicyOptions = await this.policyService.getMasterPasswordPolicyOptions(policies);
}
}
async submit() { async submit() {
if (!await this.strongPassword()) { if (!await this.strongPassword()) {

View File

@ -8,6 +8,10 @@
</a> </a>
</p> </p>
<p *ngIf="isOrganizationOwner">
<b>{{'warning' | i18n }}:</b> {{'emergencyAccessOwnerWarning' | i18n}}
</p>
<div class="page-header d-flex"> <div class="page-header d-flex">
<h2> <h2>
{{'trustedEmergencyContacts' | i18n}} {{'trustedEmergencyContacts' | i18n}}

View File

@ -36,6 +36,7 @@ export class EmergencyAccessComponent implements OnInit {
emergencyAccessType = EmergencyAccessType; emergencyAccessType = EmergencyAccessType;
emergencyAccessStatusType = EmergencyAccessStatusType; emergencyAccessStatusType = EmergencyAccessStatusType;
actionPromise: Promise<any>; actionPromise: Promise<any>;
isOrganizationOwner: boolean;
private modal: ModalComponent = null; private modal: ModalComponent = null;
@ -48,6 +49,8 @@ export class EmergencyAccessComponent implements OnInit {
async ngOnInit() { async ngOnInit() {
this.canAccessPremium = await this.userService.canAccessPremium(); this.canAccessPremium = await this.userService.canAccessPremium();
const orgs = await this.userService.getAllOrganizations();
this.isOrganizationOwner = orgs.some(o => o.isOwner);
this.load(); this.load();
} }

View File

@ -3424,7 +3424,10 @@
"message": "Emergency Access" "message": "Emergency Access"
}, },
"emergencyAccessDesc": { "emergencyAccessDesc": {
"message": "Grant and manage emergency access for trusted contacts. Trusted contacts may request access to either View or Takeover your account in case of a emergency. Visit our help page for more information and details into how zero knowledge sharing works." "message": "Grant and manage emergency access for trusted contacts. Trusted contacts may request access to either View or Takeover your account in case of an emergency. Visit our help page for more information and details into how zero knowledge sharing works."
},
"emergencyAccessOwnerWarning": {
"message": "You are an Owner of one or more organizations. If you give takeover access to an emergency contact, they will be able to use all your permissions as Owner after a takeover."
}, },
"trustedEmergencyContacts": { "trustedEmergencyContacts": {
"message": "Trusted emergency contacts" "message": "Trusted emergency contacts"