1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-22 04:14:04 +00:00

Merge branch 'main' into km/auto-kdf-qa

This commit is contained in:
Bernd Schoolmann
2025-11-12 15:22:58 +01:00
730 changed files with 23463 additions and 8142 deletions

View File

@@ -1,7 +1,7 @@
{
"name": "@bitwarden/cli",
"description": "A secure and free password manager for all of your devices.",
"version": "2025.10.1",
"version": "2025.11.0",
"keywords": [
"bitwarden",
"password",

View File

@@ -1,16 +1,22 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { VaultTimeoutService } from "@bitwarden/common/key-management/vault-timeout";
import { firstValueFrom } from "rxjs";
import { LockService } from "@bitwarden/auth/common";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { getUserId } from "@bitwarden/common/auth/services/account.service";
import { Response } from "../../models/response";
import { MessageResponse } from "../../models/response/message.response";
export class LockCommand {
constructor(private vaultTimeoutService: VaultTimeoutService) {}
constructor(
private lockService: LockService,
private accountService: AccountService,
) {}
async run() {
await this.vaultTimeoutService.lock();
process.env.BW_SESSION = null;
const activeUserId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
await this.lockService.lock(activeUserId);
process.env.BW_SESSION = undefined;
const res = new MessageResponse("Your vault is locked.", null);
return Response.success(res);
}

View File

@@ -1,6 +1,6 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { firstValueFrom, map, switchMap } from "rxjs";
import { filter, firstValueFrom, map, switchMap } from "rxjs";
import { CollectionService, CollectionView } from "@bitwarden/admin-console/common";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
@@ -448,7 +448,9 @@ export class GetCommand extends DownloadCommand {
this.collectionService.encryptedCollections$(activeUserId).pipe(getById(id)),
);
if (collection != null) {
const orgKeys = await firstValueFrom(this.keyService.activeUserOrgKeys$);
const orgKeys = await firstValueFrom(
this.keyService.orgKeys$(activeUserId).pipe(filter((orgKeys) => orgKeys != null)),
);
decCollection = await collection.decrypt(
orgKeys[collection.organizationId as OrganizationId],
this.encryptService,

View File

@@ -0,0 +1,10 @@
import { ProcessReloadServiceAbstraction } from "@bitwarden/common/key-management/abstractions/process-reload.service";
/**
* CLI implementation of ProcessReloadServiceAbstraction.
* This is NOOP since there is no effective way to process reload the CLI.
*/
export class CliProcessReloadService extends ProcessReloadServiceAbstraction {
async startProcessReload(): Promise<void> {}
async cancelProcessReload(): Promise<void> {}
}

View File

@@ -160,7 +160,10 @@ export class OssServeConfigurator {
this.serviceContainer.cipherService,
this.serviceContainer.accountService,
);
this.lockCommand = new LockCommand(this.serviceContainer.vaultTimeoutService);
this.lockCommand = new LockCommand(
serviceContainer.lockService,
serviceContainer.accountService,
);
this.unlockCommand = new UnlockCommand(
this.serviceContainer.accountService,
this.serviceContainer.masterPasswordService,

View File

@@ -0,0 +1,10 @@
import { SystemService } from "@bitwarden/common/platform/abstractions/system.service";
/**
* CLI implementation of SystemService.
* The implementation is NOOP since these functions are meant for GUI clients.
*/
export class CliSystemService extends SystemService {
async clearClipboard(clipboardValue: string, timeoutMs?: number): Promise<void> {}
async clearPendingClipboard(): Promise<any> {}
}

View File

@@ -251,7 +251,10 @@ export class Program extends BaseProgram {
return;
}
const command = new LockCommand(this.serviceContainer.vaultTimeoutService);
const command = new LockCommand(
this.serviceContainer.lockService,
this.serviceContainer.accountService,
);
const response = await command.run();
this.processResponse(response);
});

View File

@@ -20,6 +20,9 @@ import {
SsoUrlService,
AuthRequestApiServiceAbstraction,
DefaultAuthRequestApiService,
DefaultLockService,
DefaultLogoutService,
LockService,
} from "@bitwarden/auth/common";
import { EventCollectionService as EventCollectionServiceAbstraction } from "@bitwarden/common/abstractions/event/event-collection.service";
import { EventUploadService as EventUploadServiceAbstraction } from "@bitwarden/common/abstractions/event/event-upload.service";
@@ -203,9 +206,11 @@ import {
} from "@bitwarden/vault-export-core";
import { CliBiometricsService } from "../key-management/cli-biometrics-service";
import { CliProcessReloadService } from "../key-management/cli-process-reload.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 { CliSystemService } from "../platform/services/cli-system.service";
import { ConsoleLogService } from "../platform/services/console-log.service";
import { I18nService } from "../platform/services/i18n.service";
import { LowdbStorageService } from "../platform/services/lowdb-storage.service";
@@ -323,6 +328,7 @@ export class ServiceContainer {
securityStateService: SecurityStateService;
masterPasswordUnlockService: MasterPasswordUnlockService;
cipherArchiveService: CipherArchiveService;
lockService: LockService;
constructor() {
let p = null;
@@ -783,9 +789,6 @@ export class ServiceContainer {
this.folderApiService = new FolderApiService(this.folderService, this.apiService);
const lockedCallback = async (userId: UserId) =>
await this.keyService.clearStoredUserKey(userId);
this.userVerificationApiService = new UserVerificationApiService(this.apiService);
this.userVerificationService = new UserVerificationService(
@@ -801,25 +804,35 @@ export class ServiceContainer {
);
const biometricService = new CliBiometricsService();
const logoutService = new DefaultLogoutService(this.messagingService);
const processReloadService = new CliProcessReloadService();
const systemService = new CliSystemService();
this.lockService = new DefaultLockService(
this.accountService,
biometricService,
this.vaultTimeoutSettingsService,
logoutService,
this.messagingService,
this.searchService,
this.folderService,
this.masterPasswordService,
this.stateEventRunnerService,
this.cipherService,
this.authService,
systemService,
processReloadService,
this.logService,
this.keyService,
);
this.vaultTimeoutService = new DefaultVaultTimeoutService(
this.accountService,
this.masterPasswordService,
this.cipherService,
this.folderService,
this.collectionService,
this.platformUtilsService,
this.messagingService,
this.searchService,
this.stateService,
this.tokenService,
this.authService,
this.vaultTimeoutSettingsService,
this.stateEventRunnerService,
this.taskSchedulerService,
this.logService,
biometricService,
lockedCallback,
this.lockService,
undefined,
);

View File

@@ -92,18 +92,18 @@ export class CreateCommand {
}
private async createCipher(req: CipherExport) {
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
const cipherView = CipherExport.toView(req);
const isCipherTypeRestricted =
await this.cliRestrictedItemTypesService.isCipherRestricted(cipherView);
if (isCipherTypeRestricted) {
return Response.error("Creating this item type is restricted by organizational policy.");
}
const cipher = await this.cipherService.encrypt(CipherExport.toView(req), activeUserId);
try {
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
const cipherView = CipherExport.toView(req);
const isCipherTypeRestricted =
await this.cliRestrictedItemTypesService.isCipherRestricted(cipherView);
if (isCipherTypeRestricted) {
return Response.error("Creating this item type is restricted by organizational policy.");
}
const cipher = await this.cipherService.encrypt(CipherExport.toView(req), activeUserId);
const newCipher = await this.cipherService.createWithServer(cipher);
const decCipher = await this.cipherService.decrypt(newCipher, activeUserId);
const res = new CipherResponse(decCipher);