mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 13:23:34 +00:00
[PM-11766] Introduce SDK client (#10974)
Integrate the SDK into our other clients.
This commit is contained in:
9
libs/common/spec/jest-sdk-client-factory.ts
Normal file
9
libs/common/spec/jest-sdk-client-factory.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { ClientSettings, LogLevel, BitwardenClient } from "@bitwarden/sdk-internal";
|
||||
|
||||
import { SdkClientFactory } from "../src/platform/abstractions/sdk/sdk-client-factory";
|
||||
|
||||
export class DefaultSdkClientFactory implements SdkClientFactory {
|
||||
createSdkClient(settings?: ClientSettings, log_level?: LogLevel): Promise<BitwardenClient> {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import type { BitwardenClient } from "@bitwarden/sdk-internal";
|
||||
|
||||
/**
|
||||
* Factory for creating SDK clients.
|
||||
*/
|
||||
export abstract class SdkClientFactory {
|
||||
abstract createSdkClient(
|
||||
...args: ConstructorParameters<typeof BitwardenClient>
|
||||
): Promise<BitwardenClient>;
|
||||
}
|
||||
8
libs/common/src/platform/abstractions/sdk/sdk.service.ts
Normal file
8
libs/common/src/platform/abstractions/sdk/sdk.service.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { Observable } from "rxjs";
|
||||
|
||||
import { BitwardenClient } from "@bitwarden/sdk-internal";
|
||||
|
||||
export abstract class SdkService {
|
||||
client$: Observable<BitwardenClient>;
|
||||
supported$: Observable<boolean>;
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export type SharedFlags = {
|
||||
showPasswordless?: boolean;
|
||||
sdk?: boolean;
|
||||
};
|
||||
|
||||
// required to avoid linting errors when there are no flags
|
||||
@@ -28,7 +29,7 @@ function getFlags<T>(envFlags: string | T): T {
|
||||
* @returns The value of the flag
|
||||
*/
|
||||
export function flagEnabled<Flags extends SharedFlags>(flag: keyof Flags): boolean {
|
||||
const flags = getFlags<Flags>(process.env.FLAGS);
|
||||
const flags = getFlags<Flags>(process.env.FLAGS) ?? ({} as Flags);
|
||||
return flags[flag] == null || !!flags[flag];
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +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.
|
||||
*/
|
||||
export class DefaultSdkClientFactory implements SdkClientFactory {
|
||||
async createSdkClient(
|
||||
...args: ConstructorParameters<typeof sdk.BitwardenClient>
|
||||
): Promise<sdk.BitwardenClient> {
|
||||
(sdk as any).init(module);
|
||||
|
||||
return Promise.resolve(new sdk.BitwardenClient(...args));
|
||||
}
|
||||
}
|
||||
95
libs/common/src/platform/services/sdk/default-sdk.service.ts
Normal file
95
libs/common/src/platform/services/sdk/default-sdk.service.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import { concatMap, shareReplay } from "rxjs";
|
||||
|
||||
import { LogLevel, DeviceType as SdkDeviceType } from "@bitwarden/sdk-internal";
|
||||
|
||||
import { DeviceType } from "../../../enums/device-type.enum";
|
||||
import { EnvironmentService } from "../../abstractions/environment.service";
|
||||
import { PlatformUtilsService } from "../../abstractions/platform-utils.service";
|
||||
import { SdkClientFactory } from "../../abstractions/sdk/sdk-client-factory";
|
||||
import { SdkService } from "../../abstractions/sdk/sdk.service";
|
||||
|
||||
export class DefaultSdkService implements SdkService {
|
||||
client$ = this.environmentService.environment$.pipe(
|
||||
concatMap(async (env) => {
|
||||
const settings = {
|
||||
apiUrl: env.getApiUrl(),
|
||||
identityUrl: env.getIdentityUrl(),
|
||||
deviceType: this.toDevice(this.platformUtilsService.getDevice()),
|
||||
userAgent: this.userAgent ?? navigator.userAgent,
|
||||
};
|
||||
|
||||
return await this.sdkClientFactory.createSdkClient(settings, LogLevel.Info);
|
||||
}),
|
||||
shareReplay({ refCount: true, bufferSize: 1 }),
|
||||
);
|
||||
|
||||
supported$ = this.client$.pipe(
|
||||
concatMap(async (client) => {
|
||||
return client.echo("bitwarden wasm!") === "bitwarden wasm!";
|
||||
}),
|
||||
);
|
||||
|
||||
constructor(
|
||||
private sdkClientFactory: SdkClientFactory,
|
||||
private environmentService: EnvironmentService,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private userAgent: string = null,
|
||||
) {}
|
||||
|
||||
private toDevice(device: DeviceType): SdkDeviceType {
|
||||
switch (device) {
|
||||
case DeviceType.Android:
|
||||
return "Android";
|
||||
case DeviceType.iOS:
|
||||
return "iOS";
|
||||
case DeviceType.ChromeExtension:
|
||||
return "ChromeExtension";
|
||||
case DeviceType.FirefoxExtension:
|
||||
return "FirefoxExtension";
|
||||
case DeviceType.OperaExtension:
|
||||
return "OperaExtension";
|
||||
case DeviceType.EdgeExtension:
|
||||
return "EdgeExtension";
|
||||
case DeviceType.WindowsDesktop:
|
||||
return "WindowsDesktop";
|
||||
case DeviceType.MacOsDesktop:
|
||||
return "MacOsDesktop";
|
||||
case DeviceType.LinuxDesktop:
|
||||
return "LinuxDesktop";
|
||||
case DeviceType.ChromeBrowser:
|
||||
return "ChromeBrowser";
|
||||
case DeviceType.FirefoxBrowser:
|
||||
return "FirefoxBrowser";
|
||||
case DeviceType.OperaBrowser:
|
||||
return "OperaBrowser";
|
||||
case DeviceType.EdgeBrowser:
|
||||
return "EdgeBrowser";
|
||||
case DeviceType.IEBrowser:
|
||||
return "IEBrowser";
|
||||
case DeviceType.UnknownBrowser:
|
||||
return "UnknownBrowser";
|
||||
case DeviceType.AndroidAmazon:
|
||||
return "AndroidAmazon";
|
||||
case DeviceType.UWP:
|
||||
return "UWP";
|
||||
case DeviceType.SafariBrowser:
|
||||
return "SafariBrowser";
|
||||
case DeviceType.VivaldiBrowser:
|
||||
return "VivaldiBrowser";
|
||||
case DeviceType.VivaldiExtension:
|
||||
return "VivaldiExtension";
|
||||
case DeviceType.SafariExtension:
|
||||
return "SafariExtension";
|
||||
case DeviceType.Server:
|
||||
return "Server";
|
||||
case DeviceType.WindowsCLI:
|
||||
return "WindowsCLI";
|
||||
case DeviceType.MacOsCLI:
|
||||
return "MacOsCLI";
|
||||
case DeviceType.LinuxCLI:
|
||||
return "LinuxCLI";
|
||||
default:
|
||||
return "SDK";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import type { BitwardenClient } from "@bitwarden/sdk-internal";
|
||||
|
||||
import { SdkClientFactory } from "../../abstractions/sdk/sdk-client-factory";
|
||||
|
||||
/**
|
||||
* Noop SDK client factory.
|
||||
*
|
||||
* Used during SDK rollout to prevent bundling the SDK with some applications.
|
||||
*/
|
||||
export class NoopSdkClientFactory implements SdkClientFactory {
|
||||
createSdkClient(
|
||||
...args: ConstructorParameters<typeof BitwardenClient>
|
||||
): Promise<BitwardenClient> {
|
||||
return Promise.reject(new Error("SDK not available"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user