1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-11 05:43:41 +00:00

[PM-24689] Handle possible null active account (#16006)

This commit is contained in:
Shane Melton
2025-08-13 11:58:55 -07:00
committed by GitHub
parent e9d7f58da9
commit d825b5c6e5
2 changed files with 41 additions and 30 deletions

View File

@@ -67,6 +67,13 @@ describe("RestrictedItemTypesService", () => {
expect(result).toEqual([]);
});
it("emits empty array if no account is active", async () => {
accountService.activeAccount$ = of(null);
const result = await firstValueFrom(service.restricted$);
expect(result).toEqual([]);
});
it("emits empty array if no organizations exist", async () => {
organizationService.organizations$.mockReturnValue(of([]));
policyService.policiesByType$.mockReturnValue(of([]));

View File

@@ -5,7 +5,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { PolicyType } from "@bitwarden/common/admin-console/enums";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { getUserId } from "@bitwarden/common/auth/services/account.service";
import { getOptionalUserId } from "@bitwarden/common/auth/services/account.service";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { CipherType } from "@bitwarden/common/vault/enums";
@@ -32,39 +32,43 @@ export class RestrictedItemTypesService {
return of([]);
}
return this.accountService.activeAccount$.pipe(
getUserId,
switchMap((userId) =>
combineLatest([
getOptionalUserId,
switchMap((userId) => {
if (userId == null) {
return of([]); // No user logged in, no restrictions
}
return combineLatest([
this.organizationService.organizations$(userId),
this.policyService.policiesByType$(PolicyType.RestrictedItemTypes, userId),
]),
),
map(([orgs, enabledPolicies]) => {
// Helper to extract restricted types, defaulting to [Card]
const restrictedTypes = (p: (typeof enabledPolicies)[number]) =>
(p.data as CipherType[]) ?? [CipherType.Card];
]).pipe(
map(([orgs, enabledPolicies]) => {
// Helper to extract restricted types, defaulting to [Card]
const restrictedTypes = (p: (typeof enabledPolicies)[number]) =>
(p.data as CipherType[]) ?? [CipherType.Card];
// Union across all enabled policies
const allRestrictedTypes = Array.from(
new Set(enabledPolicies.flatMap(restrictedTypes)),
// Union across all enabled policies
const allRestrictedTypes = Array.from(
new Set(enabledPolicies.flatMap(restrictedTypes)),
);
return allRestrictedTypes.map((cipherType) => {
// Determine which orgs allow viewing this type
const allowViewOrgIds = orgs
.filter((org) => {
const orgPolicy = enabledPolicies.find((p) => p.organizationId === org.id);
// no policy for this org => allows everything
if (!orgPolicy) {
return true;
}
// if this type not in their restricted list => they allow it
return !restrictedTypes(orgPolicy).includes(cipherType);
})
.map((org) => org.id);
return { cipherType, allowViewOrgIds };
});
}),
);
return allRestrictedTypes.map((cipherType) => {
// Determine which orgs allow viewing this type
const allowViewOrgIds = orgs
.filter((org) => {
const orgPolicy = enabledPolicies.find((p) => p.organizationId === org.id);
// no policy for this org => allows everything
if (!orgPolicy) {
return true;
}
// if this type not in their restricted list => they allow it
return !restrictedTypes(orgPolicy).includes(cipherType);
})
.map((org) => org.id);
return { cipherType, allowViewOrgIds };
});
}),
);
}),