1
0
mirror of https://github.com/bitwarden/browser synced 2026-01-02 00:23:35 +00:00

[PM-24011] Add handler for new policy sync push notification (#17465)

* add handler for new policy sync push notification

* fix story book build failure

* move logic into policy service, fix tests

* add account service

* add missing service to clie
This commit is contained in:
Brandon Treston
2025-12-01 10:21:48 -05:00
committed by GitHub
parent e1d14ca7bd
commit b9d5724312
11 changed files with 131 additions and 8 deletions

View File

@@ -101,4 +101,9 @@ export abstract class InternalPolicyService extends PolicyService {
* Replace a policy in the local sync data. This does not update any policies on the server.
*/
abstract replace: (policies: { [id: string]: PolicyData }, userId: UserId) => Promise<void>;
/**
* Wrapper around upsert that uses account service to sync policies for the logged in user. This comes from
* the server push notification to update local policies.
*/
abstract syncPolicy: (payload: PolicyData) => Promise<void>;
}

View File

@@ -1,6 +1,8 @@
import { mock, MockProxy } from "jest-mock-extended";
import { firstValueFrom, of } from "rxjs";
import { newGuid } from "@bitwarden/guid";
import { FakeStateProvider, mockAccountServiceWith } from "../../../../spec";
import { FakeSingleUserState } from "../../../../spec/fake-state";
import {
@@ -22,15 +24,15 @@ import { DefaultPolicyService, getFirstPolicy } from "./default-policy.service";
import { POLICIES } from "./policy-state";
describe("PolicyService", () => {
const userId = "userId" as UserId;
const userId = newGuid() as UserId;
let stateProvider: FakeStateProvider;
let organizationService: MockProxy<OrganizationService>;
let singleUserState: FakeSingleUserState<Record<PolicyId, PolicyData>>;
const accountService = mockAccountServiceWith(userId);
let policyService: DefaultPolicyService;
beforeEach(() => {
const accountService = mockAccountServiceWith(userId);
stateProvider = new FakeStateProvider(accountService);
organizationService = mock<OrganizationService>();
singleUserState = stateProvider.singleUser.getFake(userId, POLICIES);
@@ -59,7 +61,7 @@ describe("PolicyService", () => {
organizationService.organizations$.calledWith(userId).mockReturnValue(organizations$);
policyService = new DefaultPolicyService(stateProvider, organizationService);
policyService = new DefaultPolicyService(stateProvider, organizationService, accountService);
});
it("upsert", async () => {
@@ -635,7 +637,7 @@ describe("PolicyService", () => {
beforeEach(() => {
stateProvider = new FakeStateProvider(mockAccountServiceWith(userId));
organizationService = mock<OrganizationService>();
policyService = new DefaultPolicyService(stateProvider, organizationService);
policyService = new DefaultPolicyService(stateProvider, organizationService, accountService);
});
it("returns undefined when there are no policies", () => {

View File

@@ -1,4 +1,7 @@
import { combineLatest, map, Observable, of } from "rxjs";
import { combineLatest, firstValueFrom, map, Observable, of, switchMap } from "rxjs";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { getUserId } from "@bitwarden/common/auth/services/account.service";
import { StateProvider } from "../../../platform/state";
import { UserId } from "../../../types/guid";
@@ -25,6 +28,7 @@ export class DefaultPolicyService implements PolicyService {
constructor(
private stateProvider: StateProvider,
private organizationService: OrganizationService,
private accountService: AccountService,
) {}
private policyState(userId: UserId) {
@@ -326,4 +330,13 @@ export class DefaultPolicyService implements PolicyService {
target.enforceOnLogin = Boolean(target.enforceOnLogin || source.enforceOnLogin);
}
}
async syncPolicy(policyData: PolicyData) {
await firstValueFrom(
this.accountService.activeAccount$.pipe(
getUserId,
switchMap((userId) => this.upsert(policyData, userId)),
),
);
}
}