mirror of
https://github.com/bitwarden/browser.git
synced 2024-09-27 04:03:00 +02:00
Merge remote-tracking branch 'origin/main' into ps/pm-10744/remove-get-bg-service
This commit is contained in:
commit
15077e6094
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@bitwarden/browser",
|
||||
"version": "2024.9.1",
|
||||
"version": "2024.9.2",
|
||||
"scripts": {
|
||||
"build": "cross-env MANIFEST_VERSION=3 webpack",
|
||||
"build:mv2": "webpack",
|
||||
|
@ -2374,6 +2374,10 @@
|
||||
"message": "Are you sure you want to delete this Send?",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"deleteSendPermanentConfirmation": {
|
||||
"message": "Are you sure you want to permanently delete this Send?",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"editSend": {
|
||||
"message": "Edit Send",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
|
@ -416,7 +416,7 @@ export default class MainBackground {
|
||||
this.logService = new ConsoleLogService(isDev);
|
||||
this.cryptoFunctionService = new WebCryptoFunctionService(self);
|
||||
this.keyGenerationService = new KeyGenerationService(this.cryptoFunctionService);
|
||||
this.storageService = new BrowserLocalStorageService();
|
||||
this.storageService = new BrowserLocalStorageService(this.logService);
|
||||
|
||||
this.intraprocessMessagingSubject = new Subject<Message<Record<string, unknown>>>();
|
||||
|
||||
@ -681,6 +681,7 @@ export default class MainBackground {
|
||||
|
||||
this.collectionService = new CollectionService(
|
||||
this.cryptoService,
|
||||
this.encryptService,
|
||||
this.i18nService,
|
||||
this.stateProvider,
|
||||
);
|
||||
@ -791,9 +792,11 @@ export default class MainBackground {
|
||||
this.cipherFileUploadService,
|
||||
this.configService,
|
||||
this.stateProvider,
|
||||
this.accountService,
|
||||
);
|
||||
this.folderService = new FolderService(
|
||||
this.cryptoService,
|
||||
this.encryptService,
|
||||
this.i18nService,
|
||||
this.cipherService,
|
||||
this.stateProvider,
|
||||
@ -947,6 +950,7 @@ export default class MainBackground {
|
||||
this.i18nService,
|
||||
this.collectionService,
|
||||
this.cryptoService,
|
||||
this.encryptService,
|
||||
this.pinService,
|
||||
this.accountService,
|
||||
);
|
||||
@ -956,8 +960,10 @@ export default class MainBackground {
|
||||
this.cipherService,
|
||||
this.pinService,
|
||||
this.cryptoService,
|
||||
this.encryptService,
|
||||
this.cryptoFunctionService,
|
||||
this.kdfConfigService,
|
||||
this.accountService,
|
||||
);
|
||||
|
||||
this.organizationVaultExportService = new OrganizationVaultExportService(
|
||||
@ -965,6 +971,7 @@ export default class MainBackground {
|
||||
this.apiService,
|
||||
this.pinService,
|
||||
this.cryptoService,
|
||||
this.encryptService,
|
||||
this.cryptoFunctionService,
|
||||
this.collectionService,
|
||||
this.kdfConfigService,
|
||||
@ -1068,6 +1075,7 @@ export default class MainBackground {
|
||||
);
|
||||
this.nativeMessagingBackground = new NativeMessagingBackground(
|
||||
this.cryptoService,
|
||||
this.encryptService,
|
||||
this.cryptoFunctionService,
|
||||
this.runtimeBackground,
|
||||
this.messagingService,
|
||||
|
@ -6,6 +6,7 @@ import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authenticatio
|
||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@ -73,6 +74,7 @@ export class NativeMessagingBackground {
|
||||
|
||||
constructor(
|
||||
private cryptoService: CryptoService,
|
||||
private encryptService: EncryptService,
|
||||
private cryptoFunctionService: CryptoFunctionService,
|
||||
private runtimeBackground: RuntimeBackground,
|
||||
private messagingService: MessagingService,
|
||||
@ -227,7 +229,7 @@ export class NativeMessagingBackground {
|
||||
await this.secureCommunication();
|
||||
}
|
||||
|
||||
return await this.cryptoService.encrypt(JSON.stringify(message), this.sharedSecret);
|
||||
return await this.encryptService.encrypt(JSON.stringify(message), this.sharedSecret);
|
||||
}
|
||||
|
||||
getResponse(): Promise<any> {
|
||||
@ -273,7 +275,7 @@ export class NativeMessagingBackground {
|
||||
let message = rawMessage as ReceiveMessage;
|
||||
if (!this.platformUtilsService.isSafari()) {
|
||||
message = JSON.parse(
|
||||
await this.cryptoService.decryptToUtf8(rawMessage as EncString, this.sharedSecret),
|
||||
await this.encryptService.decryptToUtf8(rawMessage as EncString, this.sharedSecret),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
"manifest_version": 2,
|
||||
"name": "__MSG_extName__",
|
||||
"short_name": "__MSG_appName__",
|
||||
"version": "2024.9.1",
|
||||
"version": "2024.9.2",
|
||||
"description": "__MSG_extDesc__",
|
||||
"default_locale": "en",
|
||||
"author": "Bitwarden Inc.",
|
||||
|
@ -3,7 +3,7 @@
|
||||
"minimum_chrome_version": "102.0",
|
||||
"name": "__MSG_extName__",
|
||||
"short_name": "__MSG_appName__",
|
||||
"version": "2024.9.1",
|
||||
"version": "2024.9.2",
|
||||
"description": "__MSG_extDesc__",
|
||||
"default_locale": "en",
|
||||
"author": "Bitwarden Inc.",
|
||||
|
@ -1,10 +1,67 @@
|
||||
import AbstractChromeStorageService from "./abstractions/abstract-chrome-storage-api.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
|
||||
import AbstractChromeStorageService, {
|
||||
SerializedValue,
|
||||
} from "./abstractions/abstract-chrome-storage-api.service";
|
||||
|
||||
export default class BrowserLocalStorageService extends AbstractChromeStorageService {
|
||||
constructor() {
|
||||
constructor(private readonly logService: LogService) {
|
||||
super(chrome.storage.local);
|
||||
}
|
||||
|
||||
override async get<T>(key: string): Promise<T> {
|
||||
return await this.getWithRetries<T>(key, 0);
|
||||
}
|
||||
|
||||
private async getWithRetries<T>(key: string, retryNum: number): Promise<T> {
|
||||
// See: https://github.com/EFForg/privacybadger/pull/2980
|
||||
const MAX_RETRIES = 5;
|
||||
const WAIT_TIME = 200;
|
||||
|
||||
const store = await this.getStore(key);
|
||||
|
||||
if (store == null) {
|
||||
if (retryNum >= MAX_RETRIES) {
|
||||
throw new Error(`Failed to get a value for key '${key}', see logs for more details.`);
|
||||
}
|
||||
|
||||
retryNum++;
|
||||
this.logService.warning(`Retrying attempt to get value for key '${key}' in ${WAIT_TIME}ms`);
|
||||
await new Promise<void>((resolve) => setTimeout(resolve, WAIT_TIME));
|
||||
return await this.getWithRetries(key, retryNum);
|
||||
}
|
||||
|
||||
// We have a store
|
||||
return this.processGetObject<T>(store[key] as T | SerializedValue);
|
||||
}
|
||||
|
||||
private async getStore(key: string) {
|
||||
if (this.chromeStorageApi == null) {
|
||||
this.logService.warning(
|
||||
`chrome.storage.local was not initialized while retrieving key '${key}'.`,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Promise<{ [key: string]: unknown }>((resolve) => {
|
||||
this.chromeStorageApi.get(key, (store) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
this.logService.warning(`Failed to get value for key '${key}'`, chrome.runtime.lastError);
|
||||
resolve(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (store == null) {
|
||||
this.logService.warning(`Store was empty while retrieving value for key '${key}'`);
|
||||
resolve(null);
|
||||
return;
|
||||
}
|
||||
|
||||
resolve(store);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async fillBuffer() {
|
||||
// Write 4MB of data in chrome.storage.local, log files will hold 4MB of data (by default)
|
||||
// before forcing a compaction. To force a compaction and have it remove previously saved data,
|
||||
|
@ -305,7 +305,7 @@ const safeProviders: SafeProvider[] = [
|
||||
safeProvider({
|
||||
provide: AbstractStorageService,
|
||||
useClass: BrowserLocalStorageService,
|
||||
deps: [],
|
||||
deps: [LogService],
|
||||
}),
|
||||
safeProvider({
|
||||
provide: AutofillServiceAbstraction,
|
||||
|
@ -13,5 +13,14 @@
|
||||
<button bitButton type="submit" form="sendForm" buttonType="primary" #submitBtn>
|
||||
{{ "save" | i18n }}
|
||||
</button>
|
||||
<button
|
||||
*ngIf="config?.mode !== 'add'"
|
||||
type="button"
|
||||
buttonType="danger"
|
||||
class="tw-ml-auto bwi-lg"
|
||||
bitIconButton="bwi-trash"
|
||||
[bitAction]="deleteSend"
|
||||
appA11yTitle="{{ 'delete' | i18n }}"
|
||||
></button>
|
||||
</popup-footer>
|
||||
</popup-page>
|
||||
|
@ -8,8 +8,16 @@ import { map, switchMap } from "rxjs";
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
|
||||
import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction";
|
||||
import { SendId } from "@bitwarden/common/types/guid";
|
||||
import { AsyncActionsModule, ButtonModule, SearchModule } from "@bitwarden/components";
|
||||
import {
|
||||
AsyncActionsModule,
|
||||
ButtonModule,
|
||||
DialogService,
|
||||
IconButtonModule,
|
||||
SearchModule,
|
||||
ToastService,
|
||||
} from "@bitwarden/components";
|
||||
import {
|
||||
DefaultSendFormConfigService,
|
||||
SendFormConfig,
|
||||
@ -58,6 +66,7 @@ export type AddEditQueryParams = Partial<Record<keyof QueryParams, string>>;
|
||||
JslibModule,
|
||||
FormsModule,
|
||||
ButtonModule,
|
||||
IconButtonModule,
|
||||
PopupPageComponent,
|
||||
PopupHeaderComponent,
|
||||
PopupFooterComponent,
|
||||
@ -81,6 +90,9 @@ export class SendAddEditComponent {
|
||||
private location: Location,
|
||||
private i18nService: I18nService,
|
||||
private addEditFormConfigService: SendFormConfigService,
|
||||
private sendApiService: SendApiService,
|
||||
private toastService: ToastService,
|
||||
private dialogService: DialogService,
|
||||
) {
|
||||
this.subscribeToParams();
|
||||
}
|
||||
@ -92,6 +104,37 @@ export class SendAddEditComponent {
|
||||
this.location.back();
|
||||
}
|
||||
|
||||
deleteSend = async () => {
|
||||
const confirmed = await this.dialogService.openSimpleDialog({
|
||||
title: { key: "deleteSend" },
|
||||
content: { key: "deleteSendPermanentConfirmation" },
|
||||
type: "warning",
|
||||
});
|
||||
|
||||
if (!confirmed) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.sendApiService.delete(this.config.originalSend?.id);
|
||||
} catch (e) {
|
||||
this.toastService.showToast({
|
||||
variant: "error",
|
||||
title: null,
|
||||
message: e.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.location.back();
|
||||
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
title: null,
|
||||
message: this.i18nService.t("deletedSend"),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Subscribes to the route query parameters and builds the configuration based on the parameters.
|
||||
*/
|
||||
|
@ -1,9 +1,13 @@
|
||||
import { DIALOG_DATA, DialogRef } from "@angular/cdk/dialog";
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
||||
import { BehaviorSubject } from "rxjs";
|
||||
|
||||
import { AccountInfo, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { FolderApiServiceAbstraction } from "@bitwarden/common/vault/abstractions/folder/folder-api.service.abstraction";
|
||||
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
||||
import { Folder } from "@bitwarden/common/vault/models/domain/folder";
|
||||
@ -25,6 +29,7 @@ describe("AddEditFolderDialogComponent", () => {
|
||||
const save = jest.fn().mockResolvedValue(null);
|
||||
const deleteFolder = jest.fn().mockResolvedValue(null);
|
||||
const openSimpleDialog = jest.fn().mockResolvedValue(true);
|
||||
const getUserKeyWithLegacySupport = jest.fn().mockResolvedValue("");
|
||||
const error = jest.fn();
|
||||
const close = jest.fn();
|
||||
const showToast = jest.fn();
|
||||
@ -41,12 +46,29 @@ describe("AddEditFolderDialogComponent", () => {
|
||||
close.mockClear();
|
||||
showToast.mockClear();
|
||||
|
||||
const userId = "" as UserId;
|
||||
const accountInfo: AccountInfo = {
|
||||
email: "",
|
||||
emailVerified: true,
|
||||
name: undefined,
|
||||
};
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [AddEditFolderDialogComponent, NoopAnimationsModule],
|
||||
providers: [
|
||||
{ provide: I18nService, useValue: { t: (key: string) => key } },
|
||||
{ provide: FolderService, useValue: { encrypt } },
|
||||
{ provide: FolderApiServiceAbstraction, useValue: { save, delete: deleteFolder } },
|
||||
{
|
||||
provide: AccountService,
|
||||
useValue: { activeAccount$: new BehaviorSubject({ id: userId, ...accountInfo }) },
|
||||
},
|
||||
{
|
||||
provide: CryptoService,
|
||||
useValue: {
|
||||
getUserKeyWithLegacySupport,
|
||||
},
|
||||
},
|
||||
{ provide: LogService, useValue: { error } },
|
||||
{ provide: ToastService, useValue: { showToast } },
|
||||
{ provide: DIALOG_DATA, useValue: dialogData },
|
||||
@ -82,7 +104,7 @@ describe("AddEditFolderDialogComponent", () => {
|
||||
const newFolder = new FolderView();
|
||||
newFolder.name = "New Folder";
|
||||
|
||||
expect(encrypt).toHaveBeenCalledWith(newFolder);
|
||||
expect(encrypt).toHaveBeenCalledWith(newFolder, "");
|
||||
expect(save).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@ -137,10 +159,13 @@ describe("AddEditFolderDialogComponent", () => {
|
||||
component.folderForm.controls.name.setValue("Edited Folder");
|
||||
await component.submit();
|
||||
|
||||
expect(encrypt).toHaveBeenCalledWith({
|
||||
...dialogData.editFolderConfig.folder,
|
||||
name: "Edited Folder",
|
||||
});
|
||||
expect(encrypt).toHaveBeenCalledWith(
|
||||
{
|
||||
...dialogData.editFolderConfig.folder,
|
||||
name: "Edited Folder",
|
||||
},
|
||||
"",
|
||||
);
|
||||
});
|
||||
|
||||
it("deletes the folder", async () => {
|
||||
|
@ -11,8 +11,11 @@ import {
|
||||
} from "@angular/core";
|
||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||
import { FormBuilder, ReactiveFormsModule, Validators } from "@angular/forms";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { FolderApiServiceAbstraction } from "@bitwarden/common/vault/abstractions/folder/folder-api.service.abstraction";
|
||||
@ -68,6 +71,8 @@ export class AddEditFolderDialogComponent implements AfterViewInit, OnInit {
|
||||
private formBuilder: FormBuilder,
|
||||
private folderService: FolderService,
|
||||
private folderApiService: FolderApiServiceAbstraction,
|
||||
private accountService: AccountService,
|
||||
private cryptoService: CryptoService,
|
||||
private toastService: ToastService,
|
||||
private i18nService: I18nService,
|
||||
private logService: LogService,
|
||||
@ -107,7 +112,9 @@ export class AddEditFolderDialogComponent implements AfterViewInit, OnInit {
|
||||
this.folder.name = this.folderForm.controls.name.value;
|
||||
|
||||
try {
|
||||
const folder = await this.folderService.encrypt(this.folder);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$);
|
||||
const userKey = await this.cryptoService.getUserKeyWithLegacySupport(activeUserId.id);
|
||||
const folder = await this.folderService.encrypt(this.folder, userKey);
|
||||
await this.folderApiService.save(folder);
|
||||
|
||||
this.toastService.showToast({
|
||||
|
@ -8,6 +8,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
@ -28,6 +29,7 @@ export class AttachmentsComponent extends BaseAttachmentsComponent implements On
|
||||
cipherService: CipherService,
|
||||
i18nService: I18nService,
|
||||
cryptoService: CryptoService,
|
||||
encryptService: EncryptService,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
apiService: ApiService,
|
||||
private location: Location,
|
||||
@ -44,6 +46,7 @@ export class AttachmentsComponent extends BaseAttachmentsComponent implements On
|
||||
cipherService,
|
||||
i18nService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
platformUtilsService,
|
||||
apiService,
|
||||
window,
|
||||
|
@ -13,6 +13,7 @@ import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
@ -80,6 +81,7 @@ export class ViewComponent extends BaseViewComponent implements OnInit, OnDestro
|
||||
tokenService: TokenService,
|
||||
i18nService: I18nService,
|
||||
cryptoService: CryptoService,
|
||||
encryptService: EncryptService,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
auditService: AuditService,
|
||||
private route: ActivatedRoute,
|
||||
@ -108,6 +110,7 @@ export class ViewComponent extends BaseViewComponent implements OnInit, OnDestro
|
||||
tokenService,
|
||||
i18nService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
platformUtilsService,
|
||||
auditService,
|
||||
window,
|
||||
|
@ -4,6 +4,8 @@ import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { first } from "rxjs/operators";
|
||||
|
||||
import { FolderAddEditComponent as BaseFolderAddEditComponent } from "@bitwarden/angular/vault/components/folder-add-edit.component";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@ -20,6 +22,8 @@ export class FolderAddEditComponent extends BaseFolderAddEditComponent implement
|
||||
constructor(
|
||||
folderService: FolderService,
|
||||
folderApiService: FolderApiServiceAbstraction,
|
||||
accountService: AccountService,
|
||||
cryptoService: CryptoService,
|
||||
i18nService: I18nService,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
private router: Router,
|
||||
@ -31,6 +35,8 @@ export class FolderAddEditComponent extends BaseFolderAddEditComponent implement
|
||||
super(
|
||||
folderService,
|
||||
folderApiService,
|
||||
accountService,
|
||||
cryptoService,
|
||||
i18nService,
|
||||
platformUtilsService,
|
||||
logService,
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@bitwarden/cli",
|
||||
"description": "A secure and free password manager for all of your devices.",
|
||||
"version": "2024.9.0",
|
||||
"version": "2024.9.1",
|
||||
"keywords": [
|
||||
"bitwarden",
|
||||
"password",
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as fet from "node-fetch";
|
||||
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||
|
||||
@ -9,7 +9,7 @@ import { FileResponse } from "../models/response/file.response";
|
||||
import { CliUtils } from "../utils";
|
||||
|
||||
export abstract class DownloadCommand {
|
||||
constructor(protected cryptoService: CryptoService) {}
|
||||
constructor(protected encryptService: EncryptService) {}
|
||||
|
||||
protected async saveAttachmentToFile(
|
||||
url: string,
|
||||
@ -26,7 +26,7 @@ export abstract class DownloadCommand {
|
||||
|
||||
try {
|
||||
const encBuf = await EncArrayBuffer.fromResponse(response);
|
||||
const decBuf = await this.cryptoService.decryptFromBytes(encBuf, key);
|
||||
const decBuf = await this.encryptService.decryptToBytes(encBuf, key);
|
||||
if (process.env.BW_SERVE === "true") {
|
||||
const res = new FileResponse(Buffer.from(decBuf), fileName);
|
||||
return Response.success(res);
|
||||
|
@ -7,6 +7,7 @@ import { CipherExport } from "@bitwarden/common/models/export/cipher.export";
|
||||
import { CollectionExport } from "@bitwarden/common/models/export/collection.export";
|
||||
import { FolderExport } from "@bitwarden/common/models/export/folder.export";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { FolderApiServiceAbstraction } from "@bitwarden/common/vault/abstractions/folder/folder-api.service.abstraction";
|
||||
@ -25,6 +26,7 @@ export class EditCommand {
|
||||
private cipherService: CipherService,
|
||||
private folderService: FolderService,
|
||||
private cryptoService: CryptoService,
|
||||
private encryptService: EncryptService,
|
||||
private apiService: ApiService,
|
||||
private folderApiService: FolderApiServiceAbstraction,
|
||||
private accountService: AccountService,
|
||||
@ -139,7 +141,10 @@ export class EditCommand {
|
||||
|
||||
let folderView = await folder.decrypt();
|
||||
folderView = FolderExport.toView(req, folderView);
|
||||
const encFolder = await this.folderService.encrypt(folderView);
|
||||
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$);
|
||||
const userKey = await this.cryptoService.getUserKeyWithLegacySupport(activeUserId.id);
|
||||
const encFolder = await this.folderService.encrypt(folderView, userKey);
|
||||
try {
|
||||
await this.folderApiService.save(encFolder);
|
||||
const updatedFolder = await this.folderService.get(folder.id);
|
||||
@ -187,7 +192,7 @@ export class EditCommand {
|
||||
(u) => new SelectionReadOnlyRequest(u.id, u.readOnly, u.hidePasswords, u.manage),
|
||||
);
|
||||
const request = new CollectionRequest();
|
||||
request.name = (await this.cryptoService.encrypt(req.name, orgKey)).encryptedString;
|
||||
request.name = (await this.encryptService.encrypt(req.name, orgKey)).encryptedString;
|
||||
request.externalId = req.externalId;
|
||||
request.groups = groups;
|
||||
request.users = users;
|
||||
|
@ -20,6 +20,7 @@ import { LoginExport } from "@bitwarden/common/models/export/login.export";
|
||||
import { SecureNoteExport } from "@bitwarden/common/models/export/secure-note.export";
|
||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||
@ -56,7 +57,8 @@ export class GetCommand extends DownloadCommand {
|
||||
private collectionService: CollectionService,
|
||||
private totpService: TotpService,
|
||||
private auditService: AuditService,
|
||||
cryptoService: CryptoService,
|
||||
private cryptoService: CryptoService,
|
||||
encryptService: EncryptService,
|
||||
private stateService: StateService,
|
||||
private searchService: SearchService,
|
||||
private apiService: ApiService,
|
||||
@ -65,7 +67,7 @@ export class GetCommand extends DownloadCommand {
|
||||
private accountProfileService: BillingAccountProfileStateService,
|
||||
private accountService: AccountService,
|
||||
) {
|
||||
super(cryptoService);
|
||||
super(encryptService);
|
||||
}
|
||||
|
||||
async run(object: string, id: string, cmdOptions: Record<string, any>): Promise<Response> {
|
||||
@ -451,7 +453,7 @@ export class GetCommand extends DownloadCommand {
|
||||
|
||||
const response = await this.apiService.getCollectionAccessDetails(options.organizationId, id);
|
||||
const decCollection = new CollectionView(response);
|
||||
decCollection.name = await this.cryptoService.decryptToUtf8(
|
||||
decCollection.name = await this.encryptService.decryptToUtf8(
|
||||
new EncString(response.name),
|
||||
orgKey,
|
||||
);
|
||||
|
@ -57,6 +57,7 @@ export class OssServeConfigurator {
|
||||
this.serviceContainer.totpService,
|
||||
this.serviceContainer.auditService,
|
||||
this.serviceContainer.cryptoService,
|
||||
this.serviceContainer.encryptService,
|
||||
this.serviceContainer.stateService,
|
||||
this.serviceContainer.searchService,
|
||||
this.serviceContainer.apiService,
|
||||
@ -79,6 +80,7 @@ export class OssServeConfigurator {
|
||||
this.serviceContainer.cipherService,
|
||||
this.serviceContainer.folderService,
|
||||
this.serviceContainer.cryptoService,
|
||||
this.serviceContainer.encryptService,
|
||||
this.serviceContainer.apiService,
|
||||
this.serviceContainer.folderApiService,
|
||||
this.serviceContainer.billingAccountProfileStateService,
|
||||
@ -89,6 +91,7 @@ export class OssServeConfigurator {
|
||||
this.serviceContainer.cipherService,
|
||||
this.serviceContainer.folderService,
|
||||
this.serviceContainer.cryptoService,
|
||||
this.serviceContainer.encryptService,
|
||||
this.serviceContainer.apiService,
|
||||
this.serviceContainer.folderApiService,
|
||||
this.serviceContainer.accountService,
|
||||
@ -150,7 +153,7 @@ export class OssServeConfigurator {
|
||||
this.serviceContainer.sendService,
|
||||
this.serviceContainer.environmentService,
|
||||
this.serviceContainer.searchService,
|
||||
this.serviceContainer.cryptoService,
|
||||
this.serviceContainer.encryptService,
|
||||
);
|
||||
this.sendEditCommand = new SendEditCommand(
|
||||
this.serviceContainer.sendService,
|
||||
|
@ -494,6 +494,7 @@ export class ServiceContainer {
|
||||
|
||||
this.collectionService = new CollectionService(
|
||||
this.cryptoService,
|
||||
this.encryptService,
|
||||
this.i18nService,
|
||||
this.stateProvider,
|
||||
);
|
||||
@ -631,10 +632,12 @@ export class ServiceContainer {
|
||||
this.cipherFileUploadService,
|
||||
this.configService,
|
||||
this.stateProvider,
|
||||
this.accountService,
|
||||
);
|
||||
|
||||
this.folderService = new FolderService(
|
||||
this.cryptoService,
|
||||
this.encryptService,
|
||||
this.i18nService,
|
||||
this.cipherService,
|
||||
this.stateProvider,
|
||||
@ -721,6 +724,7 @@ export class ServiceContainer {
|
||||
this.i18nService,
|
||||
this.collectionService,
|
||||
this.cryptoService,
|
||||
this.encryptService,
|
||||
this.pinService,
|
||||
this.accountService,
|
||||
);
|
||||
@ -730,8 +734,10 @@ export class ServiceContainer {
|
||||
this.cipherService,
|
||||
this.pinService,
|
||||
this.cryptoService,
|
||||
this.encryptService,
|
||||
this.cryptoFunctionService,
|
||||
this.kdfConfigService,
|
||||
this.accountService,
|
||||
);
|
||||
|
||||
this.organizationExportService = new OrganizationVaultExportService(
|
||||
@ -739,6 +745,7 @@ export class ServiceContainer {
|
||||
this.apiService,
|
||||
this.pinService,
|
||||
this.cryptoService,
|
||||
this.encryptService,
|
||||
this.cryptoFunctionService,
|
||||
this.collectionService,
|
||||
this.kdfConfigService,
|
||||
|
@ -2,7 +2,7 @@ import { OptionValues } from "commander";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { SearchService } from "@bitwarden/common/abstractions/search.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
|
||||
@ -17,9 +17,9 @@ export class SendGetCommand extends DownloadCommand {
|
||||
private sendService: SendService,
|
||||
private environmentService: EnvironmentService,
|
||||
private searchService: SearchService,
|
||||
cryptoService: CryptoService,
|
||||
encryptService: EncryptService,
|
||||
) {
|
||||
super(cryptoService);
|
||||
super(encryptService);
|
||||
}
|
||||
|
||||
async run(id: string, options: OptionValues) {
|
||||
|
@ -2,10 +2,10 @@ import { OptionValues } from "commander";
|
||||
import * as inquirer from "inquirer";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
@ -27,14 +27,14 @@ export class SendReceiveCommand extends DownloadCommand {
|
||||
private sendAccessRequest: SendAccessRequest;
|
||||
|
||||
constructor(
|
||||
private apiService: ApiService,
|
||||
cryptoService: CryptoService,
|
||||
private cryptoService: CryptoService,
|
||||
encryptService: EncryptService,
|
||||
private cryptoFunctionService: CryptoFunctionService,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private environmentService: EnvironmentService,
|
||||
private sendApiService: SendApiService,
|
||||
) {
|
||||
super(cryptoService);
|
||||
super(encryptService);
|
||||
}
|
||||
|
||||
async run(url: string, options: OptionValues): Promise<Response> {
|
||||
|
@ -100,8 +100,8 @@ export class SendProgram extends BaseProgram {
|
||||
})
|
||||
.action(async (url: string, options: OptionValues) => {
|
||||
const cmd = new SendReceiveCommand(
|
||||
this.serviceContainer.apiService,
|
||||
this.serviceContainer.cryptoService,
|
||||
this.serviceContainer.encryptService,
|
||||
this.serviceContainer.cryptoFunctionService,
|
||||
this.serviceContainer.platformUtilsService,
|
||||
this.serviceContainer.environmentService,
|
||||
@ -143,6 +143,7 @@ export class SendProgram extends BaseProgram {
|
||||
this.serviceContainer.totpService,
|
||||
this.serviceContainer.auditService,
|
||||
this.serviceContainer.cryptoService,
|
||||
this.serviceContainer.encryptService,
|
||||
this.serviceContainer.stateService,
|
||||
this.serviceContainer.searchService,
|
||||
this.serviceContainer.apiService,
|
||||
@ -187,7 +188,7 @@ export class SendProgram extends BaseProgram {
|
||||
this.serviceContainer.sendService,
|
||||
this.serviceContainer.environmentService,
|
||||
this.serviceContainer.searchService,
|
||||
this.serviceContainer.cryptoService,
|
||||
this.serviceContainer.encryptService,
|
||||
);
|
||||
const response = await cmd.run(id, options);
|
||||
this.processResponse(response);
|
||||
@ -246,7 +247,7 @@ export class SendProgram extends BaseProgram {
|
||||
this.serviceContainer.sendService,
|
||||
this.serviceContainer.environmentService,
|
||||
this.serviceContainer.searchService,
|
||||
this.serviceContainer.cryptoService,
|
||||
this.serviceContainer.encryptService,
|
||||
);
|
||||
const cmd = new SendEditCommand(
|
||||
this.serviceContainer.sendService,
|
||||
|
@ -178,6 +178,7 @@ export class VaultProgram extends BaseProgram {
|
||||
this.serviceContainer.totpService,
|
||||
this.serviceContainer.auditService,
|
||||
this.serviceContainer.cryptoService,
|
||||
this.serviceContainer.encryptService,
|
||||
this.serviceContainer.stateService,
|
||||
this.serviceContainer.searchService,
|
||||
this.serviceContainer.apiService,
|
||||
@ -224,6 +225,7 @@ export class VaultProgram extends BaseProgram {
|
||||
this.serviceContainer.cipherService,
|
||||
this.serviceContainer.folderService,
|
||||
this.serviceContainer.cryptoService,
|
||||
this.serviceContainer.encryptService,
|
||||
this.serviceContainer.apiService,
|
||||
this.serviceContainer.folderApiService,
|
||||
this.serviceContainer.billingAccountProfileStateService,
|
||||
@ -272,6 +274,7 @@ export class VaultProgram extends BaseProgram {
|
||||
this.serviceContainer.cipherService,
|
||||
this.serviceContainer.folderService,
|
||||
this.serviceContainer.cryptoService,
|
||||
this.serviceContainer.encryptService,
|
||||
this.serviceContainer.apiService,
|
||||
this.serviceContainer.folderApiService,
|
||||
this.serviceContainer.accountService,
|
||||
|
@ -12,6 +12,7 @@ import { CipherExport } from "@bitwarden/common/models/export/cipher.export";
|
||||
import { CollectionExport } from "@bitwarden/common/models/export/collection.export";
|
||||
import { FolderExport } from "@bitwarden/common/models/export/folder.export";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { FolderApiServiceAbstraction } from "@bitwarden/common/vault/abstractions/folder/folder-api.service.abstraction";
|
||||
@ -31,6 +32,7 @@ export class CreateCommand {
|
||||
private cipherService: CipherService,
|
||||
private folderService: FolderService,
|
||||
private cryptoService: CryptoService,
|
||||
private encryptService: EncryptService,
|
||||
private apiService: ApiService,
|
||||
private folderApiService: FolderApiServiceAbstraction,
|
||||
private accountProfileService: BillingAccountProfileStateService,
|
||||
@ -167,7 +169,9 @@ export class CreateCommand {
|
||||
}
|
||||
|
||||
private async createFolder(req: FolderExport) {
|
||||
const folder = await this.folderService.encrypt(FolderExport.toView(req));
|
||||
const activeAccountId = await firstValueFrom(this.accountService.activeAccount$);
|
||||
const userKey = await this.cryptoService.getUserKeyWithLegacySupport(activeAccountId.id);
|
||||
const folder = await this.folderService.encrypt(FolderExport.toView(req), userKey);
|
||||
try {
|
||||
await this.folderApiService.save(folder);
|
||||
const newFolder = await this.folderService.get(folder.id);
|
||||
@ -210,7 +214,7 @@ export class CreateCommand {
|
||||
(u) => new SelectionReadOnlyRequest(u.id, u.readOnly, u.hidePasswords, u.manage),
|
||||
);
|
||||
const request = new CollectionRequest();
|
||||
request.name = (await this.cryptoService.encrypt(req.name, orgKey)).encryptedString;
|
||||
request.name = (await this.encryptService.encrypt(req.name, orgKey)).encryptedString;
|
||||
request.externalId = req.externalId;
|
||||
request.groups = groups;
|
||||
request.users = users;
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@bitwarden/desktop",
|
||||
"description": "A secure and free password manager for all of your devices.",
|
||||
"version": "2024.9.1",
|
||||
"version": "2024.9.2",
|
||||
"keywords": [
|
||||
"bitwarden",
|
||||
"password",
|
||||
|
@ -234,7 +234,7 @@ const safeProviders: SafeProvider[] = [
|
||||
provide: NativeMessageHandlerService,
|
||||
deps: [
|
||||
StateServiceAbstraction,
|
||||
CryptoServiceAbstraction,
|
||||
EncryptService,
|
||||
CryptoFunctionServiceAbstraction,
|
||||
MessagingServiceAbstraction,
|
||||
EncryptedMessageHandlerService,
|
||||
|
4
apps/desktop/src/package-lock.json
generated
4
apps/desktop/src/package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@bitwarden/desktop",
|
||||
"version": "2024.9.1",
|
||||
"version": "2024.9.2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@bitwarden/desktop",
|
||||
"version": "2024.9.1",
|
||||
"version": "2024.9.2",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@bitwarden/desktop-napi": "file:../desktop_native/napi",
|
||||
|
@ -2,7 +2,7 @@
|
||||
"name": "@bitwarden/desktop",
|
||||
"productName": "Bitwarden",
|
||||
"description": "A secure and free password manager for all of your devices.",
|
||||
"version": "2024.9.1",
|
||||
"version": "2024.9.2",
|
||||
"author": "Bitwarden Inc. <hello@bitwarden.com> (https://bitwarden.com)",
|
||||
"homepage": "https://bitwarden.com",
|
||||
"license": "GPL-3.0",
|
||||
|
@ -3,7 +3,7 @@ import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { NativeMessagingVersion } from "@bitwarden/common/enums";
|
||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
@ -31,7 +31,7 @@ export class NativeMessageHandlerService {
|
||||
|
||||
constructor(
|
||||
private stateService: StateService,
|
||||
private cryptoService: CryptoService,
|
||||
private encryptService: EncryptService,
|
||||
private cryptoFunctionService: CryptoFunctionService,
|
||||
private messagingService: MessagingService,
|
||||
private encryptedMessageHandlerService: EncryptedMessageHandlerService,
|
||||
@ -162,7 +162,7 @@ export class NativeMessageHandlerService {
|
||||
payload: DecryptedCommandData,
|
||||
key: SymmetricCryptoKey,
|
||||
): Promise<EncString> {
|
||||
return await this.cryptoService.encrypt(JSON.stringify(payload), key);
|
||||
return await this.encryptService.encrypt(JSON.stringify(payload), key);
|
||||
}
|
||||
|
||||
private async decryptPayload(message: EncryptedMessage): Promise<DecryptedCommandData> {
|
||||
@ -182,7 +182,7 @@ export class NativeMessageHandlerService {
|
||||
}
|
||||
|
||||
try {
|
||||
let decryptedResult = await this.cryptoService.decryptToUtf8(
|
||||
let decryptedResult = await this.encryptService.decryptToUtf8(
|
||||
message.encryptedCommand as EncString,
|
||||
this.ddgSharedSecret,
|
||||
);
|
||||
|
@ -6,6 +6,7 @@ import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service";
|
||||
@ -33,6 +34,7 @@ export class NativeMessagingService {
|
||||
constructor(
|
||||
private cryptoFunctionService: CryptoFunctionService,
|
||||
private cryptoService: CryptoService,
|
||||
private encryptService: EncryptService,
|
||||
private logService: LogService,
|
||||
private messagingService: MessagingService,
|
||||
private desktopSettingService: DesktopSettingsService,
|
||||
@ -111,7 +113,7 @@ export class NativeMessagingService {
|
||||
}
|
||||
|
||||
const message: LegacyMessage = JSON.parse(
|
||||
await this.cryptoService.decryptToUtf8(
|
||||
await this.encryptService.decryptToUtf8(
|
||||
rawMessage as EncString,
|
||||
SymmetricCryptoKey.fromString(await ipc.platform.ephemeralStore.getEphemeralValue(appId)),
|
||||
),
|
||||
@ -224,7 +226,7 @@ export class NativeMessagingService {
|
||||
private async send(message: any, appId: string) {
|
||||
message.timestamp = Date.now();
|
||||
|
||||
const encrypted = await this.cryptoService.encrypt(
|
||||
const encrypted = await this.encryptService.encrypt(
|
||||
JSON.stringify(message),
|
||||
SymmetricCryptoKey.fromString(await ipc.platform.ephemeralStore.getEphemeralValue(appId)),
|
||||
);
|
||||
|
@ -5,6 +5,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
@ -22,6 +23,7 @@ export class AttachmentsComponent extends BaseAttachmentsComponent {
|
||||
cipherService: CipherService,
|
||||
i18nService: I18nService,
|
||||
cryptoService: CryptoService,
|
||||
encryptService: EncryptService,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
apiService: ApiService,
|
||||
logService: LogService,
|
||||
@ -36,6 +38,7 @@ export class AttachmentsComponent extends BaseAttachmentsComponent {
|
||||
cipherService,
|
||||
i18nService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
platformUtilsService,
|
||||
apiService,
|
||||
window,
|
||||
|
@ -2,6 +2,8 @@ import { Component } from "@angular/core";
|
||||
import { FormBuilder } from "@angular/forms";
|
||||
|
||||
import { FolderAddEditComponent as BaseFolderAddEditComponent } from "@bitwarden/angular/vault/components/folder-add-edit.component";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@ -17,6 +19,8 @@ export class FolderAddEditComponent extends BaseFolderAddEditComponent {
|
||||
constructor(
|
||||
folderService: FolderService,
|
||||
folderApiService: FolderApiServiceAbstraction,
|
||||
accountService: AccountService,
|
||||
cryptoService: CryptoService,
|
||||
i18nService: I18nService,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
logService: LogService,
|
||||
@ -26,6 +30,8 @@ export class FolderAddEditComponent extends BaseFolderAddEditComponent {
|
||||
super(
|
||||
folderService,
|
||||
folderApiService,
|
||||
accountService,
|
||||
cryptoService,
|
||||
i18nService,
|
||||
platformUtilsService,
|
||||
logService,
|
||||
|
@ -19,6 +19,7 @@ import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
@ -48,6 +49,7 @@ export class ViewComponent extends BaseViewComponent implements OnInit, OnDestro
|
||||
tokenService: TokenService,
|
||||
i18nService: I18nService,
|
||||
cryptoService: CryptoService,
|
||||
encryptService: EncryptService,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
auditService: AuditService,
|
||||
broadcasterService: BroadcasterService,
|
||||
@ -72,6 +74,7 @@ export class ViewComponent extends BaseViewComponent implements OnInit, OnDestro
|
||||
tokenService,
|
||||
i18nService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
platformUtilsService,
|
||||
auditService,
|
||||
window,
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@bitwarden/web-vault",
|
||||
"version": "2024.9.1",
|
||||
"version": "2024.9.2",
|
||||
"scripts": {
|
||||
"build:oss": "webpack",
|
||||
"build:bit": "webpack -c ../../bitwarden_license/bit-web/webpack.config.js",
|
||||
|
@ -5,6 +5,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
@ -26,6 +27,7 @@ export class EmergencyAccessAttachmentsComponent extends BaseAttachmentsComponen
|
||||
cipherService: CipherService,
|
||||
i18nService: I18nService,
|
||||
cryptoService: CryptoService,
|
||||
encryptService: EncryptService,
|
||||
stateService: StateService,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
apiService: ApiService,
|
||||
@ -40,6 +42,7 @@ export class EmergencyAccessAttachmentsComponent extends BaseAttachmentsComponen
|
||||
cipherService,
|
||||
i18nService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
platformUtilsService,
|
||||
apiService,
|
||||
window,
|
||||
|
@ -31,6 +31,7 @@ import { PlanResponse } from "@bitwarden/common/billing/models/response/plan.res
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
@ -147,6 +148,7 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy {
|
||||
private i18nService: I18nService,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private cryptoService: CryptoService,
|
||||
private encryptService: EncryptService,
|
||||
private router: Router,
|
||||
private syncService: SyncService,
|
||||
private policyService: PolicyService,
|
||||
@ -590,7 +592,7 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy {
|
||||
if (this.createOrganization) {
|
||||
const orgKey = await this.cryptoService.makeOrgKey<OrgKey>();
|
||||
const key = orgKey[0].encryptedString;
|
||||
const collection = await this.cryptoService.encrypt(
|
||||
const collection = await this.encryptService.encrypt(
|
||||
this.i18nService.t("defaultCollection"),
|
||||
orgKey[1],
|
||||
);
|
||||
@ -744,7 +746,7 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy {
|
||||
);
|
||||
const providerKey = await this.cryptoService.getProviderKey(this.providerId);
|
||||
providerRequest.organizationCreateRequest.key = (
|
||||
await this.cryptoService.encrypt(orgKey.key, providerKey)
|
||||
await this.encryptService.encrypt(orgKey.key, providerKey)
|
||||
).encryptedString;
|
||||
const orgId = (
|
||||
await this.apiService.postProviderCreateOrganization(this.providerId, providerRequest)
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Component, Input } from "@angular/core";
|
||||
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
@ -26,7 +26,7 @@ export class SendAccessFileComponent {
|
||||
constructor(
|
||||
private i18nService: I18nService,
|
||||
private toastService: ToastService,
|
||||
private cryptoService: CryptoService,
|
||||
private encryptService: EncryptService,
|
||||
private fileDownloadService: FileDownloadService,
|
||||
private sendApiService: SendApiService,
|
||||
) {}
|
||||
@ -62,7 +62,7 @@ export class SendAccessFileComponent {
|
||||
|
||||
try {
|
||||
const encBuf = await EncArrayBuffer.fromResponse(response);
|
||||
const decBuf = await this.cryptoService.decryptFromBytes(encBuf, this.decKey);
|
||||
const decBuf = await this.encryptService.decryptToBytes(encBuf, this.decKey);
|
||||
this.fileDownloadService.download({
|
||||
fileName: this.send.file.fileName,
|
||||
blobData: decBuf,
|
||||
|
@ -3,6 +3,7 @@ import { Injectable } from "@angular/core";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { SelectionReadOnlyRequest } from "@bitwarden/common/admin-console/models/request/selection-read-only.request";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||
import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service";
|
||||
import { CollectionData } from "@bitwarden/common/vault/models/data/collection.data";
|
||||
@ -23,6 +24,7 @@ export class CollectionAdminService {
|
||||
constructor(
|
||||
private apiService: ApiService,
|
||||
private cryptoService: CryptoService,
|
||||
private encryptService: EncryptService,
|
||||
private collectionService: CollectionService,
|
||||
) {}
|
||||
|
||||
@ -116,7 +118,7 @@ export class CollectionAdminService {
|
||||
const promises = collections.map(async (c) => {
|
||||
const view = new CollectionAdminView();
|
||||
view.id = c.id;
|
||||
view.name = await this.cryptoService.decryptToUtf8(new EncString(c.name), orgKey);
|
||||
view.name = await this.encryptService.decryptToUtf8(new EncString(c.name), orgKey);
|
||||
view.externalId = c.externalId;
|
||||
view.organizationId = c.organizationId;
|
||||
|
||||
@ -146,7 +148,7 @@ export class CollectionAdminService {
|
||||
}
|
||||
const collection = new CollectionRequest();
|
||||
collection.externalId = model.externalId;
|
||||
collection.name = (await this.cryptoService.encrypt(model.name, key)).encryptedString;
|
||||
collection.name = (await this.encryptService.encrypt(model.name, key)).encryptedString;
|
||||
collection.groups = model.groups.map(
|
||||
(group) =>
|
||||
new SelectionReadOnlyRequest(group.id, group.readOnly, group.hidePasswords, group.manage),
|
||||
|
@ -5,6 +5,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
@ -25,6 +26,7 @@ export class AttachmentsComponent extends BaseAttachmentsComponent {
|
||||
cipherService: CipherService,
|
||||
i18nService: I18nService,
|
||||
cryptoService: CryptoService,
|
||||
encryptService: EncryptService,
|
||||
stateService: StateService,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
apiService: ApiService,
|
||||
@ -39,6 +41,7 @@ export class AttachmentsComponent extends BaseAttachmentsComponent {
|
||||
cipherService,
|
||||
i18nService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
platformUtilsService,
|
||||
apiService,
|
||||
window,
|
||||
|
@ -1,8 +1,11 @@
|
||||
import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog";
|
||||
import { Component, Inject } from "@angular/core";
|
||||
import { FormBuilder } from "@angular/forms";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { FolderAddEditComponent as BaseFolderAddEditComponent } from "@bitwarden/angular/vault/components/folder-add-edit.component";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@ -19,6 +22,8 @@ export class FolderAddEditComponent extends BaseFolderAddEditComponent {
|
||||
constructor(
|
||||
folderService: FolderService,
|
||||
folderApiService: FolderApiServiceAbstraction,
|
||||
protected accountSerivce: AccountService,
|
||||
protected cryptoService: CryptoService,
|
||||
i18nService: I18nService,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
logService: LogService,
|
||||
@ -31,6 +36,8 @@ export class FolderAddEditComponent extends BaseFolderAddEditComponent {
|
||||
super(
|
||||
folderService,
|
||||
folderApiService,
|
||||
accountSerivce,
|
||||
cryptoService,
|
||||
i18nService,
|
||||
platformUtilsService,
|
||||
logService,
|
||||
@ -73,7 +80,9 @@ export class FolderAddEditComponent extends BaseFolderAddEditComponent {
|
||||
}
|
||||
|
||||
try {
|
||||
const folder = await this.folderService.encrypt(this.folder);
|
||||
const activeAccountId = (await firstValueFrom(this.accountSerivce.activeAccount$)).id;
|
||||
const userKey = await this.cryptoService.getUserKeyWithLegacySupport(activeAccountId);
|
||||
const folder = await this.folderService.encrypt(this.folder, userKey);
|
||||
this.formPromise = this.folderApiService.save(folder);
|
||||
await this.formPromise;
|
||||
this.platformUtilsService.showToast(
|
||||
|
@ -5,6 +5,7 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
@ -31,6 +32,7 @@ export class AttachmentsComponent extends BaseAttachmentsComponent implements On
|
||||
cipherService: CipherService,
|
||||
i18nService: I18nService,
|
||||
cryptoService: CryptoService,
|
||||
encryptService: EncryptService,
|
||||
stateService: StateService,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
apiService: ApiService,
|
||||
@ -45,6 +47,7 @@ export class AttachmentsComponent extends BaseAttachmentsComponent implements On
|
||||
cipherService,
|
||||
i18nService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
stateService,
|
||||
platformUtilsService,
|
||||
apiService,
|
||||
|
@ -11,7 +11,6 @@ import { ActivatedRoute, Params, Router } from "@angular/router";
|
||||
import {
|
||||
BehaviorSubject,
|
||||
combineLatest,
|
||||
defer,
|
||||
firstValueFrom,
|
||||
lastValueFrom,
|
||||
Observable,
|
||||
@ -283,27 +282,10 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
|
||||
this.currentSearchText$ = this.route.queryParams.pipe(map((queryParams) => queryParams.search));
|
||||
|
||||
this.allCollectionsWithoutUnassigned$ = combineLatest([
|
||||
organizationId$.pipe(switchMap((orgId) => this.collectionAdminService.getAll(orgId))),
|
||||
defer(() => this.collectionService.getAllDecrypted()),
|
||||
]).pipe(
|
||||
map(([adminCollections, syncCollections]) => {
|
||||
const syncCollectionDict = Object.fromEntries(syncCollections.map((c) => [c.id, c]));
|
||||
|
||||
return adminCollections.map((collection) => {
|
||||
const currentId: any = collection.id;
|
||||
|
||||
const match = syncCollectionDict[currentId];
|
||||
|
||||
if (match) {
|
||||
collection.manage = match.manage;
|
||||
collection.readOnly = match.readOnly;
|
||||
collection.hidePasswords = match.hidePasswords;
|
||||
}
|
||||
return collection;
|
||||
});
|
||||
}),
|
||||
shareReplay({ refCount: true, bufferSize: 1 }),
|
||||
this.allCollectionsWithoutUnassigned$ = this.refresh$.pipe(
|
||||
switchMap(() => organizationId$),
|
||||
switchMap((orgId) => this.collectionAdminService.getAll(orgId)),
|
||||
shareReplay({ refCount: false, bufferSize: 1 }),
|
||||
);
|
||||
|
||||
this.editableCollections$ = this.allCollectionsWithoutUnassigned$.pipe(
|
||||
@ -367,7 +349,6 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
map((ciphers) => {
|
||||
return Object.fromEntries(ciphers.map((c) => [c.id, c]));
|
||||
}),
|
||||
shareReplay({ refCount: true, bufferSize: 1 }),
|
||||
);
|
||||
|
||||
const nestedCollections$ = allCollections$.pipe(
|
||||
|
@ -18,6 +18,7 @@ export class ServiceContainer extends OssServiceContainer {
|
||||
this.organizationAuthRequestService = new OrganizationAuthRequestService(
|
||||
this.organizationAuthRequestApiService,
|
||||
this.cryptoService,
|
||||
this.encryptService,
|
||||
this.organizationUserApiService,
|
||||
);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
} from "@bitwarden/admin-console/common";
|
||||
import { ListResponse } from "@bitwarden/common/models/response/list.response";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||
|
||||
import { OrganizationAuthRequestApiService } from "./organization-auth-request-api.service";
|
||||
@ -16,16 +17,19 @@ import { PendingAuthRequestView } from "./pending-auth-request.view";
|
||||
describe("OrganizationAuthRequestService", () => {
|
||||
let organizationAuthRequestApiService: MockProxy<OrganizationAuthRequestApiService>;
|
||||
let cryptoService: MockProxy<CryptoService>;
|
||||
let encryptService: MockProxy<EncryptService>;
|
||||
let organizationUserApiService: MockProxy<OrganizationUserApiService>;
|
||||
let organizationAuthRequestService: OrganizationAuthRequestService;
|
||||
|
||||
beforeEach(() => {
|
||||
organizationAuthRequestApiService = mock<OrganizationAuthRequestApiService>();
|
||||
cryptoService = mock<CryptoService>();
|
||||
encryptService = mock<EncryptService>();
|
||||
organizationUserApiService = mock<OrganizationUserApiService>();
|
||||
organizationAuthRequestService = new OrganizationAuthRequestService(
|
||||
organizationAuthRequestApiService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
organizationUserApiService,
|
||||
);
|
||||
});
|
||||
|
@ -3,6 +3,7 @@ import {
|
||||
OrganizationUserResetPasswordDetailsResponse,
|
||||
} from "@bitwarden/admin-console/common";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||
@ -15,6 +16,7 @@ export class OrganizationAuthRequestService {
|
||||
constructor(
|
||||
private organizationAuthRequestApiService: OrganizationAuthRequestApiService,
|
||||
private cryptoService: CryptoService,
|
||||
private encryptService: EncryptService,
|
||||
private organizationUserApiService: OrganizationUserApiService,
|
||||
) {}
|
||||
|
||||
@ -109,7 +111,7 @@ export class OrganizationAuthRequestService {
|
||||
|
||||
// Decrypt Organization's encrypted Private Key with org key
|
||||
const orgSymKey = await this.cryptoService.getOrgKey(organizationId);
|
||||
const decOrgPrivateKey = await this.cryptoService.decryptToBytes(
|
||||
const decOrgPrivateKey = await this.encryptService.decryptToBytes(
|
||||
new EncString(encryptedOrgPrivateKey),
|
||||
orgSymKey,
|
||||
);
|
||||
|
@ -10,6 +10,7 @@ import { PendingAuthRequestView } from "@bitwarden/bit-common/admin-console/auth
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@ -30,7 +31,12 @@ import { SharedModule } from "@bitwarden/web-vault/app/shared/shared.module";
|
||||
}),
|
||||
safeProvider({
|
||||
provide: OrganizationAuthRequestService,
|
||||
deps: [OrganizationAuthRequestApiService, CryptoService, OrganizationUserApiService],
|
||||
deps: [
|
||||
OrganizationAuthRequestApiService,
|
||||
CryptoService,
|
||||
EncryptService,
|
||||
OrganizationUserApiService,
|
||||
],
|
||||
}),
|
||||
] satisfies SafeProvider[],
|
||||
imports: [SharedModule, NoItemsModule, LooseComponentsModule],
|
||||
|
@ -27,7 +27,7 @@ export class WebProviderService {
|
||||
const orgKey = await this.cryptoService.getOrgKey(organizationId);
|
||||
const providerKey = await this.cryptoService.getProviderKey(providerId);
|
||||
|
||||
const encryptedOrgKey = await this.cryptoService.encrypt(orgKey.key, providerKey);
|
||||
const encryptedOrgKey = await this.encryptService.encrypt(orgKey.key, providerKey);
|
||||
|
||||
const request = new ProviderAddOrganizationRequest();
|
||||
request.organizationId = organizationId;
|
||||
|
@ -449,6 +449,7 @@ const safeProviders: SafeProvider[] = [
|
||||
fileUploadService: CipherFileUploadServiceAbstraction,
|
||||
configService: ConfigService,
|
||||
stateProvider: StateProvider,
|
||||
accountService: AccountServiceAbstraction,
|
||||
) =>
|
||||
new CipherService(
|
||||
cryptoService,
|
||||
@ -463,6 +464,7 @@ const safeProviders: SafeProvider[] = [
|
||||
fileUploadService,
|
||||
configService,
|
||||
stateProvider,
|
||||
accountService,
|
||||
),
|
||||
deps: [
|
||||
CryptoServiceAbstraction,
|
||||
@ -477,6 +479,7 @@ const safeProviders: SafeProvider[] = [
|
||||
CipherFileUploadServiceAbstraction,
|
||||
ConfigService,
|
||||
StateProvider,
|
||||
AccountServiceAbstraction,
|
||||
],
|
||||
}),
|
||||
safeProvider({
|
||||
@ -484,6 +487,7 @@ const safeProviders: SafeProvider[] = [
|
||||
useClass: FolderService,
|
||||
deps: [
|
||||
CryptoServiceAbstraction,
|
||||
EncryptService,
|
||||
I18nServiceAbstraction,
|
||||
CipherServiceAbstraction,
|
||||
StateProvider,
|
||||
@ -527,7 +531,7 @@ const safeProviders: SafeProvider[] = [
|
||||
safeProvider({
|
||||
provide: CollectionServiceAbstraction,
|
||||
useClass: CollectionService,
|
||||
deps: [CryptoServiceAbstraction, I18nServiceAbstraction, StateProvider],
|
||||
deps: [CryptoServiceAbstraction, EncryptService, I18nServiceAbstraction, StateProvider],
|
||||
}),
|
||||
safeProvider({
|
||||
provide: EnvironmentService,
|
||||
@ -785,6 +789,7 @@ const safeProviders: SafeProvider[] = [
|
||||
I18nServiceAbstraction,
|
||||
CollectionServiceAbstraction,
|
||||
CryptoServiceAbstraction,
|
||||
EncryptService,
|
||||
PinServiceAbstraction,
|
||||
AccountServiceAbstraction,
|
||||
],
|
||||
@ -797,8 +802,10 @@ const safeProviders: SafeProvider[] = [
|
||||
CipherServiceAbstraction,
|
||||
PinServiceAbstraction,
|
||||
CryptoServiceAbstraction,
|
||||
EncryptService,
|
||||
CryptoFunctionServiceAbstraction,
|
||||
KdfConfigServiceAbstraction,
|
||||
AccountServiceAbstraction,
|
||||
],
|
||||
}),
|
||||
safeProvider({
|
||||
@ -809,6 +816,7 @@ const safeProviders: SafeProvider[] = [
|
||||
ApiServiceAbstraction,
|
||||
PinServiceAbstraction,
|
||||
CryptoServiceAbstraction,
|
||||
EncryptService,
|
||||
CryptoFunctionServiceAbstraction,
|
||||
CollectionServiceAbstraction,
|
||||
KdfConfigServiceAbstraction,
|
||||
|
@ -329,6 +329,11 @@ export class AddEditComponent implements OnInit, OnDestroy {
|
||||
this.cipher.card.expYear = normalizeExpiryYearFormat(this.cipher.card.expYear);
|
||||
}
|
||||
|
||||
// trim whitespace from the TOTP field
|
||||
if (this.cipher.type === this.cipherType.Login && this.cipher.login.totp) {
|
||||
this.cipher.login.totp = this.cipher.login.totp.trim();
|
||||
}
|
||||
|
||||
if (this.cipher.name == null || this.cipher.name === "") {
|
||||
this.platformUtilsService.showToast(
|
||||
"error",
|
||||
|
@ -6,6 +6,7 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
@ -40,6 +41,7 @@ export class AttachmentsComponent implements OnInit {
|
||||
protected cipherService: CipherService,
|
||||
protected i18nService: I18nService,
|
||||
protected cryptoService: CryptoService,
|
||||
protected encryptService: EncryptService,
|
||||
protected platformUtilsService: PlatformUtilsService,
|
||||
protected apiService: ApiService,
|
||||
protected win: Window,
|
||||
@ -178,7 +180,7 @@ export class AttachmentsComponent implements OnInit {
|
||||
attachment.key != null
|
||||
? attachment.key
|
||||
: await this.cryptoService.getOrgKey(this.cipher.organizationId);
|
||||
const decBuf = await this.cryptoService.decryptFromBytes(encBuf, key);
|
||||
const decBuf = await this.encryptService.decryptToBytes(encBuf, key);
|
||||
this.fileDownloadService.download({
|
||||
fileName: attachment.fileName,
|
||||
blobData: decBuf,
|
||||
@ -249,7 +251,7 @@ export class AttachmentsComponent implements OnInit {
|
||||
attachment.key != null
|
||||
? attachment.key
|
||||
: await this.cryptoService.getOrgKey(this.cipher.organizationId);
|
||||
const decBuf = await this.cryptoService.decryptFromBytes(encBuf, key);
|
||||
const decBuf = await this.encryptService.decryptToBytes(encBuf, key);
|
||||
const activeUserId = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
|
||||
);
|
||||
|
@ -1,6 +1,9 @@
|
||||
import { Directive, EventEmitter, Input, OnInit, Output } from "@angular/core";
|
||||
import { Validators, FormBuilder } from "@angular/forms";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@ -29,6 +32,8 @@ export class FolderAddEditComponent implements OnInit {
|
||||
constructor(
|
||||
protected folderService: FolderService,
|
||||
protected folderApiService: FolderApiServiceAbstraction,
|
||||
protected accountService: AccountService,
|
||||
protected cryptoService: CryptoService,
|
||||
protected i18nService: I18nService,
|
||||
protected platformUtilsService: PlatformUtilsService,
|
||||
protected logService: LogService,
|
||||
@ -52,7 +57,9 @@ export class FolderAddEditComponent implements OnInit {
|
||||
}
|
||||
|
||||
try {
|
||||
const folder = await this.folderService.encrypt(this.folder);
|
||||
const activeAccountId = await firstValueFrom(this.accountService.activeAccount$);
|
||||
const userKey = await this.cryptoService.getUserKeyWithLegacySupport(activeAccountId.id);
|
||||
const folder = await this.folderService.encrypt(this.folder, userKey);
|
||||
this.formPromise = this.folderApiService.save(folder);
|
||||
await this.formPromise;
|
||||
this.platformUtilsService.showToast(
|
||||
|
@ -21,6 +21,7 @@ import { EventType } from "@bitwarden/common/enums";
|
||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
@ -87,6 +88,7 @@ export class ViewComponent implements OnDestroy, OnInit {
|
||||
protected tokenService: TokenService,
|
||||
protected i18nService: I18nService,
|
||||
protected cryptoService: CryptoService,
|
||||
protected encryptService: EncryptService,
|
||||
protected platformUtilsService: PlatformUtilsService,
|
||||
protected auditService: AuditService,
|
||||
protected win: Window,
|
||||
@ -442,7 +444,7 @@ export class ViewComponent implements OnDestroy, OnInit {
|
||||
attachment.key != null
|
||||
? attachment.key
|
||||
: await this.cryptoService.getOrgKey(this.cipher.organizationId);
|
||||
const decBuf = await this.cryptoService.decryptFromBytes(encBuf, key);
|
||||
const decBuf = await this.encryptService.decryptToBytes(encBuf, key);
|
||||
this.fileDownloadService.download({
|
||||
fileName: attachment.fileName,
|
||||
blobData: decBuf,
|
||||
|
@ -12,6 +12,7 @@ import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abs
|
||||
import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum";
|
||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@ -37,6 +38,7 @@ describe("AuthRequestLoginStrategy", () => {
|
||||
let cache: AuthRequestLoginStrategyData;
|
||||
|
||||
let cryptoService: MockProxy<CryptoService>;
|
||||
let encryptService: MockProxy<EncryptService>;
|
||||
let apiService: MockProxy<ApiService>;
|
||||
let tokenService: MockProxy<TokenService>;
|
||||
let appIdService: MockProxy<AppIdService>;
|
||||
@ -101,6 +103,7 @@ describe("AuthRequestLoginStrategy", () => {
|
||||
accountService,
|
||||
masterPasswordService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
apiService,
|
||||
tokenService,
|
||||
appIdService,
|
||||
|
@ -22,6 +22,7 @@ import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abs
|
||||
import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum";
|
||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@ -104,6 +105,7 @@ describe("LoginStrategy", () => {
|
||||
|
||||
let loginStrategyService: MockProxy<LoginStrategyServiceAbstraction>;
|
||||
let cryptoService: MockProxy<CryptoService>;
|
||||
let encryptService: MockProxy<EncryptService>;
|
||||
let apiService: MockProxy<ApiService>;
|
||||
let tokenService: MockProxy<TokenService>;
|
||||
let appIdService: MockProxy<AppIdService>;
|
||||
@ -128,6 +130,7 @@ describe("LoginStrategy", () => {
|
||||
|
||||
loginStrategyService = mock<LoginStrategyServiceAbstraction>();
|
||||
cryptoService = mock<CryptoService>();
|
||||
encryptService = mock<EncryptService>();
|
||||
apiService = mock<ApiService>();
|
||||
tokenService = mock<TokenService>();
|
||||
appIdService = mock<AppIdService>();
|
||||
@ -156,6 +159,7 @@ describe("LoginStrategy", () => {
|
||||
accountService,
|
||||
masterPasswordService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
apiService,
|
||||
tokenService,
|
||||
appIdService,
|
||||
@ -467,6 +471,7 @@ describe("LoginStrategy", () => {
|
||||
accountService,
|
||||
masterPasswordService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
apiService,
|
||||
tokenService,
|
||||
appIdService,
|
||||
|
@ -26,6 +26,7 @@ import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action
|
||||
import { KeysRequest } from "@bitwarden/common/models/request/keys.request";
|
||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@ -66,6 +67,7 @@ export abstract class LoginStrategy {
|
||||
protected accountService: AccountService,
|
||||
protected masterPasswordService: InternalMasterPasswordServiceAbstraction,
|
||||
protected cryptoService: CryptoService,
|
||||
protected encryptService: EncryptService,
|
||||
protected apiService: ApiService,
|
||||
protected tokenService: TokenService,
|
||||
protected appIdService: AppIdService,
|
||||
|
@ -16,6 +16,7 @@ import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abs
|
||||
import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum";
|
||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@ -63,6 +64,7 @@ describe("PasswordLoginStrategy", () => {
|
||||
|
||||
let loginStrategyService: MockProxy<LoginStrategyServiceAbstraction>;
|
||||
let cryptoService: MockProxy<CryptoService>;
|
||||
let encryptService: MockProxy<EncryptService>;
|
||||
let apiService: MockProxy<ApiService>;
|
||||
let tokenService: MockProxy<TokenService>;
|
||||
let appIdService: MockProxy<AppIdService>;
|
||||
@ -88,6 +90,7 @@ describe("PasswordLoginStrategy", () => {
|
||||
|
||||
loginStrategyService = mock<LoginStrategyServiceAbstraction>();
|
||||
cryptoService = mock<CryptoService>();
|
||||
encryptService = mock<EncryptService>();
|
||||
apiService = mock<ApiService>();
|
||||
tokenService = mock<TokenService>();
|
||||
appIdService = mock<AppIdService>();
|
||||
@ -127,6 +130,7 @@ describe("PasswordLoginStrategy", () => {
|
||||
accountService,
|
||||
masterPasswordService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
apiService,
|
||||
tokenService,
|
||||
appIdService,
|
||||
|
@ -17,6 +17,7 @@ import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action
|
||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
@ -44,6 +45,7 @@ describe("SsoLoginStrategy", () => {
|
||||
let masterPasswordService: FakeMasterPasswordService;
|
||||
|
||||
let cryptoService: MockProxy<CryptoService>;
|
||||
let encryptService: MockProxy<EncryptService>;
|
||||
let apiService: MockProxy<ApiService>;
|
||||
let tokenService: MockProxy<TokenService>;
|
||||
let appIdService: MockProxy<AppIdService>;
|
||||
@ -78,6 +80,7 @@ describe("SsoLoginStrategy", () => {
|
||||
masterPasswordService = new FakeMasterPasswordService();
|
||||
|
||||
cryptoService = mock<CryptoService>();
|
||||
encryptService = mock<EncryptService>();
|
||||
apiService = mock<ApiService>();
|
||||
tokenService = mock<TokenService>();
|
||||
appIdService = mock<AppIdService>();
|
||||
@ -125,6 +128,7 @@ describe("SsoLoginStrategy", () => {
|
||||
accountService,
|
||||
masterPasswordService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
apiService,
|
||||
tokenService,
|
||||
appIdService,
|
||||
|
@ -11,6 +11,7 @@ import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abs
|
||||
import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum";
|
||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import {
|
||||
Environment,
|
||||
EnvironmentService,
|
||||
@ -39,6 +40,7 @@ describe("UserApiLoginStrategy", () => {
|
||||
let masterPasswordService: FakeMasterPasswordService;
|
||||
|
||||
let cryptoService: MockProxy<CryptoService>;
|
||||
let encryptService: MockProxy<EncryptService>;
|
||||
let apiService: MockProxy<ApiService>;
|
||||
let tokenService: MockProxy<TokenService>;
|
||||
let appIdService: MockProxy<AppIdService>;
|
||||
@ -99,6 +101,7 @@ describe("UserApiLoginStrategy", () => {
|
||||
accountService,
|
||||
masterPasswordService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
apiService,
|
||||
tokenService,
|
||||
appIdService,
|
||||
|
@ -14,6 +14,7 @@ import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abs
|
||||
import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum";
|
||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@ -37,6 +38,7 @@ describe("WebAuthnLoginStrategy", () => {
|
||||
let masterPasswordService: FakeMasterPasswordService;
|
||||
|
||||
let cryptoService!: MockProxy<CryptoService>;
|
||||
let encryptService!: MockProxy<EncryptService>;
|
||||
let apiService!: MockProxy<ApiService>;
|
||||
let tokenService!: MockProxy<TokenService>;
|
||||
let appIdService!: MockProxy<AppIdService>;
|
||||
@ -79,6 +81,7 @@ describe("WebAuthnLoginStrategy", () => {
|
||||
masterPasswordService = new FakeMasterPasswordService();
|
||||
|
||||
cryptoService = mock<CryptoService>();
|
||||
encryptService = mock<EncryptService>();
|
||||
apiService = mock<ApiService>();
|
||||
tokenService = mock<TokenService>();
|
||||
appIdService = mock<AppIdService>();
|
||||
@ -103,6 +106,7 @@ describe("WebAuthnLoginStrategy", () => {
|
||||
accountService,
|
||||
masterPasswordService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
apiService,
|
||||
tokenService,
|
||||
appIdService,
|
||||
@ -221,7 +225,7 @@ describe("WebAuthnLoginStrategy", () => {
|
||||
const mockUserKeyArray: Uint8Array = randomBytes(32);
|
||||
const mockUserKey = new SymmetricCryptoKey(mockUserKeyArray) as UserKey;
|
||||
|
||||
cryptoService.decryptToBytes.mockResolvedValue(mockPrfPrivateKey);
|
||||
encryptService.decryptToBytes.mockResolvedValue(mockPrfPrivateKey);
|
||||
cryptoService.rsaDecrypt.mockResolvedValue(mockUserKeyArray);
|
||||
|
||||
// Act
|
||||
@ -235,8 +239,8 @@ describe("WebAuthnLoginStrategy", () => {
|
||||
userId,
|
||||
);
|
||||
|
||||
expect(cryptoService.decryptToBytes).toHaveBeenCalledTimes(1);
|
||||
expect(cryptoService.decryptToBytes).toHaveBeenCalledWith(
|
||||
expect(encryptService.decryptToBytes).toHaveBeenCalledTimes(1);
|
||||
expect(encryptService.decryptToBytes).toHaveBeenCalledWith(
|
||||
idTokenResponse.userDecryptionOptions.webAuthnPrfOption.encryptedPrivateKey,
|
||||
webAuthnCredentials.prfKey,
|
||||
);
|
||||
@ -268,7 +272,7 @@ describe("WebAuthnLoginStrategy", () => {
|
||||
await webAuthnLoginStrategy.logIn(webAuthnCredentials);
|
||||
|
||||
// Assert
|
||||
expect(cryptoService.decryptToBytes).not.toHaveBeenCalled();
|
||||
expect(encryptService.decryptToBytes).not.toHaveBeenCalled();
|
||||
expect(cryptoService.rsaDecrypt).not.toHaveBeenCalled();
|
||||
expect(cryptoService.setUserKey).not.toHaveBeenCalled();
|
||||
});
|
||||
@ -303,7 +307,7 @@ describe("WebAuthnLoginStrategy", () => {
|
||||
|
||||
apiService.postIdentityToken.mockResolvedValue(idTokenResponse);
|
||||
|
||||
cryptoService.decryptToBytes.mockResolvedValue(null);
|
||||
encryptService.decryptToBytes.mockResolvedValue(null);
|
||||
|
||||
// Act
|
||||
await webAuthnLoginStrategy.logIn(webAuthnCredentials);
|
||||
|
@ -80,7 +80,7 @@ export class WebAuthnLoginStrategy extends LoginStrategy {
|
||||
}
|
||||
|
||||
// decrypt prf encrypted private key
|
||||
const privateKey = await this.cryptoService.decryptToBytes(
|
||||
const privateKey = await this.encryptService.decryptToBytes(
|
||||
webAuthnPrfOption.encryptedPrivateKey,
|
||||
credentials.prfKey,
|
||||
);
|
||||
|
@ -317,6 +317,7 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
|
||||
this.accountService,
|
||||
this.masterPasswordService,
|
||||
this.cryptoService,
|
||||
this.encryptService,
|
||||
this.apiService,
|
||||
this.tokenService,
|
||||
this.appIdService,
|
||||
|
@ -15,7 +15,6 @@ import {
|
||||
UserPublicKey,
|
||||
} from "../../types/key";
|
||||
import { KeySuffixOptions, HashPurpose } from "../enums";
|
||||
import { EncArrayBuffer } from "../models/domain/enc-array-buffer";
|
||||
import { EncString } from "../models/domain/enc-string";
|
||||
import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key";
|
||||
|
||||
@ -373,37 +372,6 @@ export abstract class CryptoService {
|
||||
* @param userId The desired user
|
||||
*/
|
||||
abstract clearDeprecatedKeys(keySuffix: KeySuffixOptions, userId?: string): Promise<void>;
|
||||
/**
|
||||
* @deprecated July 25 2022: Get the key you need from CryptoService (getKeyForUserEncryption or getOrgKey)
|
||||
* and then call encryptService.encrypt
|
||||
*/
|
||||
abstract encrypt(plainValue: string | Uint8Array, key?: SymmetricCryptoKey): Promise<EncString>;
|
||||
/**
|
||||
* @deprecated July 25 2022: Get the key you need from CryptoService (getKeyForUserEncryption or getOrgKey)
|
||||
* and then call encryptService.encryptToBytes
|
||||
*/
|
||||
abstract encryptToBytes(
|
||||
plainValue: Uint8Array,
|
||||
key?: SymmetricCryptoKey,
|
||||
): Promise<EncArrayBuffer>;
|
||||
/**
|
||||
* @deprecated July 25 2022: Get the key you need from CryptoService (getKeyForUserEncryption or getOrgKey)
|
||||
* and then call encryptService.decryptToBytes
|
||||
*/
|
||||
abstract decryptToBytes(encString: EncString, key?: SymmetricCryptoKey): Promise<Uint8Array>;
|
||||
/**
|
||||
* @deprecated July 25 2022: Get the key you need from CryptoService (getKeyForUserEncryption or getOrgKey)
|
||||
* and then call encryptService.decryptToUtf8
|
||||
*/
|
||||
abstract decryptToUtf8(encString: EncString, key?: SymmetricCryptoKey): Promise<string>;
|
||||
/**
|
||||
* @deprecated July 25 2022: Get the key you need from CryptoService (getKeyForUserEncryption or getOrgKey)
|
||||
* and then call encryptService.decryptToBytes
|
||||
*/
|
||||
abstract decryptFromBytes(
|
||||
encBuffer: EncArrayBuffer,
|
||||
key: SymmetricCryptoKey,
|
||||
): Promise<Uint8Array>;
|
||||
|
||||
/**
|
||||
* Retrieves all the keys needed for decrypting Ciphers
|
||||
|
@ -48,7 +48,6 @@ import { StateService } from "../abstractions/state.service";
|
||||
import { KeySuffixOptions, HashPurpose, EncryptionType } from "../enums";
|
||||
import { convertValues } from "../misc/convert-values";
|
||||
import { EFFLongWordList } from "../misc/wordlist";
|
||||
import { EncArrayBuffer } from "../models/domain/enc-array-buffer";
|
||||
import { EncString, EncryptedString } from "../models/domain/enc-string";
|
||||
import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key";
|
||||
import { ActiveUserState, StateProvider } from "../state";
|
||||
@ -859,58 +858,6 @@ export class CryptoService implements CryptoServiceAbstraction {
|
||||
}
|
||||
}
|
||||
|
||||
// --DEPRECATED METHODS--
|
||||
|
||||
/**
|
||||
* @deprecated July 25 2022: Get the key you need from CryptoService (getKeyForUserEncryption or getOrgKey)
|
||||
* and then call encryptService.encrypt
|
||||
*/
|
||||
async encrypt(plainValue: string | Uint8Array, key?: SymmetricCryptoKey): Promise<EncString> {
|
||||
key ||= await this.getUserKeyWithLegacySupport();
|
||||
return await this.encryptService.encrypt(plainValue, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated July 25 2022: Get the key you need from CryptoService (getKeyForUserEncryption or getOrgKey)
|
||||
* and then call encryptService.encryptToBytes
|
||||
*/
|
||||
async encryptToBytes(plainValue: Uint8Array, key?: SymmetricCryptoKey): Promise<EncArrayBuffer> {
|
||||
key ||= await this.getUserKeyWithLegacySupport();
|
||||
return this.encryptService.encryptToBytes(plainValue, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated July 25 2022: Get the key you need from CryptoService (getKeyForUserEncryption or getOrgKey)
|
||||
* and then call encryptService.decryptToBytes
|
||||
*/
|
||||
async decryptToBytes(encString: EncString, key?: SymmetricCryptoKey): Promise<Uint8Array> {
|
||||
key ||= await this.getUserKeyWithLegacySupport();
|
||||
return this.encryptService.decryptToBytes(encString, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated July 25 2022: Get the key you need from CryptoService (getKeyForUserEncryption or getOrgKey)
|
||||
* and then call encryptService.decryptToUtf8
|
||||
*/
|
||||
async decryptToUtf8(encString: EncString, key?: SymmetricCryptoKey): Promise<string> {
|
||||
key ||= await this.getUserKeyWithLegacySupport();
|
||||
return await this.encryptService.decryptToUtf8(encString, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated July 25 2022: Get the key you need from CryptoService (getKeyForUserEncryption or getOrgKey)
|
||||
* and then call encryptService.decryptToBytes
|
||||
*/
|
||||
async decryptFromBytes(encBuffer: EncArrayBuffer, key: SymmetricCryptoKey): Promise<Uint8Array> {
|
||||
if (encBuffer == null) {
|
||||
throw new Error("No buffer provided for decryption.");
|
||||
}
|
||||
|
||||
key ||= await this.getUserKeyWithLegacySupport();
|
||||
|
||||
return this.encryptService.decryptToBytes(encBuffer, key);
|
||||
}
|
||||
|
||||
userKey$(userId: UserId): Observable<UserKey> {
|
||||
return this.stateProvider.getUser(userId, USER_KEY).state$;
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
import { mock } from "jest-mock-extended";
|
||||
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||
import { UserKey } from "@bitwarden/common/types/key";
|
||||
|
||||
import { makeStaticByteArray, mockEnc } from "../../../../../spec";
|
||||
import { CryptoService } from "../../../../platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "../../../../platform/abstractions/encrypt.service";
|
||||
@ -89,6 +92,7 @@ describe("Send", () => {
|
||||
it("Decrypt", async () => {
|
||||
const text = mock<SendText>();
|
||||
text.decrypt.mockResolvedValue("textView" as any);
|
||||
const userKey = new SymmetricCryptoKey(new Uint8Array(32)) as UserKey;
|
||||
|
||||
const send = new Send();
|
||||
send.id = "id";
|
||||
@ -106,13 +110,13 @@ describe("Send", () => {
|
||||
send.disabled = false;
|
||||
send.hideEmail = true;
|
||||
|
||||
const encryptService = mock<EncryptService>();
|
||||
const cryptoService = mock<CryptoService>();
|
||||
cryptoService.decryptToBytes
|
||||
.calledWith(send.key, null)
|
||||
encryptService.decryptToBytes
|
||||
.calledWith(send.key, userKey)
|
||||
.mockResolvedValue(makeStaticByteArray(32));
|
||||
cryptoService.makeSendKey.mockResolvedValue("cryptoKey" as any);
|
||||
|
||||
const encryptService = mock<EncryptService>();
|
||||
cryptoService.getUserKey.mockResolvedValue(userKey);
|
||||
|
||||
(window as any).bitwardenContainerService = new ContainerService(cryptoService, encryptService);
|
||||
|
||||
|
@ -73,9 +73,11 @@ export class Send extends Domain {
|
||||
const model = new SendView(this);
|
||||
|
||||
const cryptoService = Utils.getContainerService().getCryptoService();
|
||||
const encryptService = Utils.getContainerService().getEncryptService();
|
||||
|
||||
try {
|
||||
model.key = await cryptoService.decryptToBytes(this.key, null);
|
||||
const sendKeyEncryptionKey = await cryptoService.getUserKey();
|
||||
model.key = await encryptService.decryptToBytes(this.key, sendKeyEncryptionKey);
|
||||
model.cryptoKey = await cryptoService.makeSendKey(model.key);
|
||||
} catch (e) {
|
||||
// TODO: error?
|
||||
|
@ -15,7 +15,7 @@ export abstract class FolderService implements UserKeyRotationDataProvider<Folde
|
||||
folderViews$: Observable<FolderView[]>;
|
||||
|
||||
clearCache: () => Promise<void>;
|
||||
encrypt: (model: FolderView, key?: SymmetricCryptoKey) => Promise<Folder>;
|
||||
encrypt: (model: FolderView, key: SymmetricCryptoKey) => Promise<Folder>;
|
||||
get: (id: string) => Promise<Folder>;
|
||||
getDecrypted$: (id: string) => Observable<FolderView | undefined>;
|
||||
getAllFromState: () => Promise<Folder[]>;
|
||||
|
@ -145,6 +145,7 @@ describe("Cipher Service", () => {
|
||||
cipherFileUploadService,
|
||||
configService,
|
||||
stateProvider,
|
||||
accountService,
|
||||
);
|
||||
|
||||
cipherObj = new Cipher(cipherData);
|
||||
@ -273,7 +274,7 @@ describe("Cipher Service", () => {
|
||||
cryptoService.makeCipherKey.mockReturnValue(
|
||||
Promise.resolve(new SymmetricCryptoKey(makeStaticByteArray(64)) as CipherKey),
|
||||
);
|
||||
cryptoService.encrypt.mockImplementation(encryptText);
|
||||
encryptService.encrypt.mockImplementation(encryptText);
|
||||
|
||||
jest.spyOn(cipherService as any, "getAutofillOnPageLoadDefault").mockResolvedValue(true);
|
||||
});
|
||||
@ -285,6 +286,10 @@ describe("Cipher Service", () => {
|
||||
{ uri: "uri", match: UriMatchStrategy.RegularExpression } as LoginUriView,
|
||||
];
|
||||
|
||||
cryptoService.getOrgKey.mockReturnValue(
|
||||
Promise.resolve<any>(new SymmetricCryptoKey(new Uint8Array(32)) as OrgKey),
|
||||
);
|
||||
|
||||
const domain = await cipherService.encrypt(cipherView, userId);
|
||||
|
||||
expect(domain.login.uris).toEqual([
|
||||
@ -301,6 +306,9 @@ describe("Cipher Service", () => {
|
||||
it("is null when feature flag is false", async () => {
|
||||
configService.getFeatureFlag.mockResolvedValue(false);
|
||||
|
||||
cryptoService.getOrgKey.mockReturnValue(
|
||||
Promise.resolve<any>(new SymmetricCryptoKey(new Uint8Array(32)) as OrgKey),
|
||||
);
|
||||
const cipher = await cipherService.encrypt(cipherView, userId);
|
||||
|
||||
expect(cipher.key).toBeNull();
|
||||
@ -322,6 +330,9 @@ describe("Cipher Service", () => {
|
||||
|
||||
it("is not called when feature flag is false", async () => {
|
||||
configService.getFeatureFlag.mockResolvedValue(false);
|
||||
cryptoService.getOrgKey.mockReturnValue(
|
||||
Promise.resolve<any>(new SymmetricCryptoKey(new Uint8Array(32)) as OrgKey),
|
||||
);
|
||||
|
||||
await cipherService.encrypt(cipherView, userId);
|
||||
|
||||
@ -330,6 +341,9 @@ describe("Cipher Service", () => {
|
||||
|
||||
it("is called when feature flag is true", async () => {
|
||||
configService.getFeatureFlag.mockResolvedValue(true);
|
||||
cryptoService.getOrgKey.mockReturnValue(
|
||||
Promise.resolve<any>(new SymmetricCryptoKey(new Uint8Array(32)) as OrgKey),
|
||||
);
|
||||
|
||||
await cipherService.encrypt(cipherView, userId);
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { firstValueFrom, map, Observable, skipWhile, switchMap } from "rxjs";
|
||||
import { SemVer } from "semver";
|
||||
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { BulkEncryptService } from "@bitwarden/common/platform/abstractions/bulk-encrypt.service";
|
||||
|
||||
@ -108,6 +109,7 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
private cipherFileUploadService: CipherFileUploadService,
|
||||
private configService: ConfigService,
|
||||
private stateProvider: StateProvider,
|
||||
private accountService: AccountService,
|
||||
) {
|
||||
this.localDataState = this.stateProvider.getActive(LOCAL_DATA_KEY);
|
||||
this.encryptedCiphersState = this.stateProvider.getActive(ENCRYPTED_CIPHERS);
|
||||
@ -165,7 +167,7 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
async encrypt(
|
||||
model: CipherView,
|
||||
userId: UserId,
|
||||
keyForEncryption?: SymmetricCryptoKey,
|
||||
keyForCipherEncryption?: SymmetricCryptoKey,
|
||||
keyForCipherKeyDecryption?: SymmetricCryptoKey,
|
||||
originalCipher: Cipher = null,
|
||||
): Promise<Cipher> {
|
||||
@ -195,26 +197,21 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
const userOrOrgKey = await this.getKeyForCipherKeyDecryption(cipher, userId);
|
||||
// The keyForEncryption is only used for encrypting the cipher key, not the cipher itself, since cipher key encryption is enabled.
|
||||
// If the caller has provided a key for cipher key encryption, use it. Otherwise, use the user or org key.
|
||||
keyForEncryption ||= userOrOrgKey;
|
||||
keyForCipherEncryption ||= userOrOrgKey;
|
||||
// If the caller has provided a key for cipher key decryption, use it. Otherwise, use the user or org key.
|
||||
keyForCipherKeyDecryption ||= userOrOrgKey;
|
||||
return this.encryptCipherWithCipherKey(
|
||||
model,
|
||||
cipher,
|
||||
keyForEncryption,
|
||||
keyForCipherEncryption,
|
||||
keyForCipherKeyDecryption,
|
||||
);
|
||||
} else {
|
||||
if (keyForEncryption == null && cipher.organizationId != null) {
|
||||
keyForEncryption = await this.cryptoService.getOrgKey(cipher.organizationId);
|
||||
if (keyForEncryption == null) {
|
||||
throw new Error("Cannot encrypt cipher for organization. No key.");
|
||||
}
|
||||
}
|
||||
keyForCipherEncryption ||= await this.getKeyForCipherKeyDecryption(cipher, userId);
|
||||
// We want to ensure that the cipher key is null if cipher key encryption is disabled
|
||||
// so that decryption uses the proper key.
|
||||
cipher.key = null;
|
||||
return this.encryptCipher(model, cipher, keyForEncryption);
|
||||
return this.encryptCipher(model, cipher, keyForCipherEncryption);
|
||||
}
|
||||
}
|
||||
|
||||
@ -243,7 +240,7 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
key,
|
||||
).then(async () => {
|
||||
if (model.key != null) {
|
||||
attachment.key = await this.cryptoService.encrypt(model.key.key, key);
|
||||
attachment.key = await this.encryptService.encrypt(model.key.key, key);
|
||||
}
|
||||
encAttachments.push(attachment);
|
||||
});
|
||||
@ -1348,7 +1345,9 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
}
|
||||
|
||||
const encBuf = await EncArrayBuffer.fromResponse(attachmentResponse);
|
||||
const decBuf = await this.cryptoService.decryptFromBytes(encBuf, null);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$);
|
||||
const userKey = await this.cryptoService.getUserKeyWithLegacySupport(activeUserId.id);
|
||||
const decBuf = await this.encryptService.decryptToBytes(encBuf, userKey);
|
||||
|
||||
let encKey: UserKey | OrgKey;
|
||||
encKey = await this.cryptoService.getOrgKey(organizationId);
|
||||
@ -1412,7 +1411,7 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
.then(() => {
|
||||
const modelProp = (model as any)[map[theProp] || theProp];
|
||||
if (modelProp && modelProp !== "") {
|
||||
return self.cryptoService.encrypt(modelProp, key);
|
||||
return self.encryptService.encrypt(modelProp, key);
|
||||
}
|
||||
return null;
|
||||
})
|
||||
@ -1458,7 +1457,7 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
key,
|
||||
);
|
||||
const uriHash = await this.encryptService.hash(model.login.uris[i].uri, "sha256");
|
||||
loginUri.uriChecksum = await this.cryptoService.encrypt(uriHash, key);
|
||||
loginUri.uriChecksum = await this.encryptService.encrypt(uriHash, key);
|
||||
cipher.login.uris.push(loginUri);
|
||||
}
|
||||
}
|
||||
@ -1485,8 +1484,8 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
},
|
||||
key,
|
||||
);
|
||||
domainKey.counter = await this.cryptoService.encrypt(String(viewKey.counter), key);
|
||||
domainKey.discoverable = await this.cryptoService.encrypt(
|
||||
domainKey.counter = await this.encryptService.encrypt(String(viewKey.counter), key);
|
||||
domainKey.discoverable = await this.encryptService.encrypt(
|
||||
String(viewKey.discoverable),
|
||||
key,
|
||||
);
|
||||
@ -1605,11 +1604,23 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
this.sortedCiphersCache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a cipher object.
|
||||
* @param model The cipher view model.
|
||||
* @param cipher The cipher object.
|
||||
* @param key The encryption key to encrypt with. This can be the org key, user key or cipher key, but must never be null
|
||||
*/
|
||||
private async encryptCipher(
|
||||
model: CipherView,
|
||||
cipher: Cipher,
|
||||
key: SymmetricCryptoKey,
|
||||
): Promise<Cipher> {
|
||||
if (key == null) {
|
||||
throw new Error(
|
||||
"Key to encrypt cipher must not be null. Use the org key, user key or cipher key.",
|
||||
);
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
this.encryptObjProperty(
|
||||
model,
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { firstValueFrom, map, Observable } from "rxjs";
|
||||
import { Jsonify } from "type-fest";
|
||||
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
|
||||
import { CryptoService } from "../../platform/abstractions/crypto.service";
|
||||
import { I18nService } from "../../platform/abstractions/i18n.service";
|
||||
import { Utils } from "../../platform/misc/utils";
|
||||
@ -61,6 +63,7 @@ export class CollectionService implements CollectionServiceAbstraction {
|
||||
|
||||
constructor(
|
||||
private cryptoService: CryptoService,
|
||||
private encryptService: EncryptService,
|
||||
private i18nService: I18nService,
|
||||
protected stateProvider: StateProvider,
|
||||
) {
|
||||
@ -101,7 +104,7 @@ export class CollectionService implements CollectionServiceAbstraction {
|
||||
collection.organizationId = model.organizationId;
|
||||
collection.readOnly = model.readOnly;
|
||||
collection.externalId = model.externalId;
|
||||
collection.name = await this.cryptoService.encrypt(model.name, key);
|
||||
collection.name = await this.encryptService.encrypt(model.name, key);
|
||||
return collection;
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,13 @@ describe("Folder Service", () => {
|
||||
);
|
||||
encryptService.decryptToUtf8.mockResolvedValue("DEC");
|
||||
|
||||
folderService = new FolderService(cryptoService, i18nService, cipherService, stateProvider);
|
||||
folderService = new FolderService(
|
||||
cryptoService,
|
||||
encryptService,
|
||||
i18nService,
|
||||
cipherService,
|
||||
stateProvider,
|
||||
);
|
||||
|
||||
folderState = stateProvider.activeUser.getFake(FOLDER_ENCRYPTED_FOLDERS);
|
||||
|
||||
@ -62,9 +68,9 @@ describe("Folder Service", () => {
|
||||
model.id = "2";
|
||||
model.name = "Test Folder";
|
||||
|
||||
cryptoService.encrypt.mockResolvedValue(new EncString("ENC"));
|
||||
encryptService.encrypt.mockResolvedValue(new EncString("ENC"));
|
||||
|
||||
const result = await folderService.encrypt(model);
|
||||
const result = await folderService.encrypt(model, null);
|
||||
|
||||
expect(result).toEqual({
|
||||
id: "2",
|
||||
@ -185,7 +191,7 @@ describe("Folder Service", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
encryptedKey = new EncString("Re-encrypted Folder");
|
||||
cryptoService.encrypt.mockResolvedValue(encryptedKey);
|
||||
encryptService.encrypt.mockResolvedValue(encryptedKey);
|
||||
});
|
||||
|
||||
it("returns re-encrypted user folders", async () => {
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { Observable, firstValueFrom, map, shareReplay } from "rxjs";
|
||||
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
|
||||
import { CryptoService } from "../../../platform/abstractions/crypto.service";
|
||||
import { I18nService } from "../../../platform/abstractions/i18n.service";
|
||||
import { Utils } from "../../../platform/misc/utils";
|
||||
@ -25,6 +27,7 @@ export class FolderService implements InternalFolderServiceAbstraction {
|
||||
|
||||
constructor(
|
||||
private cryptoService: CryptoService,
|
||||
private encryptService: EncryptService,
|
||||
private i18nService: I18nService,
|
||||
private cipherService: CipherService,
|
||||
private stateProvider: StateProvider,
|
||||
@ -48,10 +51,10 @@ export class FolderService implements InternalFolderServiceAbstraction {
|
||||
}
|
||||
|
||||
// TODO: This should be moved to EncryptService or something
|
||||
async encrypt(model: FolderView, key?: SymmetricCryptoKey): Promise<Folder> {
|
||||
async encrypt(model: FolderView, key: SymmetricCryptoKey): Promise<Folder> {
|
||||
const folder = new Folder();
|
||||
folder.id = model.id;
|
||||
folder.name = await this.cryptoService.encrypt(model.name, key);
|
||||
folder.name = await this.encryptService.encrypt(model.name, key);
|
||||
return folder;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ import { mock, MockProxy } from "jest-mock-extended";
|
||||
import { PinServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { KdfType } from "@bitwarden/common/platform/enums";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
@ -19,6 +20,7 @@ import { emptyUnencryptedExport } from "./test-data/bitwarden-json/unencrypted.j
|
||||
describe("BitwardenPasswordProtectedImporter", () => {
|
||||
let importer: BitwardenPasswordProtectedImporter;
|
||||
let cryptoService: MockProxy<CryptoService>;
|
||||
let encryptService: MockProxy<EncryptService>;
|
||||
let i18nService: MockProxy<I18nService>;
|
||||
let cipherService: MockProxy<CipherService>;
|
||||
let pinService: MockProxy<PinServiceAbstraction>;
|
||||
@ -30,6 +32,7 @@ describe("BitwardenPasswordProtectedImporter", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
cryptoService = mock<CryptoService>();
|
||||
encryptService = mock<EncryptService>();
|
||||
i18nService = mock<I18nService>();
|
||||
cipherService = mock<CipherService>();
|
||||
pinService = mock<PinServiceAbstraction>();
|
||||
@ -37,6 +40,7 @@ describe("BitwardenPasswordProtectedImporter", () => {
|
||||
|
||||
importer = new BitwardenPasswordProtectedImporter(
|
||||
cryptoService,
|
||||
encryptService,
|
||||
i18nService,
|
||||
cipherService,
|
||||
pinService,
|
||||
@ -91,7 +95,7 @@ describe("BitwardenPasswordProtectedImporter", () => {
|
||||
});
|
||||
|
||||
it("succeeds with default jdoc", async () => {
|
||||
cryptoService.decryptToUtf8.mockReturnValue(Promise.resolve(emptyUnencryptedExport));
|
||||
encryptService.decryptToUtf8.mockReturnValue(Promise.resolve(emptyUnencryptedExport));
|
||||
|
||||
expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(true);
|
||||
});
|
||||
|
@ -30,6 +30,7 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { ClientType } from "@bitwarden/common/enums";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@ -89,6 +90,7 @@ const safeProviders: SafeProvider[] = [
|
||||
I18nService,
|
||||
CollectionService,
|
||||
CryptoService,
|
||||
EncryptService,
|
||||
PinServiceAbstraction,
|
||||
AccountService,
|
||||
],
|
||||
|
@ -8,8 +8,10 @@ import {
|
||||
FolderWithIdExport,
|
||||
} from "@bitwarden/common/models/export";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view";
|
||||
@ -31,6 +33,7 @@ export class BitwardenJsonImporter extends BaseImporter implements Importer {
|
||||
|
||||
protected constructor(
|
||||
protected cryptoService: CryptoService,
|
||||
protected encryptService: EncryptService,
|
||||
protected i18nService: I18nService,
|
||||
protected cipherService: CipherService,
|
||||
protected pinService: PinServiceAbstraction,
|
||||
@ -60,11 +63,16 @@ export class BitwardenJsonImporter extends BaseImporter implements Importer {
|
||||
results: BitwardenEncryptedIndividualJsonExport | BitwardenEncryptedOrgJsonExport,
|
||||
) {
|
||||
if (results.encKeyValidation_DO_NOT_EDIT != null) {
|
||||
const orgKey = await this.cryptoService.getOrgKey(this.organizationId);
|
||||
let keyForDecryption: SymmetricCryptoKey = await this.cryptoService.getOrgKey(
|
||||
this.organizationId,
|
||||
);
|
||||
if (keyForDecryption == null) {
|
||||
keyForDecryption = await this.cryptoService.getUserKeyWithLegacySupport();
|
||||
}
|
||||
const encKeyValidation = new EncString(results.encKeyValidation_DO_NOT_EDIT);
|
||||
const encKeyValidationDecrypt = await this.cryptoService.decryptToUtf8(
|
||||
const encKeyValidationDecrypt = await this.encryptService.decryptToUtf8(
|
||||
encKeyValidation,
|
||||
orgKey,
|
||||
keyForDecryption,
|
||||
);
|
||||
if (encKeyValidationDecrypt === null) {
|
||||
this.result.success = false;
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
PBKDF2KdfConfig,
|
||||
} from "@bitwarden/common/auth/models/domain/kdf-config";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { KdfType } from "@bitwarden/common/platform/enums";
|
||||
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||
@ -23,13 +24,14 @@ export class BitwardenPasswordProtectedImporter extends BitwardenJsonImporter im
|
||||
|
||||
constructor(
|
||||
cryptoService: CryptoService,
|
||||
encryptService: EncryptService,
|
||||
i18nService: I18nService,
|
||||
cipherService: CipherService,
|
||||
pinService: PinServiceAbstraction,
|
||||
accountService: AccountService,
|
||||
private promptForPassword_callback: () => Promise<string>,
|
||||
) {
|
||||
super(cryptoService, i18nService, cipherService, pinService, accountService);
|
||||
super(cryptoService, encryptService, i18nService, cipherService, pinService, accountService);
|
||||
}
|
||||
|
||||
async parse(data: string): Promise<ImportResult> {
|
||||
@ -65,7 +67,7 @@ export class BitwardenPasswordProtectedImporter extends BitwardenJsonImporter im
|
||||
}
|
||||
|
||||
const encData = new EncString(parsedData.data);
|
||||
const clearTextData = await this.cryptoService.decryptToUtf8(encData, this.key);
|
||||
const clearTextData = await this.encryptService.decryptToUtf8(encData, this.key);
|
||||
return await super.parse(clearTextData);
|
||||
}
|
||||
|
||||
@ -86,7 +88,7 @@ export class BitwardenPasswordProtectedImporter extends BitwardenJsonImporter im
|
||||
|
||||
const encKeyValidation = new EncString(jdoc.encKeyValidation_DO_NOT_EDIT);
|
||||
|
||||
const encKeyValidationDecrypt = await this.cryptoService.decryptToUtf8(
|
||||
const encKeyValidationDecrypt = await this.encryptService.decryptToUtf8(
|
||||
encKeyValidation,
|
||||
this.key,
|
||||
);
|
||||
|
@ -3,6 +3,7 @@ import { mock, MockProxy } from "jest-mock-extended";
|
||||
import { PinServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
@ -27,6 +28,7 @@ describe("ImportService", () => {
|
||||
let i18nService: MockProxy<I18nService>;
|
||||
let collectionService: MockProxy<CollectionService>;
|
||||
let cryptoService: MockProxy<CryptoService>;
|
||||
let encryptService: MockProxy<EncryptService>;
|
||||
let pinService: MockProxy<PinServiceAbstraction>;
|
||||
let accountService: MockProxy<AccountService>;
|
||||
|
||||
@ -37,6 +39,7 @@ describe("ImportService", () => {
|
||||
i18nService = mock<I18nService>();
|
||||
collectionService = mock<CollectionService>();
|
||||
cryptoService = mock<CryptoService>();
|
||||
encryptService = mock<EncryptService>();
|
||||
pinService = mock<PinServiceAbstraction>();
|
||||
|
||||
importService = new ImportService(
|
||||
@ -46,6 +49,7 @@ describe("ImportService", () => {
|
||||
i18nService,
|
||||
collectionService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
pinService,
|
||||
accountService,
|
||||
);
|
||||
|
@ -7,6 +7,7 @@ import { ImportOrganizationCiphersRequest } from "@bitwarden/common/models/reque
|
||||
import { KvpRequest } from "@bitwarden/common/models/request/kvp.request";
|
||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
@ -104,6 +105,7 @@ export class ImportService implements ImportServiceAbstraction {
|
||||
private i18nService: I18nService,
|
||||
private collectionService: CollectionService,
|
||||
private cryptoService: CryptoService,
|
||||
private encryptService: EncryptService,
|
||||
private pinService: PinServiceAbstraction,
|
||||
private accountService: AccountService,
|
||||
) {}
|
||||
@ -207,6 +209,7 @@ export class ImportService implements ImportServiceAbstraction {
|
||||
case "bitwardenpasswordprotected":
|
||||
return new BitwardenPasswordProtectedImporter(
|
||||
this.cryptoService,
|
||||
this.encryptService,
|
||||
this.i18nService,
|
||||
this.cipherService,
|
||||
this.pinService,
|
||||
@ -344,9 +347,10 @@ export class ImportService implements ImportServiceAbstraction {
|
||||
const c = await this.cipherService.encrypt(importResult.ciphers[i], activeUserId);
|
||||
request.ciphers.push(new CipherRequest(c));
|
||||
}
|
||||
const userKey = await this.cryptoService.getUserKeyWithLegacySupport(activeUserId);
|
||||
if (importResult.folders != null) {
|
||||
for (let i = 0; i < importResult.folders.length; i++) {
|
||||
const f = await this.folderService.encrypt(importResult.folders[i]);
|
||||
const f = await this.folderService.encrypt(importResult.folders[i], userKey);
|
||||
request.folders.push(new FolderWithIdRequest(f));
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import { PinServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service";
|
||||
import { KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config";
|
||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { KdfType } from "@bitwarden/common/platform/enums";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||
@ -12,7 +12,7 @@ import { BitwardenCsvExportType, BitwardenPasswordProtectedFileFormat } from "..
|
||||
export class BaseVaultExportService {
|
||||
constructor(
|
||||
protected pinService: PinServiceAbstraction,
|
||||
protected cryptoService: CryptoService,
|
||||
protected encryptService: EncryptService,
|
||||
private cryptoFunctionService: CryptoFunctionService,
|
||||
private kdfConfigService: KdfConfigService,
|
||||
) {}
|
||||
@ -23,8 +23,8 @@ export class BaseVaultExportService {
|
||||
const salt = Utils.fromBufferToB64(await this.cryptoFunctionService.randomBytes(16));
|
||||
const key = await this.pinService.makePinKey(password, salt, kdfConfig);
|
||||
|
||||
const encKeyValidation = await this.cryptoService.encrypt(Utils.newGuid(), key);
|
||||
const encText = await this.cryptoService.encrypt(clearText, key);
|
||||
const encKeyValidation = await this.encryptService.encrypt(Utils.newGuid(), key);
|
||||
const encText = await this.encryptService.encrypt(clearText, key);
|
||||
|
||||
const jsonDoc: BitwardenPasswordProtectedFileFormat = {
|
||||
encrypted: true,
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { mock, MockProxy } from "jest-mock-extended";
|
||||
import { BehaviorSubject } from "rxjs";
|
||||
|
||||
import { PinServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { AccountInfo, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service";
|
||||
import {
|
||||
DEFAULT_KDF_CONFIG,
|
||||
@ -9,9 +11,11 @@ import {
|
||||
import { CipherWithIdExport } from "@bitwarden/common/models/export/cipher-with-ids.export";
|
||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { KdfType } from "@bitwarden/common/platform/enums";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { EncryptedString, EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||
@ -149,7 +153,9 @@ describe("VaultExportService", () => {
|
||||
let pinService: MockProxy<PinServiceAbstraction>;
|
||||
let folderService: MockProxy<FolderService>;
|
||||
let cryptoService: MockProxy<CryptoService>;
|
||||
let encryptService: MockProxy<EncryptService>;
|
||||
let kdfConfigService: MockProxy<KdfConfigService>;
|
||||
let accountService: MockProxy<AccountService>;
|
||||
|
||||
beforeEach(() => {
|
||||
cryptoFunctionService = mock<CryptoFunctionService>();
|
||||
@ -157,20 +163,35 @@ describe("VaultExportService", () => {
|
||||
pinService = mock<PinServiceAbstraction>();
|
||||
folderService = mock<FolderService>();
|
||||
cryptoService = mock<CryptoService>();
|
||||
encryptService = mock<EncryptService>();
|
||||
kdfConfigService = mock<KdfConfigService>();
|
||||
accountService = mock<AccountService>();
|
||||
|
||||
cryptoService.userKey$.mockReturnValue(new BehaviorSubject("mockOriginalUserKey" as any));
|
||||
|
||||
const userId = "" as UserId;
|
||||
const accountInfo: AccountInfo = {
|
||||
email: "",
|
||||
emailVerified: true,
|
||||
name: undefined,
|
||||
};
|
||||
const activeAccount = { id: userId, ...accountInfo };
|
||||
accountService.activeAccount$ = new BehaviorSubject(activeAccount);
|
||||
|
||||
folderService.getAllDecryptedFromState.mockResolvedValue(UserFolderViews);
|
||||
folderService.getAllFromState.mockResolvedValue(UserFolders);
|
||||
kdfConfigService.getKdfConfig.mockResolvedValue(DEFAULT_KDF_CONFIG);
|
||||
cryptoService.encrypt.mockResolvedValue(new EncString("encrypted"));
|
||||
encryptService.encrypt.mockResolvedValue(new EncString("encrypted"));
|
||||
|
||||
exportService = new IndividualVaultExportService(
|
||||
folderService,
|
||||
cipherService,
|
||||
pinService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
cryptoFunctionService,
|
||||
kdfConfigService,
|
||||
accountService,
|
||||
);
|
||||
});
|
||||
|
||||
@ -250,7 +271,7 @@ describe("VaultExportService", () => {
|
||||
});
|
||||
|
||||
it("has a mac property", async () => {
|
||||
cryptoService.encrypt.mockResolvedValue(mac);
|
||||
encryptService.encrypt.mockResolvedValue(mac);
|
||||
exportString = await exportService.getPasswordProtectedExport(password);
|
||||
exportObject = JSON.parse(exportString);
|
||||
|
||||
@ -258,7 +279,7 @@ describe("VaultExportService", () => {
|
||||
});
|
||||
|
||||
it("has data property", async () => {
|
||||
cryptoService.encrypt.mockResolvedValue(data);
|
||||
encryptService.encrypt.mockResolvedValue(data);
|
||||
exportString = await exportService.getPasswordProtectedExport(password);
|
||||
exportObject = JSON.parse(exportString);
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
import * as papa from "papaparse";
|
||||
import { firstValueFrom, map } from "rxjs";
|
||||
|
||||
import { PinServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service";
|
||||
import { CipherWithIdExport, FolderWithIdExport } from "@bitwarden/common/models/export";
|
||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
||||
@ -32,11 +35,13 @@ export class IndividualVaultExportService
|
||||
private folderService: FolderService,
|
||||
private cipherService: CipherService,
|
||||
pinService: PinServiceAbstraction,
|
||||
cryptoService: CryptoService,
|
||||
private cryptoService: CryptoService,
|
||||
encryptService: EncryptService,
|
||||
cryptoFunctionService: CryptoFunctionService,
|
||||
kdfConfigService: KdfConfigService,
|
||||
private accountService: AccountService,
|
||||
) {
|
||||
super(pinService, cryptoService, cryptoFunctionService, kdfConfigService);
|
||||
super(pinService, encryptService, cryptoFunctionService, kdfConfigService);
|
||||
}
|
||||
|
||||
async getExport(format: ExportFormat = "csv"): Promise<string> {
|
||||
@ -96,7 +101,11 @@ export class IndividualVaultExportService
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
const encKeyValidation = await this.cryptoService.encrypt(Utils.newGuid());
|
||||
const activeUserId = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
|
||||
);
|
||||
const userKey = await this.cryptoService.getUserKeyWithLegacySupport(activeUserId);
|
||||
const encKeyValidation = await this.encryptService.encrypt(Utils.newGuid(), userKey);
|
||||
|
||||
const jsonDoc: BitwardenEncryptedIndividualJsonExport = {
|
||||
encrypted: true,
|
||||
|
@ -8,6 +8,7 @@ import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config
|
||||
import { CipherWithIdExport, CollectionWithIdExport } from "@bitwarden/common/models/export";
|
||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
@ -39,13 +40,14 @@ export class OrganizationVaultExportService
|
||||
private cipherService: CipherService,
|
||||
private apiService: ApiService,
|
||||
pinService: PinServiceAbstraction,
|
||||
cryptoService: CryptoService,
|
||||
private cryptoService: CryptoService,
|
||||
encryptService: EncryptService,
|
||||
cryptoFunctionService: CryptoFunctionService,
|
||||
private collectionService: CollectionService,
|
||||
kdfConfigService: KdfConfigService,
|
||||
private accountService: AccountService,
|
||||
) {
|
||||
super(pinService, cryptoService, cryptoFunctionService, kdfConfigService);
|
||||
super(pinService, encryptService, cryptoFunctionService, kdfConfigService);
|
||||
}
|
||||
|
||||
async getPasswordProtectedExport(
|
||||
@ -242,7 +244,7 @@ export class OrganizationVaultExportService
|
||||
ciphers: Cipher[],
|
||||
): Promise<string> {
|
||||
const orgKey = await this.cryptoService.getOrgKey(organizationId);
|
||||
const encKeyValidation = await this.cryptoService.encrypt(Utils.newGuid(), orgKey);
|
||||
const encKeyValidation = await this.encryptService.encrypt(Utils.newGuid(), orgKey);
|
||||
|
||||
const jsonDoc: BitwardenEncryptedOrgJsonExport = {
|
||||
encrypted: true,
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { mock, MockProxy } from "jest-mock-extended";
|
||||
import { BehaviorSubject } from "rxjs";
|
||||
|
||||
import { PinServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { AccountInfo, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service";
|
||||
import {
|
||||
DEFAULT_KDF_CONFIG,
|
||||
@ -9,9 +11,11 @@ import {
|
||||
import { CipherWithIdExport } from "@bitwarden/common/models/export/cipher-with-ids.export";
|
||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { KdfType } from "@bitwarden/common/platform/enums";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { EncryptedString, EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||
@ -149,6 +153,8 @@ describe("VaultExportService", () => {
|
||||
let pinService: MockProxy<PinServiceAbstraction>;
|
||||
let folderService: MockProxy<FolderService>;
|
||||
let cryptoService: MockProxy<CryptoService>;
|
||||
let encryptService: MockProxy<EncryptService>;
|
||||
let accountService: MockProxy<AccountService>;
|
||||
let kdfConfigService: MockProxy<KdfConfigService>;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -157,20 +163,34 @@ describe("VaultExportService", () => {
|
||||
pinService = mock<PinServiceAbstraction>();
|
||||
folderService = mock<FolderService>();
|
||||
cryptoService = mock<CryptoService>();
|
||||
encryptService = mock<EncryptService>();
|
||||
accountService = mock<AccountService>();
|
||||
|
||||
kdfConfigService = mock<KdfConfigService>();
|
||||
|
||||
folderService.getAllDecryptedFromState.mockResolvedValue(UserFolderViews);
|
||||
folderService.getAllFromState.mockResolvedValue(UserFolders);
|
||||
kdfConfigService.getKdfConfig.mockResolvedValue(DEFAULT_KDF_CONFIG);
|
||||
cryptoService.encrypt.mockResolvedValue(new EncString("encrypted"));
|
||||
encryptService.encrypt.mockResolvedValue(new EncString("encrypted"));
|
||||
cryptoService.userKey$.mockReturnValue(new BehaviorSubject("mockOriginalUserKey" as any));
|
||||
const userId = "" as UserId;
|
||||
const accountInfo: AccountInfo = {
|
||||
email: "",
|
||||
emailVerified: true,
|
||||
name: undefined,
|
||||
};
|
||||
const activeAccount = { id: userId, ...accountInfo };
|
||||
accountService.activeAccount$ = new BehaviorSubject(activeAccount);
|
||||
|
||||
exportService = new IndividualVaultExportService(
|
||||
folderService,
|
||||
cipherService,
|
||||
pinService,
|
||||
cryptoService,
|
||||
encryptService,
|
||||
cryptoFunctionService,
|
||||
kdfConfigService,
|
||||
accountService,
|
||||
);
|
||||
});
|
||||
|
||||
@ -250,7 +270,7 @@ describe("VaultExportService", () => {
|
||||
});
|
||||
|
||||
it("has a mac property", async () => {
|
||||
cryptoService.encrypt.mockResolvedValue(mac);
|
||||
encryptService.encrypt.mockResolvedValue(mac);
|
||||
exportString = await exportService.getPasswordProtectedExport(password);
|
||||
exportObject = JSON.parse(exportString);
|
||||
|
||||
@ -258,7 +278,7 @@ describe("VaultExportService", () => {
|
||||
});
|
||||
|
||||
it("has data property", async () => {
|
||||
cryptoService.encrypt.mockResolvedValue(data);
|
||||
encryptService.encrypt.mockResolvedValue(data);
|
||||
exportString = await exportService.getPasswordProtectedExport(password);
|
||||
exportObject = JSON.parse(exportString);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<bit-section [formGroup]="sendOptionsForm">
|
||||
<bit-section-header>
|
||||
<h2 class="tw-mt-4" bitTypography="h5">{{ "additionalOptions" | i18n }}</h2>
|
||||
<h2 class="tw-mt-4" bitTypography="h6">{{ "additionalOptions" | i18n }}</h2>
|
||||
</bit-section-header>
|
||||
<bit-card>
|
||||
<bit-form-field>
|
||||
@ -16,16 +16,21 @@
|
||||
<bit-label *ngIf="hasPassword">{{ "newPassword" | i18n }}</bit-label>
|
||||
<input bitInput type="password" formControlName="password" />
|
||||
<button type="button" bitIconButton bitSuffix bitPasswordInputToggle></button>
|
||||
<button type="button" bitIconButton="bwi-refresh" bitSuffix></button>
|
||||
<button
|
||||
type="button"
|
||||
bitIconButton="bwi-generate"
|
||||
bitSuffix
|
||||
[appA11yTitle]="'generatePassword' | i18n"
|
||||
></button>
|
||||
<bit-hint>{{ "sendPasswordDescV2" | i18n }}</bit-hint>
|
||||
</bit-form-field>
|
||||
<bit-form-control *ngIf="!disableHideEmail">
|
||||
<input bitCheckbox type="checkbox" formControlName="hideEmail" />
|
||||
<bit-label>{{ "hideYourEmail" | i18n }}</bit-label>
|
||||
</bit-form-control>
|
||||
<bit-form-field>
|
||||
<bit-form-field disableMargin>
|
||||
<bit-label>{{ "privateNote" | i18n }}</bit-label>
|
||||
<textarea bitInput rows="4" formControlName="notes"></textarea>
|
||||
<textarea bitInput rows="3" formControlName="notes"></textarea>
|
||||
</bit-form-field>
|
||||
</bit-card>
|
||||
</bit-section>
|
||||
|
@ -102,7 +102,7 @@ export class SendOptionsComponent implements OnInit {
|
||||
this.sendOptionsForm.patchValue({
|
||||
maxAccessCount: this.sendFormContainer.originalSendView.maxAccessCount,
|
||||
accessCount: this.sendFormContainer.originalSendView.accessCount,
|
||||
password: this.sendFormContainer.originalSendView.password,
|
||||
password: null,
|
||||
hideEmail: this.sendFormContainer.originalSendView.hideEmail,
|
||||
notes: this.sendFormContainer.originalSendView.notes,
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
<bit-section [formGroup]="sendDetailsForm">
|
||||
<bit-section-header class="tw-mt-4">
|
||||
<h2 bitTypography="h5">{{ "sendDetails" | i18n }}</h2>
|
||||
<bit-section-header class="tw-mt-2">
|
||||
<h2 bitTypography="h6">{{ "sendDetails" | i18n }}</h2>
|
||||
</bit-section-header>
|
||||
|
||||
<bit-card>
|
||||
@ -34,7 +34,7 @@
|
||||
></button>
|
||||
</bit-form-field>
|
||||
|
||||
<bit-form-field>
|
||||
<bit-form-field disableMargin>
|
||||
<bit-label>{{ "deletionDate" | i18n }}</bit-label>
|
||||
<bit-select
|
||||
id="deletionDate"
|
||||
|
@ -1,20 +1,22 @@
|
||||
<bit-section [formGroup]="sendFileDetailsForm">
|
||||
<div *ngIf="config.mode === 'edit'">
|
||||
<div class="tw-text-muted">{{ "file" | i18n }}</div>
|
||||
<div bitTypography="body2" class="tw-text-muted">{{ "file" | i18n }}</div>
|
||||
<div>{{ originalSendView.file.fileName }}</div>
|
||||
<div class="tw-text-muted">{{ originalSendView.file.sizeName }}</div>
|
||||
</div>
|
||||
<bit-form-field *ngIf="config.mode !== 'edit'">
|
||||
<bit-label for="file">{{ "fileToShare" | i18n }}</bit-label>
|
||||
<button bitButton type="button" buttonType="primary" (click)="fileSelector.click()">
|
||||
{{ "chooseFile" | i18n }}
|
||||
</button>
|
||||
<span
|
||||
class="tw-flex tw-items-center tw-pl-3"
|
||||
[ngClass]="fileName ? 'tw-text-main' : 'tw-text-muted'"
|
||||
>
|
||||
{{ fileName || ("noFileChosen" | i18n) }}</span
|
||||
>
|
||||
<div class="tw-flex tw-mt-2 tw-mb-1">
|
||||
<button bitButton type="button" buttonType="secondary" (click)="fileSelector.click()">
|
||||
{{ "chooseFile" | i18n }}
|
||||
</button>
|
||||
<span
|
||||
class="tw-flex tw-items-center tw-pl-3"
|
||||
[ngClass]="fileName ? 'tw-text-main' : 'tw-text-muted'"
|
||||
>
|
||||
{{ fileName || ("noFileChosen" | i18n) }}</span
|
||||
>
|
||||
</div>
|
||||
<input
|
||||
bitInput
|
||||
#fileSelector
|
||||
|
@ -7,7 +7,12 @@ import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
|
||||
import { SendFileView } from "@bitwarden/common/tools/send/models/view/send-file.view";
|
||||
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
|
||||
import { ButtonModule, FormFieldModule, SectionComponent } from "@bitwarden/components";
|
||||
import {
|
||||
ButtonModule,
|
||||
FormFieldModule,
|
||||
SectionComponent,
|
||||
TypographyModule,
|
||||
} from "@bitwarden/components";
|
||||
|
||||
import { SendFormConfig } from "../../abstractions/send-form-config.service";
|
||||
import { SendFormContainer } from "../../send-form-container";
|
||||
@ -24,6 +29,7 @@ import { SendFormContainer } from "../../send-form-container";
|
||||
FormFieldModule,
|
||||
SectionComponent,
|
||||
FormsModule,
|
||||
TypographyModule,
|
||||
],
|
||||
})
|
||||
export class SendFileDetailsComponent implements OnInit {
|
||||
|
@ -16,6 +16,7 @@ import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||
import { FormBuilder, ReactiveFormsModule } from "@angular/forms";
|
||||
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
|
||||
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
|
||||
import {
|
||||
@ -199,6 +200,10 @@ export class SendFormComponent implements AfterViewInit, OnInit, OnChanges, Send
|
||||
return;
|
||||
}
|
||||
|
||||
if (Utils.isNullOrWhitespace(this.updatedSendView.password)) {
|
||||
this.updatedSendView.password = null;
|
||||
}
|
||||
|
||||
await this.addEditFormService.saveSend(this.updatedSendView, this.file, this.config);
|
||||
|
||||
this.toastService.showToast({
|
||||
|
@ -64,7 +64,7 @@ export class SendListItemsContainerComponent {
|
||||
async deleteSend(s: SendView): Promise<boolean> {
|
||||
const confirmed = await this.dialogService.openSimpleDialog({
|
||||
title: { key: "deleteSend" },
|
||||
content: { key: "deleteSendConfirmation" },
|
||||
content: { key: "deleteSendPermanentConfirmation" },
|
||||
type: "warning",
|
||||
});
|
||||
|
||||
|
@ -125,7 +125,7 @@ export class LoginDetailsSectionComponent implements OnInit {
|
||||
Object.assign(cipher.login, {
|
||||
username: value.username,
|
||||
password: value.password,
|
||||
totp: value.totp,
|
||||
totp: value.totp?.trim(),
|
||||
} as LoginView);
|
||||
|
||||
return cipher;
|
||||
|
8
package-lock.json
generated
8
package-lock.json
generated
@ -192,11 +192,11 @@
|
||||
},
|
||||
"apps/browser": {
|
||||
"name": "@bitwarden/browser",
|
||||
"version": "2024.9.1"
|
||||
"version": "2024.9.2"
|
||||
},
|
||||
"apps/cli": {
|
||||
"name": "@bitwarden/cli",
|
||||
"version": "2024.9.0",
|
||||
"version": "2024.9.1",
|
||||
"license": "SEE LICENSE IN LICENSE.txt",
|
||||
"dependencies": {
|
||||
"@koa/multer": "3.0.2",
|
||||
@ -232,7 +232,7 @@
|
||||
},
|
||||
"apps/desktop": {
|
||||
"name": "@bitwarden/desktop",
|
||||
"version": "2024.9.1",
|
||||
"version": "2024.9.2",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0"
|
||||
},
|
||||
@ -246,7 +246,7 @@
|
||||
},
|
||||
"apps/web": {
|
||||
"name": "@bitwarden/web-vault",
|
||||
"version": "2024.9.1"
|
||||
"version": "2024.9.2"
|
||||
},
|
||||
"libs/admin-console": {
|
||||
"name": "@bitwarden/admin-console",
|
||||
|
Loading…
Reference in New Issue
Block a user