mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 21:33:27 +00:00
[PM-22107] Update Remove Individual Vault policy dialog (#15323)
* WIP * switch to signal * fix ts strict errors * clean up * refactor policy list service * implement vnext component * refactor to include feature flag check in display() * CR feedback * refactor submit to cancel before request is built * clean up * Fix typo --------- Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Directive, Input, OnInit } from "@angular/core";
|
||||
import { UntypedFormControl, UntypedFormGroup } from "@angular/forms";
|
||||
import { Observable, of } from "rxjs";
|
||||
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { PolicyRequest } from "@bitwarden/common/admin-console/models/request/policy.request";
|
||||
import { PolicyResponse } from "@bitwarden/common/admin-console/models/response/policy.response";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
|
||||
export abstract class BasePolicy {
|
||||
abstract name: string;
|
||||
@@ -14,38 +14,56 @@ export abstract class BasePolicy {
|
||||
abstract type: PolicyType;
|
||||
abstract component: any;
|
||||
|
||||
display(organization: Organization) {
|
||||
return true;
|
||||
/**
|
||||
* If true, the description will be reused in the policy edit modal. Set this to false if you
|
||||
* have more complex requirements that you will implement in your template instead.
|
||||
**/
|
||||
showDescription: boolean = true;
|
||||
|
||||
display(organization: Organization, configService: ConfigService): Observable<boolean> {
|
||||
return of(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Directive()
|
||||
export abstract class BasePolicyComponent implements OnInit {
|
||||
@Input() policyResponse: PolicyResponse;
|
||||
@Input() policy: BasePolicy;
|
||||
@Input() policyResponse: PolicyResponse | undefined;
|
||||
@Input() policy: BasePolicy | undefined;
|
||||
|
||||
enabled = new UntypedFormControl(false);
|
||||
data: UntypedFormGroup = null;
|
||||
data: UntypedFormGroup | undefined;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.enabled.setValue(this.policyResponse.enabled);
|
||||
this.enabled.setValue(this.policyResponse?.enabled);
|
||||
|
||||
if (this.policyResponse.data != null) {
|
||||
if (this.policyResponse?.data != null) {
|
||||
this.loadData();
|
||||
}
|
||||
}
|
||||
|
||||
buildRequest() {
|
||||
const request = new PolicyRequest();
|
||||
request.enabled = this.enabled.value;
|
||||
request.type = this.policy.type;
|
||||
request.data = this.buildRequestData();
|
||||
if (!this.policy) {
|
||||
throw new Error("Policy was not found");
|
||||
}
|
||||
|
||||
const request: PolicyRequest = {
|
||||
type: this.policy.type,
|
||||
enabled: this.enabled.value,
|
||||
data: this.buildRequestData(),
|
||||
};
|
||||
|
||||
return Promise.resolve(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable optional validation before sumitting a respose for policy submission
|
||||
* */
|
||||
confirm(): Promise<boolean> | boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected loadData() {
|
||||
this.data.patchValue(this.policyResponse.data ?? {});
|
||||
this.data?.patchValue(this.policyResponse?.data ?? {});
|
||||
}
|
||||
|
||||
protected buildRequestData() {
|
||||
|
||||
@@ -3,6 +3,7 @@ export { BasePolicy, BasePolicyComponent } from "./base-policy.component";
|
||||
export { DisableSendPolicy } from "./disable-send.component";
|
||||
export { MasterPasswordPolicy } from "./master-password.component";
|
||||
export { PasswordGeneratorPolicy } from "./password-generator.component";
|
||||
export { vNextOrganizationDataOwnershipPolicy } from "./vnext-organization-data-ownership.component";
|
||||
export { OrganizationDataOwnershipPolicy } from "./organization-data-ownership.component";
|
||||
export { RequireSsoPolicy } from "./require-sso.component";
|
||||
export { ResetPasswordPolicy } from "./reset-password.component";
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { map, Observable } from "rxjs";
|
||||
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
|
||||
import { BasePolicy, BasePolicyComponent } from "./base-policy.component";
|
||||
|
||||
@@ -9,6 +13,12 @@ export class OrganizationDataOwnershipPolicy extends BasePolicy {
|
||||
description = "personalOwnershipPolicyDesc";
|
||||
type = PolicyType.OrganizationDataOwnership;
|
||||
component = OrganizationDataOwnershipPolicyComponent;
|
||||
|
||||
display(organization: Organization, configService: ConfigService): Observable<boolean> {
|
||||
return configService
|
||||
.getFeatureFlag$(FeatureFlag.CreateDefaultLocation)
|
||||
.pipe(map((enabled) => !enabled));
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -1,38 +1,45 @@
|
||||
<app-header>
|
||||
@let organization = organization$ | async;
|
||||
<button
|
||||
bitBadge
|
||||
class="!tw-align-middle"
|
||||
(click)="changePlan(organization)"
|
||||
*ngIf="isBreadcrumbingEnabled$ | async"
|
||||
slot="title-suffix"
|
||||
type="button"
|
||||
variant="primary"
|
||||
>
|
||||
{{ "upgrade" | i18n }}
|
||||
</button>
|
||||
@if (isBreadcrumbingEnabled$ | async) {
|
||||
<button
|
||||
bitBadge
|
||||
class="!tw-align-middle"
|
||||
(click)="changePlan(organization)"
|
||||
slot="title-suffix"
|
||||
type="button"
|
||||
variant="primary"
|
||||
>
|
||||
{{ "upgrade" | i18n }}
|
||||
</button>
|
||||
}
|
||||
</app-header>
|
||||
|
||||
<bit-container>
|
||||
<ng-container *ngIf="loading">
|
||||
@if (loading) {
|
||||
<i
|
||||
class="bwi bwi-spinner bwi-spin tw-text-muted"
|
||||
title="{{ 'loading' | i18n }}"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||
</ng-container>
|
||||
<bit-table *ngIf="!loading">
|
||||
<ng-template body>
|
||||
<tr bitRow *ngFor="let p of policies">
|
||||
<td bitCell *ngIf="p.display(organization)" ngPreserveWhitespaces>
|
||||
<button type="button" bitLink (click)="edit(p)">{{ p.name | i18n }}</button>
|
||||
<span bitBadge variant="success" *ngIf="policiesEnabledMap.get(p.type)">{{
|
||||
"on" | i18n
|
||||
}}</span>
|
||||
<small class="tw-text-muted tw-block">{{ p.description | i18n }}</small>
|
||||
</td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
</bit-table>
|
||||
}
|
||||
@if (!loading) {
|
||||
<bit-table>
|
||||
<ng-template body>
|
||||
@for (p of policies; track p.name) {
|
||||
@if (p.display(organization, configService) | async) {
|
||||
<tr bitRow>
|
||||
<td bitCell ngPreserveWhitespaces>
|
||||
<button type="button" bitLink (click)="edit(p)">{{ p.name | i18n }}</button>
|
||||
@if (policiesEnabledMap.get(p.type)) {
|
||||
<span bitBadge variant="success">{{ "on" | i18n }}</span>
|
||||
}
|
||||
<small class="tw-text-muted tw-block">{{ p.description | i18n }}</small>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
</ng-template>
|
||||
</bit-table>
|
||||
}
|
||||
</bit-container>
|
||||
|
||||
@@ -15,7 +15,6 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga
|
||||
import { PolicyResponse } from "@bitwarden/common/admin-console/models/response/policy.response";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { OrganizationBillingServiceAbstraction } from "@bitwarden/common/billing/abstractions";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
import {
|
||||
@@ -25,7 +24,7 @@ import {
|
||||
import { All } from "@bitwarden/web-vault/app/vault/individual-vault/vault-filter/shared/models/routed-vault-filter.model";
|
||||
|
||||
import { PolicyListService } from "../../core/policy-list.service";
|
||||
import { BasePolicy, RestrictedItemTypesPolicy } from "../policies";
|
||||
import { BasePolicy } from "../policies";
|
||||
import { CollectionDialogTabType } from "../shared/components/collection-dialog";
|
||||
|
||||
import { PolicyEditComponent, PolicyEditDialogResult } from "./policy-edit.component";
|
||||
@@ -53,7 +52,7 @@ export class PoliciesComponent implements OnInit {
|
||||
private policyListService: PolicyListService,
|
||||
private organizationBillingService: OrganizationBillingServiceAbstraction,
|
||||
private dialogService: DialogService,
|
||||
private configService: ConfigService,
|
||||
protected configService: ConfigService,
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
@@ -71,35 +70,31 @@ export class PoliciesComponent implements OnInit {
|
||||
await this.load();
|
||||
|
||||
// Handle policies component launch from Event message
|
||||
/* eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe, rxjs/no-nested-subscribe */
|
||||
this.route.queryParams.pipe(first()).subscribe(async (qParams) => {
|
||||
if (qParams.policyId != null) {
|
||||
const policyIdFromEvents: string = qParams.policyId;
|
||||
for (const orgPolicy of this.orgPolicies) {
|
||||
if (orgPolicy.id === policyIdFromEvents) {
|
||||
for (let i = 0; i < this.policies.length; i++) {
|
||||
if (this.policies[i].type === orgPolicy.type) {
|
||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this.edit(this.policies[i]);
|
||||
break;
|
||||
this.route.queryParams
|
||||
.pipe(first())
|
||||
/* eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe, rxjs/no-nested-subscribe */
|
||||
.subscribe(async (qParams) => {
|
||||
if (qParams.policyId != null) {
|
||||
const policyIdFromEvents: string = qParams.policyId;
|
||||
for (const orgPolicy of this.orgPolicies) {
|
||||
if (orgPolicy.id === policyIdFromEvents) {
|
||||
for (let i = 0; i < this.policies.length; i++) {
|
||||
if (this.policies[i].type === orgPolicy.type) {
|
||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this.edit(this.policies[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async load() {
|
||||
if (
|
||||
(await this.configService.getFeatureFlag(FeatureFlag.RemoveCardItemTypePolicy)) &&
|
||||
this.policyListService.getPolicies().every((p) => !(p instanceof RestrictedItemTypesPolicy))
|
||||
) {
|
||||
this.policyListService.addPolicies([new RestrictedItemTypesPolicy()]);
|
||||
}
|
||||
const response = await this.policyApiService.getPolicies(this.organizationId);
|
||||
this.orgPolicies = response.data != null && response.data.length > 0 ? response.data : [];
|
||||
this.orgPolicies.forEach((op) => {
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
||||
</div>
|
||||
<div [hidden]="loading">
|
||||
<p bitTypography="body1">{{ policy.description | i18n }}</p>
|
||||
@if (policy.showDescription) {
|
||||
<p bitTypography="body1">{{ policy.description | i18n }}</p>
|
||||
}
|
||||
<ng-template #policyForm></ng-template>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
@@ -128,13 +128,20 @@ export class PolicyEditComponent implements AfterViewInit {
|
||||
}
|
||||
|
||||
submit = async () => {
|
||||
if ((await this.policyComponent.confirm()) == false) {
|
||||
this.dialogRef.close();
|
||||
return;
|
||||
}
|
||||
|
||||
let request: PolicyRequest;
|
||||
|
||||
try {
|
||||
request = await this.policyComponent.buildRequest();
|
||||
} catch (e) {
|
||||
this.toastService.showToast({ variant: "error", title: null, message: e.message });
|
||||
return;
|
||||
}
|
||||
|
||||
await this.policyApiService.putPolicy(this.data.organizationId, this.data.policy.type, request);
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { of } from "rxjs";
|
||||
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
|
||||
import { BasePolicy, BasePolicyComponent } from "./base-policy.component";
|
||||
|
||||
@@ -11,8 +13,8 @@ export class RequireSsoPolicy extends BasePolicy {
|
||||
type = PolicyType.RequireSso;
|
||||
component = RequireSsoPolicyComponent;
|
||||
|
||||
display(organization: Organization) {
|
||||
return organization.useSso;
|
||||
display(organization: Organization, configService: ConfigService) {
|
||||
return of(organization.useSso);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { FormBuilder } from "@angular/forms";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
import { firstValueFrom, of } from "rxjs";
|
||||
|
||||
import {
|
||||
getOrganizationById,
|
||||
@@ -10,6 +10,7 @@ import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
|
||||
import { BasePolicy, BasePolicyComponent } from "./base-policy.component";
|
||||
|
||||
@@ -19,8 +20,8 @@ export class ResetPasswordPolicy extends BasePolicy {
|
||||
type = PolicyType.ResetPassword;
|
||||
component = ResetPasswordPolicyComponent;
|
||||
|
||||
display(organization: Organization) {
|
||||
return organization.useResetPassword;
|
||||
display(organization: Organization, configService: ConfigService) {
|
||||
return of(organization.useResetPassword);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +53,10 @@ export class ResetPasswordPolicyComponent extends BasePolicyComponent implements
|
||||
throw new Error("No user found.");
|
||||
}
|
||||
|
||||
if (!this.policyResponse) {
|
||||
throw new Error("Policies not found");
|
||||
}
|
||||
|
||||
const organization = await firstValueFrom(
|
||||
this.organizationService
|
||||
.organizations$(userId)
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { Observable } from "rxjs";
|
||||
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
|
||||
import { BasePolicy, BasePolicyComponent } from "./base-policy.component";
|
||||
|
||||
@@ -9,6 +13,10 @@ export class RestrictedItemTypesPolicy extends BasePolicy {
|
||||
description = "restrictedItemTypePolicyDesc";
|
||||
type = PolicyType.RestrictedItemTypes;
|
||||
component = RestrictedItemTypesPolicyComponent;
|
||||
|
||||
display(organization: Organization, configService: ConfigService): Observable<boolean> {
|
||||
return configService.getFeatureFlag$(FeatureFlag.RemoveCardItemTypePolicy);
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -20,6 +20,9 @@ export class SingleOrgPolicyComponent extends BasePolicyComponent implements OnI
|
||||
async ngOnInit() {
|
||||
super.ngOnInit();
|
||||
|
||||
if (!this.policyResponse) {
|
||||
throw new Error("Policies not found");
|
||||
}
|
||||
if (!this.policyResponse.canToggleState) {
|
||||
this.enabled.disable();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<p>
|
||||
{{ "organizationDataOwnershipContent" | i18n }}
|
||||
<a
|
||||
bitLink
|
||||
href="https://bitwarden.com/resources/credential-lifecycle-management/"
|
||||
target="_blank"
|
||||
>
|
||||
{{ "organizationDataOwnershipContentAnchor" | i18n }}.
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<bit-form-control>
|
||||
<input type="checkbox" bitCheckbox [formControl]="enabled" id="enabled" />
|
||||
<bit-label>{{ "turnOn" | i18n }}</bit-label>
|
||||
</bit-form-control>
|
||||
|
||||
<ng-template #dialog>
|
||||
<bit-simple-dialog background="alt">
|
||||
<span bitDialogTitle>{{ "organizationDataOwnershipWarningTitle" | i18n }}</span>
|
||||
<ng-container bitDialogContent>
|
||||
<div class="tw-text-left tw-overflow-hidden">
|
||||
{{ "organizationDataOwnershipWarningContentTop" | i18n }}
|
||||
<div class="tw-flex tw-flex-col tw-p-2">
|
||||
<ul class="tw-list-disc tw-pl-5 tw-space-y-2 tw-break-words tw-mb-0">
|
||||
<li>
|
||||
{{ "organizationDataOwnershipWarning1" | i18n }}
|
||||
</li>
|
||||
<li>
|
||||
{{ "organizationDataOwnershipWarning2" | i18n }}
|
||||
</li>
|
||||
<li>
|
||||
{{ "organizationDataOwnershipWarning3" | i18n }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{{ "organizationDataOwnershipWarningContentBottom" | i18n }}
|
||||
<a
|
||||
bitLink
|
||||
href="https://bitwarden.com/resources/credential-lifecycle-management/"
|
||||
target="_blank"
|
||||
>
|
||||
{{ "organizationDataOwnershipContentAnchor" | i18n }}.
|
||||
</a>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container bitDialogFooter>
|
||||
<span class="tw-flex tw-gap-2">
|
||||
<button bitButton buttonType="primary" [bitDialogClose]="true" type="submit">
|
||||
{{ "continue" | i18n }}
|
||||
</button>
|
||||
<button bitButton buttonType="secondary" [bitDialogClose]="false" type="button">
|
||||
{{ "cancel" | i18n }}
|
||||
</button>
|
||||
</span>
|
||||
</ng-container>
|
||||
</bit-simple-dialog>
|
||||
</ng-template>
|
||||
@@ -0,0 +1,50 @@
|
||||
import { Component, OnInit, TemplateRef, ViewChild } from "@angular/core";
|
||||
import { lastValueFrom, Observable } from "rxjs";
|
||||
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
|
||||
import { SharedModule } from "../../../shared";
|
||||
|
||||
import { BasePolicy, BasePolicyComponent } from "./base-policy.component";
|
||||
|
||||
export class vNextOrganizationDataOwnershipPolicy extends BasePolicy {
|
||||
name = "organizationDataOwnership";
|
||||
description = "organizationDataOwnershipDesc";
|
||||
type = PolicyType.OrganizationDataOwnership;
|
||||
component = vNextOrganizationDataOwnershipPolicyComponent;
|
||||
showDescription = false;
|
||||
|
||||
override display(organization: Organization, configService: ConfigService): Observable<boolean> {
|
||||
return configService.getFeatureFlag$(FeatureFlag.CreateDefaultLocation);
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: "vnext-policy-organization-data-ownership",
|
||||
templateUrl: "vnext-organization-data-ownership.component.html",
|
||||
standalone: true,
|
||||
imports: [SharedModule],
|
||||
})
|
||||
export class vNextOrganizationDataOwnershipPolicyComponent
|
||||
extends BasePolicyComponent
|
||||
implements OnInit
|
||||
{
|
||||
constructor(private dialogService: DialogService) {
|
||||
super();
|
||||
}
|
||||
|
||||
@ViewChild("dialog", { static: true }) warningContent!: TemplateRef<unknown>;
|
||||
|
||||
override async confirm(): Promise<boolean> {
|
||||
if (this.policyResponse?.enabled && !this.enabled.value) {
|
||||
const dialogRef = this.dialogService.open(this.warningContent);
|
||||
const result = await lastValueFrom(dialogRef.closed);
|
||||
return Boolean(result);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -35,12 +35,14 @@ import {
|
||||
MasterPasswordPolicy,
|
||||
PasswordGeneratorPolicy,
|
||||
OrganizationDataOwnershipPolicy,
|
||||
vNextOrganizationDataOwnershipPolicy,
|
||||
RequireSsoPolicy,
|
||||
ResetPasswordPolicy,
|
||||
SendOptionsPolicy,
|
||||
SingleOrgPolicy,
|
||||
TwoFactorAuthenticationPolicy,
|
||||
RemoveUnlockWithPinPolicy,
|
||||
RestrictedItemTypesPolicy,
|
||||
} from "./admin-console/organizations/policies";
|
||||
|
||||
const BroadcasterSubscriptionId = "AppComponent";
|
||||
@@ -244,8 +246,10 @@ export class AppComponent implements OnDestroy, OnInit {
|
||||
new SingleOrgPolicy(),
|
||||
new RequireSsoPolicy(),
|
||||
new OrganizationDataOwnershipPolicy(),
|
||||
new vNextOrganizationDataOwnershipPolicy(),
|
||||
new DisableSendPolicy(),
|
||||
new SendOptionsPolicy(),
|
||||
new RestrictedItemTypesPolicy(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -5429,6 +5429,37 @@
|
||||
"organizationDataOwnership": {
|
||||
"message": "Enforce organization data ownership"
|
||||
},
|
||||
"organizationDataOwnershipDesc": {
|
||||
"message": "Require all items to be owned by an organization, removing the option to store items at the account level.",
|
||||
"description": "This is the policy description shown in the policy list."
|
||||
},
|
||||
"organizationDataOwnershipContent": {
|
||||
"message": "All items will be owned and saved to the organization, enabling organization-wide controls, visibility, and reporting. When turned on, a default collection be available for each member to store items. Learn more about managing the ",
|
||||
"description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'All items will be owned and saved to the organization, enabling organization-wide controls, visibility, and reporting. When turned on, a default collection be available for each member to store items. Learn more about managing the credential lifecycle.'"
|
||||
},
|
||||
"organizationDataOwnershipContentAnchor":{
|
||||
"message": "credential lifecycle",
|
||||
"description": "This will be used as a hyperlink"
|
||||
},
|
||||
"organizationDataOwnershipWarningTitle":{
|
||||
"message": "Are you sure you want to proceed?"
|
||||
},
|
||||
"organizationDataOwnershipWarning1":{
|
||||
"message": "will remain accessible to members"
|
||||
},
|
||||
"organizationDataOwnershipWarning2":{
|
||||
"message": "will not be automatically selected when creating new items"
|
||||
},
|
||||
"organizationDataOwnershipWarning3":{
|
||||
"message": "cannot be managed from the Admin Console until the user is offboarded"
|
||||
},
|
||||
"organizationDataOwnershipWarningContentTop":{
|
||||
"message": "By turning this policy off, the default collection: "
|
||||
},
|
||||
"organizationDataOwnershipWarningContentBottom":{
|
||||
"message": "Learn more about the ",
|
||||
"description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more about the credential lifecycle.'"
|
||||
},
|
||||
"personalOwnership": {
|
||||
"message": "Remove individual vault"
|
||||
},
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { of } from "rxjs";
|
||||
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import {
|
||||
BasePolicy,
|
||||
BasePolicyComponent,
|
||||
@@ -13,8 +15,8 @@ export class ActivateAutofillPolicy extends BasePolicy {
|
||||
type = PolicyType.ActivateAutofill;
|
||||
component = ActivateAutofillPolicyComponent;
|
||||
|
||||
display(organization: Organization) {
|
||||
return organization.useActivateAutofillPolicy;
|
||||
display(organization: Organization, configService: ConfigService) {
|
||||
return of(organization.useActivateAutofillPolicy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { PolicyType } from "../../enums";
|
||||
|
||||
export class PolicyRequest {
|
||||
export type PolicyRequest = {
|
||||
type: PolicyType;
|
||||
enabled: boolean;
|
||||
data: any;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user