diff --git a/apps/browser/src/platform/services/sdk/remote-sdk-server.service.ts b/apps/browser/src/platform/services/sdk/remote-sdk-server.service.ts index 2edfcdac3ca..2e1962ba116 100644 --- a/apps/browser/src/platform/services/sdk/remote-sdk-server.service.ts +++ b/apps/browser/src/platform/services/sdk/remote-sdk-server.service.ts @@ -4,8 +4,8 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service"; +import { Rc } from "@bitwarden/common/platform/misc/reference-counting/rc"; import { RpcServer } from "@bitwarden/common/platform/services/sdk/rpc/server"; -import { Rc } from "@bitwarden/common/src/platform/misc/reference-counting/rc"; import { BitwardenClient } from "@bitwarden/sdk-internal"; import { BrowserApi } from "../../browser/browser-api"; diff --git a/libs/common/src/platform/services/sdk/local-remote-sdk.service.ts b/libs/common/src/platform/services/sdk/local-remote-sdk.service.ts new file mode 100644 index 00000000000..f619a6745d4 --- /dev/null +++ b/libs/common/src/platform/services/sdk/local-remote-sdk.service.ts @@ -0,0 +1,74 @@ +import { map, Observable, of, switchMap } from "rxjs"; + +import { BitwardenClient } from "@bitwarden/sdk-internal"; + +import { AccountService } from "../../../auth/abstractions/account.service"; +import { AuthService } from "../../../auth/abstractions/auth.service"; +import { AuthenticationStatus } from "../../../auth/enums/authentication-status"; +import { SdkService } from "../../abstractions/sdk/sdk.service"; +import { Rc } from "../../misc/reference-counting/rc"; + +import { RemoteSdkService } from "./remote-sdk.service"; +import { RpcClient, RpcRequestChannel } from "./rpc/client"; +import { Command, Response } from "./rpc/protocol"; +import { RpcServer } from "./rpc/server"; + +/** + * A LocalRemoteSdkService is an implementation of RemoteSdkService + * that forwards calls to the local SDK service. That way the + * consumers of RemoteSdkService can remain agnostic of whether + * they are using a local or remote SDK. + */ +export class LocalRemoteSdkService implements RemoteSdkService { + private server: RpcServer | null>; + private client: RpcClient | null>; + + constructor( + private sdkService: SdkService, + private accountService: AccountService, + private authService: AuthService, + ) { + this.server = new RpcServer | null>(); + this.client = new RpcClient | null>(new InMemoryChannel(this.server)); + + // TODO: This is hacky because we don't support multiple roots. + // Needs to be fixed. + this.accountService.activeAccount$ + .pipe( + switchMap((account) => { + if (!account) { + return of(null); + } + + return this.authService + .authStatusFor$(account.id) + .pipe(map((status) => ({ account, status }))); + }), + switchMap((accountStatus) => { + if (accountStatus == null || accountStatus.status !== AuthenticationStatus.Unlocked) { + return of(null); + } + return this.sdkService.userClient$(accountStatus.account.id); + }), + ) + .subscribe((client) => { + this.server.setValue(client); + }); + } + + get remoteClient$() { + return this.client.getRoot(); + } +} + +class InMemoryChannel implements RpcRequestChannel { + constructor(private server: RpcServer) {} + + async sendCommand(command: Command): Promise { + return await this.server.handle(command); + } + + subscribeToRoot(): Observable { + return this.server.value$.pipe(map((result) => ({ status: "success", result }))); + } +} diff --git a/libs/common/src/platform/services/sdk/remote-sdk.service.ts b/libs/common/src/platform/services/sdk/remote-sdk.service.ts index 63756045720..b62c3834e66 100644 --- a/libs/common/src/platform/services/sdk/remote-sdk.service.ts +++ b/libs/common/src/platform/services/sdk/remote-sdk.service.ts @@ -7,5 +7,5 @@ import { Rc } from "../../misc/reference-counting/rc"; import { Remote } from "./remote"; export abstract class RemoteSdkService { - abstract remoteClient$: Observable>>; + abstract remoteClient$: Observable | null>>; }