diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 35704fc289f..a14d43fd218 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -786,6 +786,7 @@ export default class MainBackground { this.kdfConfigService, this.keyService, this.stateProvider, + this.configService, ); this.passwordStrengthService = new PasswordStrengthService(); diff --git a/apps/cli/src/service-container/service-container.ts b/apps/cli/src/service-container/service-container.ts index 27fde5863de..e3359c17b91 100644 --- a/apps/cli/src/service-container/service-container.ts +++ b/apps/cli/src/service-container/service-container.ts @@ -602,6 +602,7 @@ export class ServiceContainer { this.kdfConfigService, this.keyService, this.stateProvider, + this.configService, customUserAgent, ); diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 72bdd9f8b2f..4920acc1ba4 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -1500,6 +1500,7 @@ const safeProviders: SafeProvider[] = [ KdfConfigService, KeyService, StateProvider, + ConfigService, ], }), safeProvider({ diff --git a/libs/common/src/platform/services/sdk/default-sdk.service.spec.ts b/libs/common/src/platform/services/sdk/default-sdk.service.spec.ts index 2b94305f0ec..2f6c32aa78d 100644 --- a/libs/common/src/platform/services/sdk/default-sdk.service.spec.ts +++ b/libs/common/src/platform/services/sdk/default-sdk.service.spec.ts @@ -1,6 +1,7 @@ import { mock, MockProxy } from "jest-mock-extended"; import { BehaviorSubject, firstValueFrom, of } from "rxjs"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; // This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop. // eslint-disable-next-line no-restricted-imports import { KdfConfigService, KeyService, PBKDF2KdfConfig } from "@bitwarden/key-management"; @@ -41,6 +42,7 @@ describe("DefaultSdkService", () => { let platformUtilsService!: MockProxy; let kdfConfigService!: MockProxy; let keyService!: MockProxy; + let configService!: MockProxy; let service!: DefaultSdkService; let accountService!: FakeAccountService; let fakeStateProvider!: FakeStateProvider; @@ -56,6 +58,9 @@ describe("DefaultSdkService", () => { const mockUserId = Utils.newGuid() as UserId; accountService = mockAccountServiceWith(mockUserId); fakeStateProvider = new FakeStateProvider(accountService); + configService = mock(); + + configService.serverConfig$ = new BehaviorSubject(null); // Can't use `of(mock())` for some reason environmentService.environment$ = new BehaviorSubject(mock()); @@ -68,6 +73,7 @@ describe("DefaultSdkService", () => { kdfConfigService, keyService, fakeStateProvider, + configService, ); }); diff --git a/libs/common/src/platform/services/sdk/default-sdk.service.ts b/libs/common/src/platform/services/sdk/default-sdk.service.ts index 9d965acb44b..210e1bdc59b 100644 --- a/libs/common/src/platform/services/sdk/default-sdk.service.ts +++ b/libs/common/src/platform/services/sdk/default-sdk.service.ts @@ -12,8 +12,10 @@ import { of, takeWhile, throwIfEmpty, + firstValueFrom, } from "rxjs"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; // This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop. // eslint-disable-next-line no-restricted-imports import { KeyService, KdfConfigService, KdfConfig, KdfType } from "@bitwarden/key-management"; @@ -67,7 +69,9 @@ export class DefaultSdkService implements SdkService { concatMap(async (env) => { await SdkLoadService.Ready; const settings = this.toSettings(env); - return await this.sdkClientFactory.createSdkClient(new JsTokenProvider(), settings); + const client = await this.sdkClientFactory.createSdkClient(new JsTokenProvider(), settings); + await this.loadFeatureFlags(client); + return client; }), shareReplay({ refCount: true, bufferSize: 1 }), ); @@ -85,6 +89,7 @@ export class DefaultSdkService implements SdkService { private kdfConfigService: KdfConfigService, private keyService: KeyService, private stateProvider: StateProvider, + private configService: ConfigService, private userAgent: string | null = null, ) {} @@ -248,6 +253,20 @@ export class DefaultSdkService implements SdkService { // Initialize the SDK managed database and the client managed repositories. await initializeState(userId, client.platform().state(), this.stateProvider); + + await this.loadFeatureFlags(client); + } + + private async loadFeatureFlags(client: BitwardenClient) { + const serverConfig = await firstValueFrom(this.configService.serverConfig$); + + const featureFlagMap = new Map( + Object.entries(serverConfig?.featureStates ?? {}) + .filter(([, value]) => typeof value === "boolean") // The SDK only supports boolean feature flags at this time + .map(([key, value]) => [key, value] as [string, boolean]), + ); + + client.platform().load_flags(featureFlagMap); } private toSettings(env: Environment): ClientSettings {