mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-21 11:35:34 +01:00
[PM-10314] Update Warnings for Verifying Domains and Single Org Policy Auto Enable (#11688)
* Updated description and warning for single org policy. * Added check for verified domains in disabling single org.
This commit is contained in:
parent
f86bc9bf28
commit
53f13f4ea5
@ -15,7 +15,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container bitDialogFooter>
|
<ng-container bitDialogFooter>
|
||||||
<button bitButton buttonType="primary" bitFormButton type="submit">
|
<button bitButton buttonType="primary" [disabled]="saveDisabled" bitFormButton type="submit">
|
||||||
{{ "save" | i18n }}
|
{{ "save" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
<button bitButton buttonType="secondary" bitDialogClose type="button">
|
<button bitButton buttonType="secondary" bitDialogClose type="button">
|
||||||
|
@ -42,6 +42,7 @@ export class PolicyEditComponent implements AfterViewInit {
|
|||||||
policyType = PolicyType;
|
policyType = PolicyType;
|
||||||
loading = true;
|
loading = true;
|
||||||
enabled = false;
|
enabled = false;
|
||||||
|
saveDisabled = false;
|
||||||
defaultTypes: any[];
|
defaultTypes: any[];
|
||||||
policyComponent: BasePolicyComponent;
|
policyComponent: BasePolicyComponent;
|
||||||
|
|
||||||
@ -72,6 +73,8 @@ export class PolicyEditComponent implements AfterViewInit {
|
|||||||
this.policyComponent.policy = this.data.policy;
|
this.policyComponent.policy = this.data.policy;
|
||||||
this.policyComponent.policyResponse = this.policyResponse;
|
this.policyComponent.policyResponse = this.policyResponse;
|
||||||
|
|
||||||
|
this.saveDisabled = !this.policyResponse.canToggleState;
|
||||||
|
|
||||||
this.cdr.detectChanges();
|
this.cdr.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
<bit-callout type="warning">
|
<bit-callout *ngIf="accountDeprovisioningEnabled$ | async; else disabledBlock" type="warning">
|
||||||
{{ "singleOrgPolicyWarning" | i18n }}
|
{{ "singleOrgPolicyMemberWarning" | i18n }}
|
||||||
</bit-callout>
|
</bit-callout>
|
||||||
|
<ng-template #disabledBlock>
|
||||||
|
<bit-callout type="warning">
|
||||||
|
{{ "singleOrgPolicyWarning" | i18n }}
|
||||||
|
</bit-callout>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
<bit-form-control>
|
<bit-form-control>
|
||||||
<input type="checkbox" bitCheckbox [formControl]="enabled" id="enabled" />
|
<input type="checkbox" bitCheckbox [formControl]="enabled" id="enabled" />
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
|
import { firstValueFrom, Observable } from "rxjs";
|
||||||
|
|
||||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||||
import { PolicyRequest } from "@bitwarden/common/admin-console/models/request/policy.request";
|
import { PolicyRequest } from "@bitwarden/common/admin-console/models/request/policy.request";
|
||||||
@ -19,7 +20,7 @@ export class SingleOrgPolicy extends BasePolicy {
|
|||||||
selector: "policy-single-org",
|
selector: "policy-single-org",
|
||||||
templateUrl: "single-org.component.html",
|
templateUrl: "single-org.component.html",
|
||||||
})
|
})
|
||||||
export class SingleOrgPolicyComponent extends BasePolicyComponent {
|
export class SingleOrgPolicyComponent extends BasePolicyComponent implements OnInit {
|
||||||
constructor(
|
constructor(
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private configService: ConfigService,
|
private configService: ConfigService,
|
||||||
@ -27,6 +28,23 @@ export class SingleOrgPolicyComponent extends BasePolicyComponent {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected accountDeprovisioningEnabled$: Observable<boolean> = this.configService.getFeatureFlag$(
|
||||||
|
FeatureFlag.AccountDeprovisioning,
|
||||||
|
);
|
||||||
|
|
||||||
|
async ngOnInit() {
|
||||||
|
super.ngOnInit();
|
||||||
|
|
||||||
|
const isAccountDeprovisioningEnabled = await firstValueFrom(this.accountDeprovisioningEnabled$);
|
||||||
|
this.policy.description = isAccountDeprovisioningEnabled
|
||||||
|
? "singleOrgPolicyDesc"
|
||||||
|
: "singleOrgDesc";
|
||||||
|
|
||||||
|
if (!this.policyResponse.canToggleState) {
|
||||||
|
this.enabled.disable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async buildRequest(policiesEnabledMap: Map<PolicyType, boolean>): Promise<PolicyRequest> {
|
async buildRequest(policiesEnabledMap: Map<PolicyType, boolean>): Promise<PolicyRequest> {
|
||||||
if (await this.configService.getFeatureFlag(FeatureFlag.Pm13322AddPolicyDefinitions)) {
|
if (await this.configService.getFeatureFlag(FeatureFlag.Pm13322AddPolicyDefinitions)) {
|
||||||
// We are now relying on server-side validation only
|
// We are now relying on server-side validation only
|
||||||
@ -48,6 +66,15 @@ export class SingleOrgPolicyComponent extends BasePolicyComponent {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
(await firstValueFrom(this.accountDeprovisioningEnabled$)) &&
|
||||||
|
!this.policyResponse.canToggleState
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
this.i18nService.t("disableRequiredError", this.i18nService.t("singleOrg")),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.buildRequest(policiesEnabledMap);
|
return super.buildRequest(policiesEnabledMap);
|
||||||
|
@ -4684,12 +4684,18 @@
|
|||||||
"singleOrgDesc": {
|
"singleOrgDesc": {
|
||||||
"message": "Restrict members from joining other organizations."
|
"message": "Restrict members from joining other organizations."
|
||||||
},
|
},
|
||||||
|
"singleOrgPolicyDesc": {
|
||||||
|
"message": "Restrict members from joining other organizations. This policy is required for organizations that have enabled domain verification."
|
||||||
|
},
|
||||||
"singleOrgBlockCreateMessage": {
|
"singleOrgBlockCreateMessage": {
|
||||||
"message": "Your current organization has a policy that does not allow you to join more than one organization. Please contact your organization admins or sign up from a different Bitwarden account."
|
"message": "Your current organization has a policy that does not allow you to join more than one organization. Please contact your organization admins or sign up from a different Bitwarden account."
|
||||||
},
|
},
|
||||||
"singleOrgPolicyWarning": {
|
"singleOrgPolicyWarning": {
|
||||||
"message": "Organization members who are not owners or admins and are already a member of another organization will be removed from your organization."
|
"message": "Organization members who are not owners or admins and are already a member of another organization will be removed from your organization."
|
||||||
},
|
},
|
||||||
|
"singleOrgPolicyMemberWarning": {
|
||||||
|
"message": "Non-compliant members will be placed in revoked status until they leave all other organizations. Administrators are exempt and can restore members once compliance is met."
|
||||||
|
},
|
||||||
"requireSso": {
|
"requireSso": {
|
||||||
"message": "Require single sign-on authentication"
|
"message": "Require single sign-on authentication"
|
||||||
},
|
},
|
||||||
@ -9531,5 +9537,11 @@
|
|||||||
},
|
},
|
||||||
"selfHostingTitleProper": {
|
"selfHostingTitleProper": {
|
||||||
"message": "Self-Hosting"
|
"message": "Self-Hosting"
|
||||||
|
},
|
||||||
|
"verified-domain-single-org-warning" : {
|
||||||
|
"message": "Verifying a domain will turn on the single organization policy."
|
||||||
|
},
|
||||||
|
"single-org-revoked-user-warning": {
|
||||||
|
"message": "Non-compliant members will be revoked. Administrators can restore members once they leave all other organizations."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,24 @@
|
|||||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||||
import { ActivatedRoute, Params } from "@angular/router";
|
import { ActivatedRoute, Params } from "@angular/router";
|
||||||
import { concatMap, Observable, Subject, take, takeUntil } from "rxjs";
|
import {
|
||||||
|
concatMap,
|
||||||
|
firstValueFrom,
|
||||||
|
map,
|
||||||
|
Observable,
|
||||||
|
Subject,
|
||||||
|
take,
|
||||||
|
takeUntil,
|
||||||
|
withLatestFrom,
|
||||||
|
} from "rxjs";
|
||||||
|
|
||||||
import { OrgDomainApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization-domain/org-domain-api.service.abstraction";
|
import { OrgDomainApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization-domain/org-domain-api.service.abstraction";
|
||||||
import { OrgDomainServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization-domain/org-domain.service.abstraction";
|
import { OrgDomainServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization-domain/org-domain.service.abstraction";
|
||||||
import { OrganizationDomainResponse } from "@bitwarden/common/admin-console/abstractions/organization-domain/responses/organization-domain.response";
|
import { OrganizationDomainResponse } from "@bitwarden/common/admin-console/abstractions/organization-domain/responses/organization-domain.response";
|
||||||
import { HttpStatusCode } from "@bitwarden/common/enums";
|
import { HttpStatusCode } from "@bitwarden/common/enums";
|
||||||
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||||
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
|
||||||
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
|
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
|
||||||
import { DialogService, ToastService } from "@bitwarden/components";
|
import { DialogService, ToastService } from "@bitwarden/components";
|
||||||
|
|
||||||
@ -31,13 +41,13 @@ export class DomainVerificationComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private platformUtilsService: PlatformUtilsService,
|
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private orgDomainApiService: OrgDomainApiServiceAbstraction,
|
private orgDomainApiService: OrgDomainApiServiceAbstraction,
|
||||||
private orgDomainService: OrgDomainServiceAbstraction,
|
private orgDomainService: OrgDomainServiceAbstraction,
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
private validationService: ValidationService,
|
private validationService: ValidationService,
|
||||||
private toastService: ToastService,
|
private toastService: ToastService,
|
||||||
|
private configService: ConfigService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||||
@ -64,13 +74,38 @@ export class DomainVerificationComponent implements OnInit, OnDestroy {
|
|||||||
this.loading = false;
|
this.loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
addDomain() {
|
async addDomain() {
|
||||||
const domainAddEditDialogData: DomainAddEditDialogData = {
|
const domainAddEditDialogData: DomainAddEditDialogData = {
|
||||||
organizationId: this.organizationId,
|
organizationId: this.organizationId,
|
||||||
orgDomain: null,
|
orgDomain: null,
|
||||||
existingDomainNames: this.getExistingDomainNames(),
|
existingDomainNames: this.getExistingDomainNames(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
await firstValueFrom(
|
||||||
|
this.configService.getFeatureFlag$(FeatureFlag.AccountDeprovisioning).pipe(
|
||||||
|
withLatestFrom(this.orgDomains$),
|
||||||
|
map(async ([accountDeprovisioningEnabled, organizationDomains]) => {
|
||||||
|
if (
|
||||||
|
accountDeprovisioningEnabled &&
|
||||||
|
organizationDomains.every((domain) => domain.verifiedDate === null)
|
||||||
|
) {
|
||||||
|
await this.dialogService.openSimpleDialog({
|
||||||
|
title: { key: "verified-domain-single-org-warning" },
|
||||||
|
content: { key: "single-org-revoked-user-warning" },
|
||||||
|
cancelButtonText: { key: "cancel" },
|
||||||
|
acceptButtonText: { key: "confirm" },
|
||||||
|
acceptAction: () => this.openAddDomainDialog(domainAddEditDialogData),
|
||||||
|
type: "info",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await this.openAddDomainDialog(domainAddEditDialogData);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async openAddDomainDialog(domainAddEditDialogData: DomainAddEditDialogData) {
|
||||||
this.dialogService.open(DomainAddEditDialogComponent, {
|
this.dialogService.open(DomainAddEditDialogComponent, {
|
||||||
data: domainAddEditDialogData,
|
data: domainAddEditDialogData,
|
||||||
});
|
});
|
||||||
|
@ -8,6 +8,7 @@ export class PolicyResponse extends BaseResponse {
|
|||||||
type: PolicyType;
|
type: PolicyType;
|
||||||
data: any;
|
data: any;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
|
canToggleState: boolean;
|
||||||
|
|
||||||
constructor(response: any) {
|
constructor(response: any) {
|
||||||
super(response);
|
super(response);
|
||||||
@ -16,5 +17,6 @@ export class PolicyResponse extends BaseResponse {
|
|||||||
this.type = this.getResponseProperty("Type");
|
this.type = this.getResponseProperty("Type");
|
||||||
this.data = this.getResponseProperty("Data");
|
this.data = this.getResponseProperty("Data");
|
||||||
this.enabled = this.getResponseProperty("Enabled");
|
this.enabled = this.getResponseProperty("Enabled");
|
||||||
|
this.canToggleState = this.getResponseProperty("CanToggleState") ?? true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user