1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-13 23:03:32 +00:00

feat: add support for IPC client managed session storage

This commit is contained in:
Andreas Coroiu
2025-11-06 09:27:22 +01:00
parent a66227638e
commit b125c7e680
7 changed files with 70 additions and 5 deletions

View File

@@ -131,7 +131,7 @@ import {
} from "@bitwarden/common/platform/abstractions/storage.service";
import { SystemService as SystemServiceAbstraction } from "@bitwarden/common/platform/abstractions/system.service";
import { ActionsService } from "@bitwarden/common/platform/actions/actions-service";
import { IpcService } from "@bitwarden/common/platform/ipc";
import { IpcService, IpcSessionRepository } from "@bitwarden/common/platform/ipc";
import { Message, MessageListener, MessageSender } from "@bitwarden/common/platform/messaging";
// eslint-disable-next-line no-restricted-imports -- Used for dependency creation
import { SubjectMessageSender } from "@bitwarden/common/platform/messaging/internal";
@@ -1476,7 +1476,12 @@ export default class MainBackground {
);
this.ipcContentScriptManagerService = new IpcContentScriptManagerService(this.configService);
this.ipcService = new IpcBackgroundService(this.platformUtilsService, this.logService);
const ipcSessionRepository = new IpcSessionRepository(this.stateProvider);
this.ipcService = new IpcBackgroundService(
this.platformUtilsService,
this.logService,
ipcSessionRepository,
);
this.endUserNotificationService = new DefaultEndUserNotificationService(
this.stateProvider,

View File

@@ -8,6 +8,7 @@ import {
OutgoingMessage,
ipcRegisterDiscoverHandler,
IpcClient,
IpcSessionRepository,
} from "@bitwarden/sdk-internal";
import { BrowserApi } from "../browser/browser-api";
@@ -18,6 +19,7 @@ export class IpcBackgroundService extends IpcService {
constructor(
private platformUtilsService: PlatformUtilsService,
private logService: LogService,
private sessionRepository: IpcSessionRepository,
) {
super();
}
@@ -70,7 +72,9 @@ export class IpcBackgroundService extends IpcService {
);
});
await super.initWithClient(new IpcClient(this.communicationBackend));
await super.initWithClient(
IpcClient.newWithClientManagedSessions(this.communicationBackend, this.sessionRepository),
);
if (this.platformUtilsService.isDev()) {
await ipcRegisterDiscoverHandler(this.client, {

View File

@@ -3,7 +3,12 @@ import { inject } from "@angular/core";
import { LogService } 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 { IpcMessage, IpcService, isIpcMessage } from "@bitwarden/common/platform/ipc";
import {
IpcMessage,
IpcService,
isIpcMessage,
IpcSessionRepository,
} from "@bitwarden/common/platform/ipc";
import {
IncomingMessage,
IpcClient,
@@ -15,6 +20,7 @@ import {
export class WebIpcService extends IpcService {
private logService = inject(LogService);
private platformUtilsService = inject(PlatformUtilsService);
private sessionRepository = inject(IpcSessionRepository);
private communicationBackend?: IpcCommunicationBackend;
override async init() {
@@ -70,7 +76,9 @@ export class WebIpcService extends IpcService {
);
});
await super.initWithClient(new IpcClient(this.communicationBackend));
await super.initWithClient(
IpcClient.newWithClientManagedSessions(this.communicationBackend, this.sessionRepository),
);
if (this.platformUtilsService.isDev()) {
await ipcRegisterDiscoverHandler(this.client, {

View File

@@ -226,6 +226,7 @@ import { SystemService } from "@bitwarden/common/platform/abstractions/system.se
import { ValidationService as ValidationServiceAbstraction } from "@bitwarden/common/platform/abstractions/validation.service";
import { ActionsService } from "@bitwarden/common/platform/actions";
import { UnsupportedActionsService } from "@bitwarden/common/platform/actions/unsupported-actions.service";
import { IpcSessionRepository } from "@bitwarden/common/platform/ipc";
import { Message, MessageListener, MessageSender } from "@bitwarden/common/platform/messaging";
// eslint-disable-next-line no-restricted-imports -- Used for dependency injection
import { SubjectMessageSender } from "@bitwarden/common/platform/messaging/internal";
@@ -1743,6 +1744,7 @@ const safeProviders: SafeProvider[] = [
useClass: DefaultNewDeviceVerificationComponentService,
deps: [],
}),
safeProvider(IpcSessionRepository),
safeProvider({
provide: PremiumInterestStateService,
useClass: NoopPremiumInterestStateService,

View File

@@ -1,2 +1,3 @@
export * from "./ipc-message";
export * from "./ipc.service";
export * from "./ipc-session-repository";

View File

@@ -0,0 +1,44 @@
import { firstValueFrom, map } from "rxjs";
import { Endpoint, IpcSessionRepository as SdkIpcSessionRepository } from "@bitwarden/sdk-internal";
import { GlobalState, IPC_MEMORY, KeyDefinition, StateProvider } from "../state";
const IPC_SESSIONS = KeyDefinition.record<object, string>(IPC_MEMORY, "ipcSessions", {
deserializer: (value: object) => value,
});
export class IpcSessionRepository implements SdkIpcSessionRepository {
private states: GlobalState<Record<string, object>>;
constructor(private stateProvider: StateProvider) {
this.states = this.stateProvider.getGlobal(IPC_SESSIONS);
}
get(endpoint: Endpoint): Promise<any | undefined> {
return firstValueFrom(this.states.state$.pipe(map((s) => s?.[endpointToString(endpoint)])));
}
async save(endpoint: Endpoint, session: any): Promise<void> {
await this.states.update((s) => ({
...s,
[endpointToString(endpoint)]: session,
}));
}
async remove(endpoint: Endpoint): Promise<void> {
await this.states.update((s) => {
const newState = { ...s };
delete newState[endpointToString(endpoint)];
return newState;
});
}
}
function endpointToString(endpoint: Endpoint): string {
if (typeof endpoint === "object" && "Web" in endpoint) {
return `Web(${endpoint.Web.id})`;
}
return endpoint;
}

View File

@@ -127,6 +127,7 @@ export const CRYPTO_MEMORY = new StateDefinition("crypto", "memory");
export const DESKTOP_SETTINGS_DISK = new StateDefinition("desktopSettings", "disk");
export const ENVIRONMENT_DISK = new StateDefinition("environment", "disk");
export const ENVIRONMENT_MEMORY = new StateDefinition("environment", "memory");
export const IPC_MEMORY = new StateDefinition("ipc", "memory");
export const POPUP_VIEW_MEMORY = new StateDefinition("popupView", "memory", {
browser: "memory-large-object",
});