mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-22 16:29:09 +01:00
add check for PersonalOwnershipPolicy in vault filters (#9570)
This commit is contained in:
parent
d594b680f9
commit
cbc34950fb
@ -3,6 +3,8 @@ import { FormBuilder } from "@angular/forms";
|
||||
import { BehaviorSubject, skipWhile } from "rxjs";
|
||||
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { ProductType } from "@bitwarden/common/enums";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
@ -23,6 +25,7 @@ describe("VaultPopupListFiltersService", () => {
|
||||
const folderViews$ = new BehaviorSubject([]);
|
||||
const cipherViews$ = new BehaviorSubject({});
|
||||
const decryptedCollections$ = new BehaviorSubject<CollectionView[]>([]);
|
||||
const policyAppliesToActiveUser$ = new BehaviorSubject<boolean>(false);
|
||||
|
||||
const collectionService = {
|
||||
decryptedCollections$,
|
||||
@ -45,9 +48,15 @@ describe("VaultPopupListFiltersService", () => {
|
||||
t: (key: string) => key,
|
||||
} as I18nService;
|
||||
|
||||
const policyService = {
|
||||
policyAppliesToActiveUser$: jest.fn(() => policyAppliesToActiveUser$),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
memberOrganizations$.next([]);
|
||||
decryptedCollections$.next([]);
|
||||
policyAppliesToActiveUser$.next(false);
|
||||
policyService.policyAppliesToActiveUser$.mockClear();
|
||||
|
||||
collectionService.getAllNested = () => Promise.resolve([]);
|
||||
TestBed.configureTestingModule({
|
||||
@ -72,6 +81,10 @@ describe("VaultPopupListFiltersService", () => {
|
||||
provide: CollectionService,
|
||||
useValue: collectionService,
|
||||
},
|
||||
{
|
||||
provide: PolicyService,
|
||||
useValue: policyService,
|
||||
},
|
||||
{ provide: FormBuilder, useClass: FormBuilder },
|
||||
],
|
||||
});
|
||||
@ -127,6 +140,65 @@ describe("VaultPopupListFiltersService", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("PersonalOwnership policy", () => {
|
||||
it('calls policyAppliesToActiveUser$ with "PersonalOwnership"', () => {
|
||||
expect(policyService.policyAppliesToActiveUser$).toHaveBeenCalledWith(
|
||||
PolicyType.PersonalOwnership,
|
||||
);
|
||||
});
|
||||
|
||||
it("returns an empty array when the policy applies and there is a single organization", (done) => {
|
||||
policyAppliesToActiveUser$.next(true);
|
||||
memberOrganizations$.next([
|
||||
{ name: "bobby's org", id: "1234-3323-23223" },
|
||||
] as Organization[]);
|
||||
|
||||
service.organizations$.subscribe((organizations) => {
|
||||
expect(organizations).toEqual([]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('adds "myVault" when the policy does not apply and there are multiple organizations', (done) => {
|
||||
policyAppliesToActiveUser$.next(false);
|
||||
const orgs = [
|
||||
{ name: "bobby's org", id: "1234-3323-23223" },
|
||||
{ name: "alice's org", id: "2223-4343-99888" },
|
||||
] as Organization[];
|
||||
|
||||
memberOrganizations$.next(orgs);
|
||||
|
||||
service.organizations$.subscribe((organizations) => {
|
||||
expect(organizations.map((o) => o.label)).toEqual([
|
||||
"myVault",
|
||||
"alice's org",
|
||||
"bobby's org",
|
||||
]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('does not add "myVault" the policy applies and there are multiple organizations', (done) => {
|
||||
policyAppliesToActiveUser$.next(true);
|
||||
const orgs = [
|
||||
{ name: "bobby's org", id: "1234-3323-23223" },
|
||||
{ name: "alice's org", id: "2223-3242-99888" },
|
||||
{ name: "catherine's org", id: "77733-4343-99888" },
|
||||
] as Organization[];
|
||||
|
||||
memberOrganizations$.next(orgs);
|
||||
|
||||
service.organizations$.subscribe((organizations) => {
|
||||
expect(organizations.map((o) => o.label)).toEqual([
|
||||
"alice's org",
|
||||
"bobby's org",
|
||||
"catherine's org",
|
||||
]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("icons", () => {
|
||||
it("sets family icon for family organizations", (done) => {
|
||||
const orgs = [
|
||||
|
@ -13,6 +13,8 @@ import {
|
||||
|
||||
import { DynamicTreeNode } from "@bitwarden/angular/vault/vault-filter/models/dynamic-tree-node.model";
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { ProductType } from "@bitwarden/common/enums";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
@ -88,6 +90,7 @@ export class VaultPopupListFiltersService {
|
||||
private i18nService: I18nService,
|
||||
private collectionService: CollectionService,
|
||||
private formBuilder: FormBuilder,
|
||||
private policyService: PolicyService,
|
||||
) {
|
||||
this.filterForm.controls.organization.valueChanges
|
||||
.pipe(takeUntilDestroyed())
|
||||
@ -167,44 +170,63 @@ export class VaultPopupListFiltersService {
|
||||
/**
|
||||
* Organization array structured to be directly passed to `ChipSelectComponent`
|
||||
*/
|
||||
organizations$: Observable<ChipSelectOption<Organization>[]> =
|
||||
this.organizationService.memberOrganizations$.pipe(
|
||||
map((orgs) => orgs.sort(Utils.getSortFunction(this.i18nService, "name"))),
|
||||
map((orgs) => {
|
||||
if (!orgs.length) {
|
||||
return [];
|
||||
}
|
||||
organizations$: Observable<ChipSelectOption<Organization>[]> = combineLatest([
|
||||
this.organizationService.memberOrganizations$,
|
||||
this.policyService.policyAppliesToActiveUser$(PolicyType.PersonalOwnership),
|
||||
]).pipe(
|
||||
map(([orgs, personalOwnershipApplies]): [Organization[], boolean] => [
|
||||
orgs.sort(Utils.getSortFunction(this.i18nService, "name")),
|
||||
personalOwnershipApplies,
|
||||
]),
|
||||
map(([orgs, personalOwnershipApplies]) => {
|
||||
// When there are no organizations return an empty array,
|
||||
// resulting in the org filter being hidden
|
||||
if (!orgs.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
// When the user is a member of an organization, make the "My Vault" option available
|
||||
{
|
||||
value: { id: MY_VAULT_ID } as Organization,
|
||||
label: this.i18nService.t("myVault"),
|
||||
icon: "bwi-user",
|
||||
},
|
||||
...orgs.map((org) => {
|
||||
let icon = "bwi-business";
|
||||
// When there is only one organization and personal ownership policy applies,
|
||||
// return an empty array, resulting in the org filter being hidden
|
||||
if (orgs.length === 1 && personalOwnershipApplies) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!org.enabled) {
|
||||
// Show a warning icon if the organization is deactivated
|
||||
icon = "bwi-exclamation-triangle tw-text-danger";
|
||||
} else if (
|
||||
org.planProductType === ProductType.Families ||
|
||||
org.planProductType === ProductType.Free
|
||||
) {
|
||||
// Show a family icon if the organization is a family or free org
|
||||
icon = "bwi-family";
|
||||
}
|
||||
const myVaultOrg: ChipSelectOption<Organization>[] = [];
|
||||
|
||||
return {
|
||||
value: org,
|
||||
label: org.name,
|
||||
icon,
|
||||
};
|
||||
}),
|
||||
];
|
||||
}),
|
||||
);
|
||||
// Only add "My vault" if personal ownership policy does not apply
|
||||
if (!personalOwnershipApplies) {
|
||||
myVaultOrg.push({
|
||||
value: { id: MY_VAULT_ID } as Organization,
|
||||
label: this.i18nService.t("myVault"),
|
||||
icon: "bwi-user",
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
...myVaultOrg,
|
||||
...orgs.map((org) => {
|
||||
let icon = "bwi-business";
|
||||
|
||||
if (!org.enabled) {
|
||||
// Show a warning icon if the organization is deactivated
|
||||
icon = "bwi-exclamation-triangle tw-text-danger";
|
||||
} else if (
|
||||
org.planProductType === ProductType.Families ||
|
||||
org.planProductType === ProductType.Free
|
||||
) {
|
||||
// Show a family icon if the organization is a family or free org
|
||||
icon = "bwi-family";
|
||||
}
|
||||
|
||||
return {
|
||||
value: org,
|
||||
label: org.name,
|
||||
icon,
|
||||
};
|
||||
}),
|
||||
];
|
||||
}),
|
||||
);
|
||||
|
||||
/**
|
||||
* Folder array structured to be directly passed to `ChipSelectComponent`
|
||||
|
Loading…
Reference in New Issue
Block a user