mirror of
https://github.com/bitwarden/browser.git
synced 2025-01-30 22:41:33 +01:00
[PM-17479] Load-sdk-once (#12764)
* create service to load sdk on application init * Eagerly load CLI SDK * Remove wasm logging to api * Fix imports * Eagerly load Desktop renderer SDK Note: If the main process ever requires an SDK, we'll need to load it there, too. In that event, it's probably a good idea to move to IPC for all SDK functions to avoid loading the SDK for every window. * init wasm module from sdk load service * Use default client factory * Fix type imports * Resolve jest module import errors A CLI sdk load service that async imports our wasm binary doesn't seem to be needed to run, but jest isn't dealing with the ESM import properly. * Fix linting * remove example code
This commit is contained in:
parent
620affd3d5
commit
f9f30f8ec4
@ -92,6 +92,7 @@ import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platfor
|
||||
import { KeyGenerationService as KeyGenerationServiceAbstraction } from "@bitwarden/common/platform/abstractions/key-generation.service";
|
||||
import { LogService as LogServiceAbstraction } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
|
||||
import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service";
|
||||
import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import {
|
||||
@ -125,6 +126,7 @@ import { FileUploadService } from "@bitwarden/common/platform/services/file-uplo
|
||||
import { KeyGenerationService } from "@bitwarden/common/platform/services/key-generation.service";
|
||||
import { MigrationBuilderService } from "@bitwarden/common/platform/services/migration-builder.service";
|
||||
import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner";
|
||||
import { DefaultSdkClientFactory } from "@bitwarden/common/platform/services/sdk/default-sdk-client-factory";
|
||||
import { DefaultSdkService } from "@bitwarden/common/platform/services/sdk/default-sdk.service";
|
||||
import { NoopSdkClientFactory } from "@bitwarden/common/platform/services/sdk/noop-sdk-client-factory";
|
||||
import { StateService } from "@bitwarden/common/platform/services/state.service";
|
||||
@ -260,7 +262,7 @@ import { LocalBackedSessionStorageService } from "../platform/services/local-bac
|
||||
import { BackgroundPlatformUtilsService } from "../platform/services/platform-utils/background-platform-utils.service";
|
||||
import { BrowserPlatformUtilsService } from "../platform/services/platform-utils/browser-platform-utils.service";
|
||||
import { PopupViewCacheBackgroundService } from "../platform/services/popup-view-cache-background.service";
|
||||
import { BrowserSdkClientFactory } from "../platform/services/sdk/browser-sdk-client-factory";
|
||||
import { BrowserSdkLoadService } from "../platform/services/sdk/browser-sdk-load.service";
|
||||
import { BackgroundTaskSchedulerService } from "../platform/services/task-scheduler/background-task-scheduler.service";
|
||||
import { BackgroundMemoryStorageService } from "../platform/storage/background-memory-storage.service";
|
||||
import { BrowserStorageServiceProvider } from "../platform/storage/browser-storage-service.provider";
|
||||
@ -379,6 +381,7 @@ export default class MainBackground {
|
||||
themeStateService: DefaultThemeStateService;
|
||||
autoSubmitLoginBackground: AutoSubmitLoginBackground;
|
||||
sdkService: SdkService;
|
||||
sdkLoadService: SdkLoadService;
|
||||
cipherAuthorizationService: CipherAuthorizationService;
|
||||
inlineMenuFieldQualificationService: InlineMenuFieldQualificationService;
|
||||
|
||||
@ -730,8 +733,9 @@ export default class MainBackground {
|
||||
);
|
||||
|
||||
const sdkClientFactory = flagEnabled("sdk")
|
||||
? new BrowserSdkClientFactory(this.logService)
|
||||
? new DefaultSdkClientFactory()
|
||||
: new NoopSdkClientFactory();
|
||||
this.sdkLoadService = new BrowserSdkLoadService(this.logService);
|
||||
this.sdkService = new DefaultSdkService(
|
||||
sdkClientFactory,
|
||||
this.environmentService,
|
||||
@ -1257,6 +1261,7 @@ export default class MainBackground {
|
||||
async bootstrap() {
|
||||
this.containerService.attachToGlobal(self);
|
||||
|
||||
await this.sdkLoadService.load();
|
||||
// Only the "true" background should run migrations
|
||||
await this.stateService.init({ runMigrations: true });
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { SdkClientFactory } from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
|
||||
import type { BitwardenClient } from "@bitwarden/sdk-internal";
|
||||
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
|
||||
|
||||
import { BrowserApi } from "../../browser/browser-api";
|
||||
|
||||
export type GlobalWithWasmInit = typeof globalThis & {
|
||||
initSdk: () => void;
|
||||
};
|
||||
|
||||
// https://stackoverflow.com/a/47880734
|
||||
const supported = (() => {
|
||||
try {
|
||||
@ -17,9 +18,7 @@ const supported = (() => {
|
||||
return new WebAssembly.Instance(module) instanceof WebAssembly.Instance;
|
||||
}
|
||||
}
|
||||
// FIXME: Remove when updating file. Eslint update
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
} catch (e) {
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
return false;
|
||||
@ -33,54 +32,42 @@ let loadingPromise: Promise<any> | undefined;
|
||||
if (BrowserApi.isManifestVersion(3)) {
|
||||
if (supported) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.debug("WebAssembly is supported in this environment");
|
||||
console.info("WebAssembly is supported in this environment");
|
||||
loadingPromise = import("./wasm");
|
||||
} else {
|
||||
// eslint-disable-next-line no-console
|
||||
console.debug("WebAssembly is not supported in this environment");
|
||||
console.info("WebAssembly is not supported in this environment");
|
||||
loadingPromise = import("./fallback");
|
||||
}
|
||||
}
|
||||
|
||||
// Manifest v2 expects dynamic imports to prevent timing issues.
|
||||
async function load() {
|
||||
async function importModule(): Promise<GlobalWithWasmInit["initSdk"]> {
|
||||
if (BrowserApi.isManifestVersion(3)) {
|
||||
// Ensure we have loaded the module
|
||||
await loadingPromise;
|
||||
return;
|
||||
}
|
||||
|
||||
if (supported) {
|
||||
} else if (supported) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.debug("WebAssembly is supported in this environment");
|
||||
console.info("WebAssembly is supported in this environment");
|
||||
await import("./wasm");
|
||||
} else {
|
||||
// eslint-disable-next-line no-console
|
||||
console.debug("WebAssembly is not supported in this environment");
|
||||
console.info("WebAssembly is not supported in this environment");
|
||||
await import("./fallback");
|
||||
}
|
||||
|
||||
// the wasm and fallback imports mutate globalThis to add the initSdk function
|
||||
return (globalThis as GlobalWithWasmInit).initSdk;
|
||||
}
|
||||
|
||||
/**
|
||||
* SDK client factory with a js fallback for when WASM is not supported.
|
||||
*
|
||||
* Works both in popup and service worker.
|
||||
*/
|
||||
export class BrowserSdkClientFactory implements SdkClientFactory {
|
||||
constructor(private logService: LogService) {}
|
||||
export class BrowserSdkLoadService implements SdkLoadService {
|
||||
constructor(readonly logService: LogService) {}
|
||||
|
||||
async createSdkClient(
|
||||
...args: ConstructorParameters<typeof BitwardenClient>
|
||||
): Promise<BitwardenClient> {
|
||||
async load(): Promise<void> {
|
||||
const startTime = performance.now();
|
||||
await load();
|
||||
|
||||
await importModule().then((initSdk) => initSdk());
|
||||
const endTime = performance.now();
|
||||
|
||||
const instance = (globalThis as any).init_sdk(...args);
|
||||
|
||||
this.logService.info("WASM SDK loaded in", Math.round(endTime - startTime), "ms");
|
||||
|
||||
return instance;
|
||||
this.logService.info(`WASM SDK loaded in ${Math.round(endTime - startTime)}ms`);
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
import * as sdk from "@bitwarden/sdk-internal";
|
||||
import * as wasm from "@bitwarden/sdk-internal/bitwarden_wasm_internal_bg.wasm.js";
|
||||
|
||||
(globalThis as any).init_sdk = (...args: ConstructorParameters<typeof sdk.BitwardenClient>) => {
|
||||
(sdk as any).init(wasm);
|
||||
import { GlobalWithWasmInit } from "./browser-sdk-load.service";
|
||||
|
||||
return new sdk.BitwardenClient(...args);
|
||||
(globalThis as GlobalWithWasmInit).initSdk = () => {
|
||||
(sdk as any).init(wasm);
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
import * as sdk from "@bitwarden/sdk-internal";
|
||||
import * as wasm from "@bitwarden/sdk-internal/bitwarden_wasm_internal_bg.wasm";
|
||||
|
||||
(globalThis as any).init_sdk = (...args: ConstructorParameters<typeof sdk.BitwardenClient>) => {
|
||||
(sdk as any).init(wasm);
|
||||
import { GlobalWithWasmInit } from "./browser-sdk-load.service";
|
||||
|
||||
return new sdk.BitwardenClient(...args);
|
||||
(globalThis as GlobalWithWasmInit).initSdk = () => {
|
||||
(sdk as any).init(wasm);
|
||||
};
|
||||
|
@ -6,6 +6,7 @@ import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService as LogServiceAbstraction } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
|
||||
import { BrowserApi } from "../../platform/browser/browser-api";
|
||||
@ -22,11 +23,13 @@ export class InitService {
|
||||
private twoFactorService: TwoFactorService,
|
||||
private logService: LogServiceAbstraction,
|
||||
private themingService: AbstractThemingService,
|
||||
private sdkLoadService: SdkLoadService,
|
||||
@Inject(DOCUMENT) private document: Document,
|
||||
) {}
|
||||
|
||||
init() {
|
||||
return async () => {
|
||||
await this.sdkLoadService.load();
|
||||
await this.stateService.init({ runMigrations: false }); // Browser background is responsible for migrations
|
||||
await this.i18nService.init();
|
||||
this.twoFactorService.init();
|
||||
|
@ -70,6 +70,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service"
|
||||
import { MessagingService as MessagingServiceAbstraction } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { SdkClientFactory } from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
|
||||
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import {
|
||||
AbstractStorageService,
|
||||
@ -82,6 +83,7 @@ import { flagEnabled } from "@bitwarden/common/platform/misc/flags";
|
||||
import { TaskSchedulerService } from "@bitwarden/common/platform/scheduling";
|
||||
import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service";
|
||||
import { ContainerService } from "@bitwarden/common/platform/services/container.service";
|
||||
import { DefaultSdkClientFactory } from "@bitwarden/common/platform/services/sdk/default-sdk-client-factory";
|
||||
import { NoopSdkClientFactory } from "@bitwarden/common/platform/services/sdk/noop-sdk-client-factory";
|
||||
import { StorageServiceProvider } from "@bitwarden/common/platform/services/storage-service.provider";
|
||||
import { WebCryptoFunctionService } from "@bitwarden/common/platform/services/web-crypto-function.service";
|
||||
@ -144,7 +146,7 @@ import BrowserMemoryStorageService from "../../platform/services/browser-memory-
|
||||
import { BrowserScriptInjectorService } from "../../platform/services/browser-script-injector.service";
|
||||
import I18nService from "../../platform/services/i18n.service";
|
||||
import { ForegroundPlatformUtilsService } from "../../platform/services/platform-utils/foreground-platform-utils.service";
|
||||
import { BrowserSdkClientFactory } from "../../platform/services/sdk/browser-sdk-client-factory";
|
||||
import { BrowserSdkLoadService } from "../../platform/services/sdk/browser-sdk-load.service";
|
||||
import { ForegroundTaskSchedulerService } from "../../platform/services/task-scheduler/foreground-task-scheduler.service";
|
||||
import { BrowserStorageServiceProvider } from "../../platform/storage/browser-storage-service.provider";
|
||||
import { ForegroundMemoryStorageService } from "../../platform/storage/foreground-memory-storage.service";
|
||||
@ -566,11 +568,16 @@ const safeProviders: SafeProvider[] = [
|
||||
deps: [MessageSender, MessageListener],
|
||||
}),
|
||||
safeProvider({
|
||||
provide: SdkClientFactory,
|
||||
useFactory: (logService: LogService) =>
|
||||
flagEnabled("sdk") ? new BrowserSdkClientFactory(logService) : new NoopSdkClientFactory(),
|
||||
provide: SdkLoadService,
|
||||
useClass: BrowserSdkLoadService,
|
||||
deps: [LogService],
|
||||
}),
|
||||
safeProvider({
|
||||
provide: SdkClientFactory,
|
||||
useFactory: () =>
|
||||
flagEnabled("sdk") ? new DefaultSdkClientFactory() : new NoopSdkClientFactory(),
|
||||
deps: [],
|
||||
}),
|
||||
safeProvider({
|
||||
provide: LoginEmailService,
|
||||
useClass: LoginEmailService,
|
||||
|
9
apps/cli/src/platform/services/cli-sdk-load.service.ts
Normal file
9
apps/cli/src/platform/services/cli-sdk-load.service.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
|
||||
import * as sdk from "@bitwarden/sdk-internal";
|
||||
|
||||
export class CliSdkLoadService implements SdkLoadService {
|
||||
async load(): Promise<void> {
|
||||
const module = await import("@bitwarden/sdk-internal/bitwarden_wasm_internal_bg.wasm");
|
||||
(sdk as any).init(module);
|
||||
}
|
||||
}
|
@ -68,6 +68,7 @@ import {
|
||||
RegionConfig,
|
||||
} from "@bitwarden/common/platform/abstractions/environment.service";
|
||||
import { KeyGenerationService as KeyGenerationServiceAbstraction } from "@bitwarden/common/platform/abstractions/key-generation.service";
|
||||
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
|
||||
import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service";
|
||||
import { KeySuffixOptions, LogLevelType } from "@bitwarden/common/platform/enums";
|
||||
import { StateFactory } from "@bitwarden/common/platform/factories/state-factory";
|
||||
@ -171,6 +172,7 @@ import {
|
||||
import { CliBiometricsService } from "../key-management/cli-biometrics-service";
|
||||
import { flagEnabled } from "../platform/flags";
|
||||
import { CliPlatformUtilsService } from "../platform/services/cli-platform-utils.service";
|
||||
import { CliSdkLoadService } from "../platform/services/cli-sdk-load.service";
|
||||
import { ConsoleLogService } from "../platform/services/console-log.service";
|
||||
import { I18nService } from "../platform/services/i18n.service";
|
||||
import { LowdbStorageService } from "../platform/services/lowdb-storage.service";
|
||||
@ -270,6 +272,7 @@ export class ServiceContainer {
|
||||
kdfConfigService: KdfConfigService;
|
||||
taskSchedulerService: TaskSchedulerService;
|
||||
sdkService: SdkService;
|
||||
sdkLoadService: SdkLoadService;
|
||||
cipherAuthorizationService: CipherAuthorizationService;
|
||||
|
||||
constructor() {
|
||||
@ -570,6 +573,7 @@ export class ServiceContainer {
|
||||
const sdkClientFactory = flagEnabled("sdk")
|
||||
? new DefaultSdkClientFactory()
|
||||
: new NoopSdkClientFactory();
|
||||
this.sdkLoadService = new CliSdkLoadService();
|
||||
this.sdkService = new DefaultSdkService(
|
||||
sdkClientFactory,
|
||||
this.environmentService,
|
||||
@ -859,6 +863,7 @@ export class ServiceContainer {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.sdkLoadService.load();
|
||||
await this.storageService.init();
|
||||
await this.stateService.init();
|
||||
this.containerService.attachToGlobal(global);
|
||||
|
@ -11,6 +11,7 @@ import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/comm
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
|
||||
import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { ContainerService } from "@bitwarden/common/platform/services/container.service";
|
||||
import { UserAutoUnlockKeyService } from "@bitwarden/common/platform/services/user-auto-unlock-key.service";
|
||||
@ -47,11 +48,13 @@ export class InitService {
|
||||
private versionService: VersionService,
|
||||
private sshAgentService: SshAgentService,
|
||||
private autofillService: DesktopAutofillService,
|
||||
private sdkLoadService: SdkLoadService,
|
||||
@Inject(DOCUMENT) private document: Document,
|
||||
) {}
|
||||
|
||||
init() {
|
||||
return async () => {
|
||||
await this.sdkLoadService.load();
|
||||
await this.sshAgentService.init();
|
||||
this.nativeMessagingService.init();
|
||||
await this.stateService.init({ runMigrations: false }); // Desktop will run them in main process
|
||||
|
@ -67,6 +67,7 @@ import {
|
||||
import { MessagingService as MessagingServiceAbstraction } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { SdkClientFactory } from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
|
||||
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
|
||||
import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service";
|
||||
import { SystemService as SystemServiceAbstraction } from "@bitwarden/common/platform/abstractions/system.service";
|
||||
@ -77,7 +78,9 @@ import { TaskSchedulerService } from "@bitwarden/common/platform/scheduling";
|
||||
import { Fido2AuthenticatorService } from "@bitwarden/common/platform/services/fido2/fido2-authenticator.service";
|
||||
import { MemoryStorageService } from "@bitwarden/common/platform/services/memory-storage.service";
|
||||
import { DefaultSdkClientFactory } from "@bitwarden/common/platform/services/sdk/default-sdk-client-factory";
|
||||
import { DefaultSdkLoadService } from "@bitwarden/common/platform/services/sdk/default-sdk-load.service";
|
||||
import { NoopSdkClientFactory } from "@bitwarden/common/platform/services/sdk/noop-sdk-client-factory";
|
||||
import { NoopSdkLoadService } from "@bitwarden/common/platform/services/sdk/noop-sdk-load.service";
|
||||
import { SystemService } from "@bitwarden/common/platform/services/system.service";
|
||||
import { GlobalStateProvider, StateProvider } from "@bitwarden/common/platform/state";
|
||||
// eslint-disable-next-line import/no-restricted-paths -- Implementation for memory storage
|
||||
@ -393,6 +396,11 @@ const safeProviders: SafeProvider[] = [
|
||||
useClass: flagEnabled("sdk") ? DefaultSdkClientFactory : NoopSdkClientFactory,
|
||||
deps: [],
|
||||
}),
|
||||
safeProvider({
|
||||
provide: SdkLoadService,
|
||||
useClass: flagEnabled("sdk") ? DefaultSdkLoadService : NoopSdkLoadService,
|
||||
deps: [],
|
||||
}),
|
||||
safeProvider({
|
||||
provide: LoginEmailService,
|
||||
useClass: LoginEmailService,
|
||||
|
@ -66,6 +66,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service"
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { SdkClientFactory } from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
|
||||
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
|
||||
import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service";
|
||||
import { ThemeType } from "@bitwarden/common/platform/enums";
|
||||
import { AppIdService as DefaultAppIdService } from "@bitwarden/common/platform/services/app-id.service";
|
||||
@ -73,7 +74,9 @@ import { MemoryStorageService } from "@bitwarden/common/platform/services/memory
|
||||
// eslint-disable-next-line import/no-restricted-paths -- Implementation for memory storage
|
||||
import { MigrationBuilderService } from "@bitwarden/common/platform/services/migration-builder.service";
|
||||
import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner";
|
||||
import { DefaultSdkClientFactory } from "@bitwarden/common/platform/services/sdk/default-sdk-client-factory";
|
||||
import { NoopSdkClientFactory } from "@bitwarden/common/platform/services/sdk/noop-sdk-client-factory";
|
||||
import { NoopSdkLoadService } from "@bitwarden/common/platform/services/sdk/noop-sdk-load.service";
|
||||
import { StorageServiceProvider } from "@bitwarden/common/platform/services/storage-service.provider";
|
||||
/* eslint-disable import/no-restricted-paths -- Implementation for memory storage */
|
||||
import { GlobalStateProvider, StateProvider } from "@bitwarden/common/platform/state";
|
||||
@ -110,7 +113,7 @@ import { WebProcessReloadService } from "../key-management/services/web-process-
|
||||
import { WebBiometricsService } from "../key-management/web-biometric.service";
|
||||
import { WebEnvironmentService } from "../platform/web-environment.service";
|
||||
import { WebMigrationRunner } from "../platform/web-migration-runner";
|
||||
import { WebSdkClientFactory } from "../platform/web-sdk-client-factory";
|
||||
import { WebSdkLoadService } from "../platform/web-sdk-load.service";
|
||||
import { WebStorageServiceProvider } from "../platform/web-storage-service.provider";
|
||||
|
||||
import { EventService } from "./event.service";
|
||||
@ -288,9 +291,14 @@ const safeProviders: SafeProvider[] = [
|
||||
useClass: DefaultCollectionAdminService,
|
||||
deps: [ApiService, KeyServiceAbstraction, EncryptService, CollectionService],
|
||||
}),
|
||||
safeProvider({
|
||||
provide: SdkLoadService,
|
||||
useClass: flagEnabled("sdk") ? WebSdkLoadService : NoopSdkLoadService,
|
||||
deps: [],
|
||||
}),
|
||||
safeProvider({
|
||||
provide: SdkClientFactory,
|
||||
useClass: flagEnabled("sdk") ? WebSdkClientFactory : NoopSdkClientFactory,
|
||||
useClass: flagEnabled("sdk") ? DefaultSdkClientFactory : NoopSdkClientFactory,
|
||||
deps: [],
|
||||
}),
|
||||
safeProvider({
|
||||
|
@ -10,6 +10,7 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv
|
||||
import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
|
||||
import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { ContainerService } from "@bitwarden/common/platform/services/container.service";
|
||||
import { UserAutoUnlockKeyService } from "@bitwarden/common/platform/services/user-auto-unlock-key.service";
|
||||
@ -35,11 +36,13 @@ export class InitService {
|
||||
private userAutoUnlockKeyService: UserAutoUnlockKeyService,
|
||||
private accountService: AccountService,
|
||||
private versionService: VersionService,
|
||||
private sdkLoadService: SdkLoadService,
|
||||
@Inject(DOCUMENT) private document: Document,
|
||||
) {}
|
||||
|
||||
init() {
|
||||
return async () => {
|
||||
await this.sdkLoadService.load();
|
||||
await this.stateService.init();
|
||||
|
||||
const activeAccount = await firstValueFrom(this.accountService.activeAccount$);
|
||||
|
@ -1,44 +0,0 @@
|
||||
import { SdkClientFactory } from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
|
||||
import * as sdk from "@bitwarden/sdk-internal";
|
||||
|
||||
/**
|
||||
* SDK client factory with a js fallback for when WASM is not supported.
|
||||
*/
|
||||
export class WebSdkClientFactory implements SdkClientFactory {
|
||||
async createSdkClient(
|
||||
...args: ConstructorParameters<typeof sdk.BitwardenClient>
|
||||
): Promise<sdk.BitwardenClient> {
|
||||
const module = await load();
|
||||
|
||||
(sdk as any).init(module);
|
||||
|
||||
return Promise.resolve(new sdk.BitwardenClient(...args));
|
||||
}
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/a/47880734
|
||||
const supported = (() => {
|
||||
try {
|
||||
if (typeof WebAssembly === "object" && typeof WebAssembly.instantiate === "function") {
|
||||
const module = new WebAssembly.Module(
|
||||
Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00),
|
||||
);
|
||||
if (module instanceof WebAssembly.Module) {
|
||||
return new WebAssembly.Instance(module) instanceof WebAssembly.Instance;
|
||||
}
|
||||
}
|
||||
// FIXME: Remove when updating file. Eslint update
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
return false;
|
||||
})();
|
||||
|
||||
async function load() {
|
||||
if (supported) {
|
||||
return await import("@bitwarden/sdk-internal/bitwarden_wasm_internal_bg.wasm");
|
||||
} else {
|
||||
return await import("@bitwarden/sdk-internal/bitwarden_wasm_internal_bg.wasm.js");
|
||||
}
|
||||
}
|
31
apps/web/src/app/platform/web-sdk-load.service.ts
Normal file
31
apps/web/src/app/platform/web-sdk-load.service.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
|
||||
import * as sdk from "@bitwarden/sdk-internal";
|
||||
|
||||
// https://stackoverflow.com/a/47880734
|
||||
const supported = (() => {
|
||||
try {
|
||||
if (typeof WebAssembly === "object" && typeof WebAssembly.instantiate === "function") {
|
||||
const module = new WebAssembly.Module(
|
||||
Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00),
|
||||
);
|
||||
if (module instanceof WebAssembly.Module) {
|
||||
return new WebAssembly.Instance(module) instanceof WebAssembly.Instance;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
return false;
|
||||
})();
|
||||
|
||||
export class WebSdkLoadService implements SdkLoadService {
|
||||
async load(): Promise<void> {
|
||||
let module: any;
|
||||
if (supported) {
|
||||
module = await import("@bitwarden/sdk-internal/bitwarden_wasm_internal_bg.wasm");
|
||||
} else {
|
||||
module = await import("@bitwarden/sdk-internal/bitwarden_wasm_internal_bg.wasm.js");
|
||||
}
|
||||
(sdk as any).init(module);
|
||||
}
|
||||
}
|
@ -4,6 +4,10 @@ import type { BitwardenClient } from "@bitwarden/sdk-internal";
|
||||
* Factory for creating SDK clients.
|
||||
*/
|
||||
export abstract class SdkClientFactory {
|
||||
/**
|
||||
* Creates a new BitwardenClient. Assumes the SDK is already loaded.
|
||||
* @param args Bitwarden client constructor parameters
|
||||
*/
|
||||
abstract createSdkClient(
|
||||
...args: ConstructorParameters<typeof BitwardenClient>
|
||||
): Promise<BitwardenClient>;
|
||||
|
@ -0,0 +1,3 @@
|
||||
export abstract class SdkLoadService {
|
||||
abstract load(): Promise<void>;
|
||||
}
|
@ -1,19 +1,19 @@
|
||||
import * as sdk from "@bitwarden/sdk-internal";
|
||||
import * as module from "@bitwarden/sdk-internal/bitwarden_wasm_internal_bg.wasm";
|
||||
|
||||
import { SdkClientFactory } from "../../abstractions/sdk/sdk-client-factory";
|
||||
|
||||
/**
|
||||
* Directly imports the Bitwarden SDK and initializes it.
|
||||
*
|
||||
* **Warning**: This requires WASM support and will fail if the environment does not support it.
|
||||
* Default SDK client factory.
|
||||
*/
|
||||
export class DefaultSdkClientFactory implements SdkClientFactory {
|
||||
/**
|
||||
* Initializes a Bitwarden client. Assumes the SDK is already loaded.
|
||||
* @param args Bitwarden client constructor parameters
|
||||
* @returns A BitwardenClient
|
||||
*/
|
||||
async createSdkClient(
|
||||
...args: ConstructorParameters<typeof sdk.BitwardenClient>
|
||||
): Promise<sdk.BitwardenClient> {
|
||||
(sdk as any).init(module);
|
||||
|
||||
return Promise.resolve(new sdk.BitwardenClient(...args));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
import * as sdk from "@bitwarden/sdk-internal";
|
||||
import * as bitwardenModule from "@bitwarden/sdk-internal/bitwarden_wasm_internal_bg.wasm";
|
||||
|
||||
import { SdkLoadService } from "../../abstractions/sdk/sdk-load.service";
|
||||
|
||||
/**
|
||||
* Directly imports the Bitwarden SDK and initializes it.
|
||||
*
|
||||
* **Warning**: This requires WASM support and will fail if the environment does not support it.
|
||||
*/
|
||||
export class DefaultSdkLoadService implements SdkLoadService {
|
||||
async load(): Promise<void> {
|
||||
(sdk as any).init(bitwardenModule);
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
import { SdkLoadService } from "../../abstractions/sdk/sdk-load.service";
|
||||
|
||||
export class NoopSdkLoadService extends SdkLoadService {
|
||||
async load() {
|
||||
return;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user