mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 07:43:35 +00:00
[PM-5535] Migrate Environment Service to StateProvider (#7621)
* Migrate EnvironmentService * Move Migration Test Helper * Claim StateDefinition * Add State Migration * Update StateServices * Update EnvironmentService Abstraction * Update DI * Update Browser Instantiation * Fix BrowserEnvironmentService * Update Desktop & CLI Instantiation * Update Usage * Create isStringRecord helper * Fix Old Tests * Use Existing AccountService * Don't Rely on Parameter Mutation * Fix Conflicts
This commit is contained in:
@@ -344,6 +344,11 @@ export default class MainBackground {
|
||||
this.globalStateProvider,
|
||||
this.derivedStateProvider,
|
||||
);
|
||||
this.environmentService = new BrowserEnvironmentService(
|
||||
this.logService,
|
||||
this.stateProvider,
|
||||
this.accountService,
|
||||
);
|
||||
this.stateService = new BrowserStateService(
|
||||
this.storageService,
|
||||
this.secureStorageService,
|
||||
@@ -351,6 +356,7 @@ export default class MainBackground {
|
||||
this.logService,
|
||||
new StateFactory(GlobalState, Account),
|
||||
this.accountService,
|
||||
this.environmentService,
|
||||
);
|
||||
this.platformUtilsService = new BrowserPlatformUtilsService(
|
||||
this.messagingService,
|
||||
@@ -386,7 +392,6 @@ export default class MainBackground {
|
||||
);
|
||||
this.tokenService = new TokenService(this.stateService);
|
||||
this.appIdService = new AppIdService(this.storageService);
|
||||
this.environmentService = new BrowserEnvironmentService(this.stateService, this.logService);
|
||||
this.apiService = new ApiService(
|
||||
this.tokenService,
|
||||
this.platformUtilsService,
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import {
|
||||
accountServiceFactory,
|
||||
AccountServiceInitOptions,
|
||||
} from "../../../auth/background/service-factories/account-service.factory";
|
||||
import { BrowserEnvironmentService } from "../../services/browser-environment.service";
|
||||
|
||||
import { CachedServices, factory, FactoryOptions } from "./factory-options";
|
||||
import { logServiceFactory, LogServiceInitOptions } from "./log-service.factory";
|
||||
import {
|
||||
stateServiceFactory as stateServiceFactory,
|
||||
StateServiceInitOptions,
|
||||
} from "./state-service.factory";
|
||||
import { stateProviderFactory, StateProviderInitOptions } from "./state-provider.factory";
|
||||
|
||||
type EnvironmentServiceFactoryOptions = FactoryOptions;
|
||||
|
||||
export type EnvironmentServiceInitOptions = EnvironmentServiceFactoryOptions &
|
||||
StateServiceInitOptions &
|
||||
StateProviderInitOptions &
|
||||
AccountServiceInitOptions &
|
||||
LogServiceInitOptions;
|
||||
|
||||
export function environmentServiceFactory(
|
||||
@@ -23,8 +25,9 @@ export function environmentServiceFactory(
|
||||
opts,
|
||||
async () =>
|
||||
new BrowserEnvironmentService(
|
||||
await stateServiceFactory(cache, opts),
|
||||
await logServiceFactory(cache, opts),
|
||||
await stateProviderFactory(cache, opts),
|
||||
await accountServiceFactory(cache, opts),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@ import {
|
||||
import { Account } from "../../../models/account";
|
||||
import { BrowserStateService } from "../../services/browser-state.service";
|
||||
|
||||
import {
|
||||
environmentServiceFactory,
|
||||
EnvironmentServiceInitOptions,
|
||||
} from "./environment-service.factory";
|
||||
import { CachedServices, factory, FactoryOptions } from "./factory-options";
|
||||
import { logServiceFactory, LogServiceInitOptions } from "./log-service.factory";
|
||||
import {
|
||||
@@ -31,7 +35,8 @@ export type StateServiceInitOptions = StateServiceFactoryOptions &
|
||||
SecureStorageServiceInitOptions &
|
||||
MemoryStorageServiceInitOptions &
|
||||
LogServiceInitOptions &
|
||||
AccountServiceInitOptions;
|
||||
AccountServiceInitOptions &
|
||||
EnvironmentServiceInitOptions;
|
||||
|
||||
export async function stateServiceFactory(
|
||||
cache: { stateService?: BrowserStateService } & CachedServices,
|
||||
@@ -42,13 +47,14 @@ export async function stateServiceFactory(
|
||||
"stateService",
|
||||
opts,
|
||||
async () =>
|
||||
await new BrowserStateService(
|
||||
new BrowserStateService(
|
||||
await diskStorageServiceFactory(cache, opts),
|
||||
await secureStorageServiceFactory(cache, opts),
|
||||
await memoryStorageServiceFactory(cache, opts),
|
||||
await logServiceFactory(cache, opts),
|
||||
opts.stateServiceOptions.stateFactory,
|
||||
await accountServiceFactory(cache, opts),
|
||||
await environmentServiceFactory(cache, opts),
|
||||
opts.stateServiceOptions.useAccountCache,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { EnvironmentService } from "@bitwarden/common/platform/services/environment.service";
|
||||
import { StateProvider } from "@bitwarden/common/platform/state";
|
||||
|
||||
import { GroupPolicyEnvironment } from "../../admin-console/types/group-policy-environment";
|
||||
import { devFlagEnabled, devFlagValue } from "../flags";
|
||||
|
||||
export class BrowserEnvironmentService extends EnvironmentService {
|
||||
constructor(
|
||||
stateService: StateService,
|
||||
private logService: LogService,
|
||||
stateProvider: StateProvider,
|
||||
accountService: AccountService,
|
||||
) {
|
||||
super(stateService);
|
||||
super(stateProvider, accountService);
|
||||
}
|
||||
|
||||
async hasManagedEnvironment(): Promise<boolean> {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { mock, MockProxy } from "jest-mock-extended";
|
||||
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import {
|
||||
AbstractMemoryStorageService,
|
||||
@@ -29,6 +30,7 @@ describe("Browser State Service", () => {
|
||||
let stateFactory: MockProxy<StateFactory<GlobalState, Account>>;
|
||||
let useAccountCache: boolean;
|
||||
let accountService: MockProxy<AccountService>;
|
||||
let environmentService: MockProxy<EnvironmentService>;
|
||||
|
||||
let state: State<GlobalState, Account>;
|
||||
const userId = "userId";
|
||||
@@ -41,6 +43,7 @@ describe("Browser State Service", () => {
|
||||
logService = mock();
|
||||
stateFactory = mock();
|
||||
accountService = mock();
|
||||
environmentService = mock();
|
||||
// turn off account cache for tests
|
||||
useAccountCache = false;
|
||||
|
||||
@@ -66,6 +69,7 @@ describe("Browser State Service", () => {
|
||||
logService,
|
||||
stateFactory,
|
||||
accountService,
|
||||
environmentService,
|
||||
useAccountCache,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { BehaviorSubject } from "rxjs";
|
||||
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import {
|
||||
AbstractStorageService,
|
||||
@@ -44,6 +45,7 @@ export class BrowserStateService
|
||||
logService: LogService,
|
||||
stateFactory: StateFactory<GlobalState, Account>,
|
||||
accountService: AccountService,
|
||||
environmentService: EnvironmentService,
|
||||
useAccountCache = true,
|
||||
) {
|
||||
super(
|
||||
@@ -53,6 +55,7 @@ export class BrowserStateService
|
||||
logService,
|
||||
stateFactory,
|
||||
accountService,
|
||||
environmentService,
|
||||
useAccountCache,
|
||||
);
|
||||
|
||||
|
||||
@@ -483,6 +483,7 @@ function getBgService<T>(service: keyof MainBackground) {
|
||||
memoryStorageService: AbstractMemoryStorageService,
|
||||
logService: LogServiceAbstraction,
|
||||
accountService: AccountServiceAbstraction,
|
||||
environmentService: EnvironmentService,
|
||||
) => {
|
||||
return new BrowserStateService(
|
||||
storageService,
|
||||
@@ -491,6 +492,7 @@ function getBgService<T>(service: keyof MainBackground) {
|
||||
logService,
|
||||
new StateFactory(GlobalState, Account),
|
||||
accountService,
|
||||
environmentService,
|
||||
);
|
||||
},
|
||||
deps: [
|
||||
@@ -499,6 +501,7 @@ function getBgService<T>(service: keyof MainBackground) {
|
||||
MEMORY_STORAGE,
|
||||
LogServiceAbstraction,
|
||||
AccountServiceAbstraction,
|
||||
EnvironmentService,
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -255,6 +255,8 @@ export class Main {
|
||||
this.derivedStateProvider,
|
||||
);
|
||||
|
||||
this.environmentService = new EnvironmentService(this.stateProvider, this.accountService);
|
||||
|
||||
this.stateService = new StateService(
|
||||
this.storageService,
|
||||
this.secureStorageService,
|
||||
@@ -262,6 +264,7 @@ export class Main {
|
||||
this.logService,
|
||||
new StateFactory(GlobalState, Account),
|
||||
this.accountService,
|
||||
this.environmentService,
|
||||
);
|
||||
|
||||
this.cryptoService = new CryptoService(
|
||||
@@ -276,7 +279,6 @@ export class Main {
|
||||
|
||||
this.appIdService = new AppIdService(this.storageService);
|
||||
this.tokenService = new TokenService(this.stateService);
|
||||
this.environmentService = new EnvironmentService(this.stateService);
|
||||
|
||||
const customUserAgent =
|
||||
"Bitwarden_CLI/" +
|
||||
|
||||
@@ -22,6 +22,7 @@ import { BroadcasterService as BroadcasterServiceAbstraction } from "@bitwarden/
|
||||
import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||
import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import {
|
||||
@@ -129,6 +130,7 @@ const RELOAD_CALLBACK = new InjectionToken<() => any>("RELOAD_CALLBACK");
|
||||
LogService,
|
||||
STATE_FACTORY,
|
||||
AccountServiceAbstraction,
|
||||
EnvironmentService,
|
||||
STATE_SERVICE_USE_CACHE,
|
||||
],
|
||||
},
|
||||
|
||||
@@ -5,10 +5,16 @@ import { app } from "electron";
|
||||
import { AccountServiceImplementation } from "@bitwarden/common/auth/services/account.service";
|
||||
import { StateFactory } from "@bitwarden/common/platform/factories/state-factory";
|
||||
import { GlobalState } from "@bitwarden/common/platform/models/domain/global-state";
|
||||
import { EnvironmentService } from "@bitwarden/common/platform/services/environment.service";
|
||||
import { MemoryStorageService } from "@bitwarden/common/platform/services/memory-storage.service";
|
||||
import { NoopMessagingService } from "@bitwarden/common/platform/services/noop-messaging.service";
|
||||
// eslint-disable-next-line import/no-restricted-paths -- We need the implementation to inject, but generally this should not be accessed
|
||||
/* eslint-disable import/no-restricted-paths -- We need the implementation to inject, but generally this should not be accessed */
|
||||
import { DefaultActiveUserStateProvider } from "@bitwarden/common/platform/state/implementations/default-active-user-state.provider";
|
||||
import { DefaultDerivedStateProvider } from "@bitwarden/common/platform/state/implementations/default-derived-state.provider";
|
||||
import { DefaultGlobalStateProvider } from "@bitwarden/common/platform/state/implementations/default-global-state.provider";
|
||||
import { DefaultSingleUserStateProvider } from "@bitwarden/common/platform/state/implementations/default-single-user-state.provider";
|
||||
import { DefaultStateProvider } from "@bitwarden/common/platform/state/implementations/default-state.provider";
|
||||
/*/ eslint-enable import/no-restricted-paths */
|
||||
|
||||
import { MenuMain } from "./main/menu/menu.main";
|
||||
import { MessagingMain } from "./main/messaging.main";
|
||||
@@ -34,6 +40,7 @@ export class Main {
|
||||
memoryStorageService: MemoryStorageService;
|
||||
messagingService: ElectronMainMessagingService;
|
||||
stateService: ElectronStateService;
|
||||
environmentService: EnvironmentService;
|
||||
desktopCredentialStorageListener: DesktopCredentialStorageListener;
|
||||
|
||||
windowMain: WindowMain;
|
||||
@@ -93,6 +100,25 @@ export class Main {
|
||||
this.storageService,
|
||||
);
|
||||
|
||||
const accountService = new AccountServiceImplementation(
|
||||
new NoopMessagingService(),
|
||||
this.logService,
|
||||
globalStateProvider,
|
||||
);
|
||||
|
||||
const stateProvider = new DefaultStateProvider(
|
||||
new DefaultActiveUserStateProvider(
|
||||
accountService,
|
||||
this.memoryStorageService,
|
||||
this.storageService,
|
||||
),
|
||||
new DefaultSingleUserStateProvider(this.memoryStorageService, this.storageService),
|
||||
globalStateProvider,
|
||||
new DefaultDerivedStateProvider(this.memoryStorageService),
|
||||
);
|
||||
|
||||
this.environmentService = new EnvironmentService(stateProvider, accountService);
|
||||
|
||||
// TODO: this state service will have access to on disk storage, but not in memory storage.
|
||||
// If we could get this to work using the stateService singleton that the rest of the app uses we could save
|
||||
// ourselves from some hacks, like having to manually update the app menu vs. the menu subscribing to events.
|
||||
@@ -102,11 +128,8 @@ export class Main {
|
||||
this.memoryStorageService,
|
||||
this.logService,
|
||||
new StateFactory(GlobalState, Account),
|
||||
new AccountServiceImplementation(
|
||||
new NoopMessagingService(),
|
||||
this.logService,
|
||||
globalStateProvider,
|
||||
), // will not broadcast logouts. This is a hack until we can remove messaging dependency
|
||||
accountService, // will not broadcast logouts. This is a hack until we can remove messaging dependency
|
||||
this.environmentService,
|
||||
false, // Do not use disk caching because this will get out of sync with the renderer service
|
||||
);
|
||||
|
||||
@@ -128,7 +151,7 @@ export class Main {
|
||||
this.menuMain = new MenuMain(
|
||||
this.i18nService,
|
||||
this.messagingService,
|
||||
this.stateService,
|
||||
this.environmentService,
|
||||
this.windowMain,
|
||||
this.updaterMain,
|
||||
);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { app, Menu } from "electron";
|
||||
|
||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
|
||||
import { UpdaterMain } from "../updater.main";
|
||||
import { WindowMain } from "../window.main";
|
||||
@@ -16,7 +16,7 @@ export class MenuMain {
|
||||
constructor(
|
||||
private i18nService: I18nService,
|
||||
private messagingService: MessagingService,
|
||||
private stateService: StateService,
|
||||
private environmentService: EnvironmentService,
|
||||
private windowMain: WindowMain,
|
||||
private updaterMain: UpdaterMain,
|
||||
) {}
|
||||
@@ -45,16 +45,7 @@ export class MenuMain {
|
||||
}
|
||||
|
||||
private async getWebVaultUrl() {
|
||||
let webVaultUrl = cloudWebVaultUrl;
|
||||
const urlsObj = await this.stateService.getEnvironmentUrls();
|
||||
if (urlsObj != null) {
|
||||
if (urlsObj.base != null) {
|
||||
webVaultUrl = urlsObj.base;
|
||||
} else if (urlsObj.webVault != null) {
|
||||
webVaultUrl = urlsObj.webVault;
|
||||
}
|
||||
}
|
||||
return webVaultUrl;
|
||||
return this.environmentService.getWebVaultUrl() ?? cloudWebVaultUrl;
|
||||
}
|
||||
|
||||
private initContextMenu() {
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
STATE_SERVICE_USE_CACHE,
|
||||
} from "@bitwarden/angular/services/injection-tokens";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import {
|
||||
AbstractMemoryStorageService,
|
||||
@@ -32,6 +33,7 @@ export class StateService extends BaseStateService<GlobalState, Account> {
|
||||
logService: LogService,
|
||||
@Inject(STATE_FACTORY) stateFactory: StateFactory<GlobalState, Account>,
|
||||
accountService: AccountService,
|
||||
environmentService: EnvironmentService,
|
||||
@Inject(STATE_SERVICE_USE_CACHE) useAccountCache = true,
|
||||
) {
|
||||
super(
|
||||
@@ -41,6 +43,7 @@ export class StateService extends BaseStateService<GlobalState, Account> {
|
||||
logService,
|
||||
stateFactory,
|
||||
accountService,
|
||||
environmentService,
|
||||
useAccountCache,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user