1
0
mirror of https://github.com/bitwarden/browser synced 2026-01-31 00:33:33 +00:00

feat: working remote cipher decryption

This commit is contained in:
Andreas Coroiu
2025-10-31 10:05:13 +01:00
parent cab3ae843b
commit 91d37d51f1
5 changed files with 55 additions and 24 deletions

View File

@@ -159,7 +159,9 @@ import { MigrationBuilderService } from "@bitwarden/common/platform/services/mig
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 { LocalRemoteSdkService } from "@bitwarden/common/platform/services/sdk/local-remote-sdk.service";
import { NoopSdkClientFactory } from "@bitwarden/common/platform/services/sdk/noop-sdk-client-factory";
import { RemoteSdkService } from "@bitwarden/common/platform/services/sdk/remote-sdk.service";
import { SystemService } from "@bitwarden/common/platform/services/system.service";
import { UserAutoUnlockKeyService } from "@bitwarden/common/platform/services/user-auto-unlock-key.service";
import { PrimarySecondaryStorageService } from "@bitwarden/common/platform/storage/primary-secondary-storage.service";
@@ -476,6 +478,7 @@ export default class MainBackground {
loginToAutoFill: CipherView = null;
remoteSdkServerService: RemoteSdkServerService;
remoteSdkService: RemoteSdkService;
private commandsBackground: CommandsBackground;
private contextMenusBackground: ContextMenusBackground;
@@ -934,9 +937,16 @@ export default class MainBackground {
this.themeStateService = new DefaultThemeStateService(this.globalStateProvider);
this.remoteSdkService = new LocalRemoteSdkService(
this.sdkService,
this.accountService,
this.authService,
);
this.cipherEncryptionService = new DefaultCipherEncryptionService(
this.sdkService,
this.logService,
this.remoteSdkService,
);
this.cipherService = new CipherService(

View File

@@ -247,6 +247,8 @@ import { FileUploadService } from "@bitwarden/common/platform/services/file-uplo
import { MigrationBuilderService } from "@bitwarden/common/platform/services/migration-builder.service";
import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner";
import { DefaultSdkService } from "@bitwarden/common/platform/services/sdk/default-sdk.service";
import { LocalRemoteSdkService } from "@bitwarden/common/platform/services/sdk/local-remote-sdk.service";
import { RemoteSdkService } from "@bitwarden/common/platform/services/sdk/remote-sdk.service";
import { StorageServiceProvider } from "@bitwarden/common/platform/services/storage-service.provider";
import { UserAutoUnlockKeyService } from "@bitwarden/common/platform/services/user-auto-unlock-key.service";
import { ValidationService } from "@bitwarden/common/platform/services/validation.service";
@@ -1674,10 +1676,15 @@ const safeProviders: SafeProvider[] = [
useClass: DocumentLangSetter,
deps: [DOCUMENT, I18nServiceAbstraction],
}),
safeProvider({
provide: RemoteSdkService,
useClass: LocalRemoteSdkService,
deps: [SdkService, AccountServiceAbstraction, AuthServiceAbstraction],
}),
safeProvider({
provide: CipherEncryptionService,
useClass: DefaultCipherEncryptionService,
deps: [SdkService, LogService],
deps: [SdkService, LogService, RemoteSdkService],
}),
safeProvider({
provide: ChangePasswordService,

View File

@@ -97,9 +97,9 @@ export const DefaultFeatureFlagValue = {
/* Vault */
[FeatureFlag.CipherKeyEncryption]: FALSE,
[FeatureFlag.PM19941MigrateCipherDomainToSdk]: FALSE,
[FeatureFlag.PM22134SdkCipherListView]: FALSE,
[FeatureFlag.PM22136_SdkCipherEncryption]: FALSE,
[FeatureFlag.PM19941MigrateCipherDomainToSdk]: true,
[FeatureFlag.PM22134SdkCipherListView]: true,
[FeatureFlag.PM22136_SdkCipherEncryption]: true,
/* Auth */
[FeatureFlag.PM22110_DisableAlternateLoginMethods]: FALSE,
@@ -144,5 +144,15 @@ export function getFeatureFlagValue<Flag extends FeatureFlag>(
return DefaultFeatureFlagValue[flag];
}
const override = [
FeatureFlag.PM19941MigrateCipherDomainToSdk,
FeatureFlag.PM22134SdkCipherListView,
FeatureFlag.PM22136_SdkCipherEncryption,
];
if (override.includes(flag)) {
return true as FeatureFlagValueType<Flag>;
}
return serverConfig.featureStates[flag] as FeatureFlagValueType<Flag>;
}

View File

@@ -42,17 +42,18 @@ export class RpcServer<T> {
return { status: "error", error: `[RPC] Reference ID ${command.referenceId} not found` };
}
try {
if (!isSerializable(target)) {
return {
status: "error",
error: `[RPC] by_value() not supported for non-serializable object of type ${target?.constructor?.name}`,
};
}
return { status: "success", result: { type: "value", value: target } };
} catch (error) {
return { status: "error", error };
}
// try {
// Not a dependable check
// if (!isSerializable(target)) {
// return {
// status: "error",
// error: `[RPC] by_value() not supported for non-serializable object of type ${target?.constructor?.name}`,
// };
// }
return { status: "success", result: { type: "value", value: target } };
// } catch (error) {
// return { status: "error", error };
// }
}
if (command.method === "call") {

View File

@@ -1,4 +1,4 @@
import { EMPTY, catchError, firstValueFrom, map } from "rxjs";
import { EMPTY, catchError, firstValueFrom, map, switchMap } from "rxjs";
import { UserKey } from "@bitwarden/common/types/key";
import { EncryptionContext } from "@bitwarden/common/vault/abstractions/cipher.service";
@@ -11,6 +11,7 @@ import {
import { LogService } from "../../platform/abstractions/log.service";
import { SdkService, asUuid, uuidAsString } from "../../platform/abstractions/sdk/sdk.service";
import { RemoteSdkService } from "../../platform/services/sdk/remote-sdk.service";
import { UserId, OrganizationId } from "../../types/guid";
import { CipherEncryptionService } from "../abstractions/cipher-encryption.service";
import { CipherType } from "../enums";
@@ -23,6 +24,7 @@ export class DefaultCipherEncryptionService implements CipherEncryptionService {
constructor(
private sdkService: SdkService,
private logService: LogService,
private remoteSdkService: RemoteSdkService,
) {}
async encrypt(model: CipherView, userId: UserId): Promise<EncryptionContext | undefined> {
@@ -224,25 +226,26 @@ export class DefaultCipherEncryptionService implements CipherEncryptionService {
userId: UserId,
): Promise<[CipherListView[], Cipher[]]> {
return firstValueFrom(
this.sdkService.userClient$(userId).pipe(
map((sdk) => {
// this.sdkService.userClient$(userId).pipe(
this.remoteSdkService!.remoteClient$.pipe(
switchMap(async (sdk) => {
if (!sdk) {
throw new Error("SDK is undefined");
}
using ref = sdk.take();
using ref = await sdk.take();
const result: DecryptCipherListResult = ref.value
.vault()
.ciphers()
.decrypt_list_with_failures(ciphers.map((cipher) => cipher.toSdkCipher()));
const ciphersClient = await ref.value.vault().await.ciphers();
const result: DecryptCipherListResult = await ciphersClient
.decrypt_list_with_failures(ciphers.map((cipher) => cipher.toSdkCipher()))
.await.by_value();
const decryptedCiphers = result.successes;
const failedCiphers: Cipher[] = result.failures
.map((cipher) => Cipher.fromSdkCipher(cipher))
.filter((cipher): cipher is Cipher => cipher !== undefined);
return [decryptedCiphers, failedCiphers];
return [decryptedCiphers, failedCiphers] as [CipherListView[], Cipher[]];
}),
),
);