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

[PM-328] Move Send to Tools (#5104)

* Move send in libs/common

* Move send in libs/angular

* Move send in browser

* Move send in cli

* Move send in desktop

* Move send in web
This commit is contained in:
Daniel James Smith
2023-03-29 16:23:37 +02:00
committed by GitHub
parent e645688f8a
commit e238ea20a9
105 changed files with 328 additions and 321 deletions

View File

@@ -1,4 +1,4 @@
import { SendView } from "../models/view/send.view";
import { SendView } from "../tools/send/models/view/send.view";
import { CipherView } from "../vault/models/view/cipher.view";
export abstract class SearchService {

View File

@@ -13,15 +13,15 @@ import { KdfType } from "../enums/kdfType";
import { ThemeType } from "../enums/themeType";
import { UriMatchType } from "../enums/uriMatchType";
import { EventData } from "../models/data/event.data";
import { SendData } from "../models/data/send.data";
import { ServerConfigData } from "../models/data/server-config.data";
import { Account, AccountSettingsSettings } from "../models/domain/account";
import { EncString } from "../models/domain/enc-string";
import { StorageOptions } from "../models/domain/storage-options";
import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key";
import { WindowState } from "../models/domain/window-state";
import { SendView } from "../models/view/send.view";
import { GeneratedPasswordHistory } from "../tools/generator/password";
import { SendData } from "../tools/send/models/data/send.data";
import { SendView } from "../tools/send/models/view/send.view";
import { CipherData } from "../vault/models/data/cipher.data";
import { FolderData } from "../vault/models/data/folder.data";
import { LocalData } from "../vault/models/data/local.data";

View File

@@ -13,14 +13,14 @@ import { KdfType } from "../../enums/kdfType";
import { UriMatchType } from "../../enums/uriMatchType";
import { Utils } from "../../misc/utils";
import { GeneratedPasswordHistory } from "../../tools/generator/password";
import { SendData } from "../../tools/send/models/data/send.data";
import { SendView } from "../../tools/send/models/view/send.view";
import { DeepJsonify } from "../../types/deep-jsonify";
import { CipherData } from "../../vault/models/data/cipher.data";
import { FolderData } from "../../vault/models/data/folder.data";
import { CipherView } from "../../vault/models/view/cipher.view";
import { EventData } from "../data/event.data";
import { SendData } from "../data/send.data";
import { ServerConfigData } from "../data/server-config.data";
import { SendView } from "../view/send.view";
import { EncString } from "./enc-string";
import { SymmetricCryptoKey } from "./symmetric-crypto-key";

View File

@@ -1,8 +1,7 @@
import { SendWithIdRequest } from "../../tools/send/models/request/send-with-id.request";
import { CipherWithIdRequest } from "../../vault/models/request/cipher-with-id.request";
import { FolderWithIdRequest } from "../../vault/models/request/folder-with-id.request";
import { SendWithIdRequest } from "./send-with-id.request";
export class UpdateKeyRequest {
ciphers: CipherWithIdRequest[] = [];
folders: FolderWithIdRequest[] = [];

View File

@@ -5,7 +5,7 @@ import { LogService } from "../abstractions/log.service";
import { SearchService as SearchServiceAbstraction } from "../abstractions/search.service";
import { FieldType } from "../enums/fieldType";
import { UriMatchType } from "../enums/uriMatchType";
import { SendView } from "../models/view/send.view";
import { SendView } from "../tools/send/models/view/send.view";
import { CipherService } from "../vault/abstractions/cipher.service";
import { CipherType } from "../vault/enums/cipher-type";
import { CipherView } from "../vault/models/view/cipher.view";

View File

@@ -25,7 +25,6 @@ import { UriMatchType } from "../enums/uriMatchType";
import { StateFactory } from "../factories/stateFactory";
import { Utils } from "../misc/utils";
import { EventData } from "../models/data/event.data";
import { SendData } from "../models/data/send.data";
import { ServerConfigData } from "../models/data/server-config.data";
import {
Account,
@@ -39,8 +38,9 @@ import { State } from "../models/domain/state";
import { StorageOptions } from "../models/domain/storage-options";
import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key";
import { WindowState } from "../models/domain/window-state";
import { SendView } from "../models/view/send.view";
import { GeneratedPasswordHistory } from "../tools/generator/password";
import { SendData } from "../tools/send/models/data/send.data";
import { SendView } from "../tools/send/models/view/send.view";
import { CipherData } from "../vault/models/data/cipher.data";
import { FolderData } from "../vault/models/data/folder.data";
import { LocalData } from "../vault/models/data/local.data";

View File

@@ -11,7 +11,6 @@ import { StateVersion } from "../enums/stateVersion";
import { ThemeType } from "../enums/themeType";
import { StateFactory } from "../factories/stateFactory";
import { EventData } from "../models/data/event.data";
import { SendData } from "../models/data/send.data";
import {
Account,
AccountSettings,
@@ -22,6 +21,7 @@ import { EncString } from "../models/domain/enc-string";
import { GlobalState } from "../models/domain/global-state";
import { StorageOptions } from "../models/domain/storage-options";
import { GeneratedPasswordHistory } from "../tools/generator/password";
import { SendData } from "../tools/send/models/data/send.data";
import { CipherData } from "../vault/models/data/cipher.data";
import { FolderData } from "../vault/models/data/folder.data";

View File

@@ -1,4 +1,4 @@
import { BaseResponse } from "../response/base.response";
import { BaseResponse } from "../../../../models/response/base.response";
export class SendFileApi extends BaseResponse {
id: string;

View File

@@ -1,4 +1,4 @@
import { BaseResponse } from "../response/base.response";
import { BaseResponse } from "../../../../models/response/base.response";
export class SendTextApi extends BaseResponse {
text: string;

View File

@@ -1,4 +1,4 @@
import { SendType } from "../../enums/sendType";
import { SendType } from "../../enums/send-type";
import { SendResponse } from "../response/send.response";
import { SendFileData } from "./send-file.data";

View File

@@ -0,0 +1,85 @@
// eslint-disable-next-line no-restricted-imports
import { Substitute, Arg } from "@fluffy-spoon/substitute";
import { mockEnc } from "../../../../../spec/utils";
import { SendType } from "../../enums/send-type";
import { SendAccessResponse } from "../response/send-access.response";
import { SendAccess } from "./send-access";
import { SendText } from "./send-text";
describe("SendAccess", () => {
let request: SendAccessResponse;
beforeEach(() => {
request = {
id: "id",
type: SendType.Text,
name: "encName",
file: null,
text: {
text: "encText",
hidden: true,
},
expirationDate: new Date("2022-01-31T12:00:00.000Z"),
creatorIdentifier: "creatorIdentifier",
} as SendAccessResponse;
});
it("Convert from empty", () => {
const request = new SendAccessResponse({});
const sendAccess = new SendAccess(request);
expect(sendAccess).toEqual({
id: null,
type: undefined,
name: null,
creatorIdentifier: null,
expirationDate: null,
});
});
it("Convert", () => {
const sendAccess = new SendAccess(request);
expect(sendAccess).toEqual({
id: "id",
type: 0,
name: { encryptedString: "encName", encryptionType: 0 },
text: {
hidden: true,
text: { encryptedString: "encText", encryptionType: 0 },
},
expirationDate: new Date("2022-01-31T12:00:00.000Z"),
creatorIdentifier: "creatorIdentifier",
});
});
it("Decrypt", async () => {
const sendAccess = new SendAccess();
sendAccess.id = "id";
sendAccess.type = SendType.Text;
sendAccess.name = mockEnc("name");
const text = Substitute.for<SendText>();
text.decrypt(Arg.any()).resolves({} as any);
sendAccess.text = text;
sendAccess.expirationDate = new Date("2022-01-31T12:00:00.000Z");
sendAccess.creatorIdentifier = "creatorIdentifier";
const view = await sendAccess.decrypt(null);
text.received(1).decrypt(Arg.any());
expect(view).toEqual({
id: "id",
type: 0,
name: "name",
text: {},
file: expect.anything(),
expirationDate: new Date("2022-01-31T12:00:00.000Z"),
creatorIdentifier: "creatorIdentifier",
});
});
});

View File

@@ -1,12 +1,12 @@
import { SendType } from "../../enums/sendType";
import Domain from "../../../../models/domain/domain-base";
import { EncString } from "../../../../models/domain/enc-string";
import { SymmetricCryptoKey } from "../../../../models/domain/symmetric-crypto-key";
import { SendType } from "../../enums/send-type";
import { SendAccessResponse } from "../response/send-access.response";
import { SendAccessView } from "../view/send-access.view";
import Domain from "./domain-base";
import { EncString } from "./enc-string";
import { SendFile } from "./send-file";
import { SendText } from "./send-text";
import { SymmetricCryptoKey } from "./symmetric-crypto-key";
export class SendAccess extends Domain {
id: string;

View File

@@ -0,0 +1,57 @@
import { mockEnc } from "../../../../../spec/utils";
import { SendFileData } from "../data/send-file.data";
import { SendFile } from "./send-file";
describe("SendFile", () => {
let data: SendFileData;
beforeEach(() => {
data = {
id: "id",
size: "1100",
sizeName: "1.1 KB",
fileName: "encFileName",
};
});
it("Convert from empty", () => {
const data = new SendFileData();
const sendFile = new SendFile(data);
expect(sendFile).toEqual({
fileName: null,
id: null,
size: undefined,
sizeName: null,
});
});
it("Convert", () => {
const sendFile = new SendFile(data);
expect(sendFile).toEqual({
id: "id",
size: "1100",
sizeName: "1.1 KB",
fileName: { encryptedString: "encFileName", encryptionType: 0 },
});
});
it("Decrypt", async () => {
const sendFile = new SendFile();
sendFile.id = "id";
sendFile.size = "1100";
sendFile.sizeName = "1.1 KB";
sendFile.fileName = mockEnc("fileName");
const view = await sendFile.decrypt(null);
expect(view).toEqual({
fileName: "fileName",
id: "id",
size: "1100",
sizeName: "1.1 KB",
});
});
});

View File

@@ -1,12 +1,11 @@
import { Jsonify } from "type-fest";
import Domain from "../../../../models/domain/domain-base";
import { EncString } from "../../../../models/domain/enc-string";
import { SymmetricCryptoKey } from "../../../../models/domain/symmetric-crypto-key";
import { SendFileData } from "../data/send-file.data";
import { SendFileView } from "../view/send-file.view";
import Domain from "./domain-base";
import { EncString } from "./enc-string";
import { SymmetricCryptoKey } from "./symmetric-crypto-key";
export class SendFile extends Domain {
id: string;
size: string;

View File

@@ -0,0 +1,47 @@
import { mockEnc } from "../../../../../spec/utils";
import { SendTextData } from "../data/send-text.data";
import { SendText } from "./send-text";
describe("SendText", () => {
let data: SendTextData;
beforeEach(() => {
data = {
text: "encText",
hidden: false,
};
});
it("Convert from empty", () => {
const data = new SendTextData();
const secureNote = new SendText(data);
expect(secureNote).toEqual({
hidden: undefined,
text: null,
});
});
it("Convert", () => {
const secureNote = new SendText(data);
expect(secureNote).toEqual({
hidden: false,
text: { encryptedString: "encText", encryptionType: 0 },
});
});
it("Decrypt", async () => {
const secureNote = new SendText();
secureNote.text = mockEnc("text");
secureNote.hidden = true;
const view = await secureNote.decrypt(null);
expect(view).toEqual({
text: "text",
hidden: true,
});
});
});

View File

@@ -1,12 +1,11 @@
import { Jsonify } from "type-fest";
import Domain from "../../../../models/domain/domain-base";
import { EncString } from "../../../../models/domain/enc-string";
import { SymmetricCryptoKey } from "../../../../models/domain/symmetric-crypto-key";
import { SendTextData } from "../data/send-text.data";
import { SendTextView } from "../view/send-text.view";
import Domain from "./domain-base";
import { EncString } from "./enc-string";
import { SymmetricCryptoKey } from "./symmetric-crypto-key";
export class SendText extends Domain {
text: EncString;
hidden: boolean;

View File

@@ -0,0 +1,144 @@
// eslint-disable-next-line no-restricted-imports
import { Substitute, Arg, SubstituteOf } from "@fluffy-spoon/substitute";
import { makeStaticByteArray, mockEnc } from "../../../../../spec/utils";
import { CryptoService } from "../../../../abstractions/crypto.service";
import { EncryptService } from "../../../../abstractions/encrypt.service";
import { EncString } from "../../../../models/domain/enc-string";
import { ContainerService } from "../../../../services/container.service";
import { SendType } from "../../enums/send-type";
import { SendData } from "../data/send.data";
import { Send } from "./send";
import { SendText } from "./send-text";
describe("Send", () => {
let data: SendData;
beforeEach(() => {
data = {
id: "id",
accessId: "accessId",
type: SendType.Text,
name: "encName",
notes: "encNotes",
text: {
text: "encText",
hidden: true,
},
file: null,
key: "encKey",
maxAccessCount: null,
accessCount: 10,
revisionDate: "2022-01-31T12:00:00.000Z",
expirationDate: "2022-01-31T12:00:00.000Z",
deletionDate: "2022-01-31T12:00:00.000Z",
password: "password",
disabled: false,
hideEmail: true,
};
});
it("Convert from empty", () => {
const data = new SendData();
const send = new Send(data);
expect(send).toEqual({
id: null,
accessId: null,
type: undefined,
name: null,
notes: null,
text: undefined,
file: undefined,
key: null,
maxAccessCount: undefined,
accessCount: undefined,
revisionDate: null,
expirationDate: null,
deletionDate: null,
password: undefined,
disabled: undefined,
hideEmail: undefined,
});
});
it("Convert", () => {
const send = new Send(data);
expect(send).toEqual({
id: "id",
accessId: "accessId",
type: SendType.Text,
name: { encryptedString: "encName", encryptionType: 0 },
notes: { encryptedString: "encNotes", encryptionType: 0 },
text: {
text: { encryptedString: "encText", encryptionType: 0 },
hidden: true,
},
key: { encryptedString: "encKey", encryptionType: 0 },
maxAccessCount: null,
accessCount: 10,
revisionDate: new Date("2022-01-31T12:00:00.000Z"),
expirationDate: new Date("2022-01-31T12:00:00.000Z"),
deletionDate: new Date("2022-01-31T12:00:00.000Z"),
password: "password",
disabled: false,
hideEmail: true,
});
});
it("Decrypt", async () => {
const text = Substitute.for<SendText>();
text.decrypt(Arg.any()).resolves("textView" as any);
const send = new Send();
send.id = "id";
send.accessId = "accessId";
send.type = SendType.Text;
send.name = mockEnc("name");
send.notes = mockEnc("notes");
send.text = text;
send.key = mockEnc("key");
send.accessCount = 10;
send.revisionDate = new Date("2022-01-31T12:00:00.000Z");
send.expirationDate = new Date("2022-01-31T12:00:00.000Z");
send.deletionDate = new Date("2022-01-31T12:00:00.000Z");
send.password = "password";
send.disabled = false;
send.hideEmail = true;
const cryptoService = Substitute.for<CryptoService>();
cryptoService.decryptToBytes(send.key, null).resolves(makeStaticByteArray(32));
cryptoService.makeSendKey(Arg.any()).resolves("cryptoKey" as any);
const encryptService = Substitute.for<EncryptService>();
(window as any).bitwardenContainerService = new ContainerService(cryptoService, encryptService);
const view = await send.decrypt();
text.received(1).decrypt("cryptoKey" as any);
(send.name as SubstituteOf<EncString>).received(1).decrypt(null, "cryptoKey" as any);
expect(view).toMatchObject({
id: "id",
accessId: "accessId",
name: "name",
notes: "notes",
type: 0,
key: expect.anything(),
cryptoKey: "cryptoKey",
file: expect.anything(),
text: "textView",
maxAccessCount: undefined,
accessCount: 10,
revisionDate: new Date("2022-01-31T12:00:00.000Z"),
expirationDate: new Date("2022-01-31T12:00:00.000Z"),
deletionDate: new Date("2022-01-31T12:00:00.000Z"),
password: "password",
disabled: false,
hideEmail: true,
});
});
});

View File

@@ -1,12 +1,12 @@
import { Jsonify } from "type-fest";
import { SendType } from "../../enums/sendType";
import { Utils } from "../../misc/utils";
import { Utils } from "../../../../misc/utils";
import Domain from "../../../../models/domain/domain-base";
import { EncString } from "../../../../models/domain/enc-string";
import { SendType } from "../../enums/send-type";
import { SendData } from "../data/send.data";
import { SendView } from "../view/send.view";
import Domain from "./domain-base";
import { EncString } from "./enc-string";
import { SendFile } from "./send-file";
import { SendText } from "./send-text";

View File

@@ -1,4 +1,4 @@
import { SendType } from "../../enums/sendType";
import { SendType } from "../../enums/send-type";
import { SendFileApi } from "../api/send-file.api";
import { SendTextApi } from "../api/send-text.api";
import { Send } from "../domain/send";

View File

@@ -1,9 +1,8 @@
import { SendType } from "../../enums/sendType";
import { BaseResponse } from "../../../../models/response/base.response";
import { SendType } from "../../enums/send-type";
import { SendFileApi } from "../api/send-file.api";
import { SendTextApi } from "../api/send-text.api";
import { BaseResponse } from "./base.response";
export class SendAccessResponse extends BaseResponse {
id: string;
type: SendType;

View File

@@ -1,4 +1,4 @@
import { BaseResponse } from "./base.response";
import { BaseResponse } from "../../../../models/response/base.response";
export class SendFileDownloadDataResponse extends BaseResponse {
id: string = null;

View File

@@ -1,6 +1,6 @@
import { FileUploadType } from "../../enums/fileUploadType";
import { FileUploadType } from "../../../../enums/fileUploadType";
import { BaseResponse } from "../../../../models/response/base.response";
import { BaseResponse } from "./base.response";
import { SendResponse } from "./send.response";
export class SendFileUploadDataResponse extends BaseResponse {

View File

@@ -1,9 +1,8 @@
import { SendType } from "../../enums/sendType";
import { BaseResponse } from "../../../../models/response/base.response";
import { SendType } from "../../enums/send-type";
import { SendFileApi } from "../api/send-file.api";
import { SendTextApi } from "../api/send-text.api";
import { BaseResponse } from "./base.response";
export class SendResponse extends BaseResponse {
id: string;
accessId: string;

View File

@@ -1,9 +1,9 @@
import { SendType } from "../../enums/sendType";
import { View } from "../../../../models/view/view";
import { SendType } from "../../enums/send-type";
import { SendAccess } from "../domain/send-access";
import { SendFileView } from "./send-file.view";
import { SendTextView } from "./send-text.view";
import { View } from "./view";
export class SendAccessView implements View {
id: string = null;

View File

@@ -1,8 +1,7 @@
import { DeepJsonify } from "../../types/deep-jsonify";
import { View } from "../../../../models/view/view";
import { DeepJsonify } from "../../../../types/deep-jsonify";
import { SendFile } from "../domain/send-file";
import { View } from "./view";
export class SendFileView implements View {
id: string = null;
size: string = null;

View File

@@ -1,8 +1,7 @@
import { DeepJsonify } from "../../types/deep-jsonify";
import { View } from "../../../../models/view/view";
import { DeepJsonify } from "../../../../types/deep-jsonify";
import { SendText } from "../domain/send-text";
import { View } from "./view";
export class SendTextView implements View {
text: string = null;
hidden: boolean;

View File

@@ -1,12 +1,12 @@
import { SendType } from "../../enums/sendType";
import { Utils } from "../../misc/utils";
import { DeepJsonify } from "../../types/deep-jsonify";
import { Utils } from "../../../../misc/utils";
import { SymmetricCryptoKey } from "../../../../models/domain/symmetric-crypto-key";
import { View } from "../../../../models/view/view";
import { DeepJsonify } from "../../../../types/deep-jsonify";
import { SendType } from "../../enums/send-type";
import { Send } from "../domain/send";
import { SymmetricCryptoKey } from "../domain/symmetric-crypto-key";
import { SendFileView } from "./send-file.view";
import { SendTextView } from "./send-text.view";
import { View } from "./view";
export class SendView implements View {
id: string = null;

View File

@@ -1,13 +1,13 @@
import { EncArrayBuffer } from "../../models/domain/enc-array-buffer";
import { Send } from "../../models/domain/send";
import { SendAccessRequest } from "../../models/request/send-access.request";
import { SendRequest } from "../../models/request/send.request";
import { ListResponse } from "../../models/response/list.response";
import { SendAccessResponse } from "../../models/response/send-access.response";
import { SendFileDownloadDataResponse } from "../../models/response/send-file-download-data.response";
import { SendFileUploadDataResponse } from "../../models/response/send-file-upload-data.response";
import { SendResponse } from "../../models/response/send.response";
import { SendAccessView } from "../../models/view/send-access.view";
import { EncArrayBuffer } from "../../../models/domain/enc-array-buffer";
import { ListResponse } from "../../../models/response/list.response";
import { Send } from "../models/domain/send";
import { SendAccessRequest } from "../models/request/send-access.request";
import { SendRequest } from "../models/request/send.request";
import { SendAccessResponse } from "../models/response/send-access.response";
import { SendFileDownloadDataResponse } from "../models/response/send-file-download-data.response";
import { SendFileUploadDataResponse } from "../models/response/send-file-upload-data.response";
import { SendResponse } from "../models/response/send.response";
import { SendAccessView } from "../models/view/send-access.view";
export abstract class SendApiService {
getSend: (id: string) => Promise<SendResponse>;

View File

@@ -1,24 +1,25 @@
import { SendType } from "../../../../common/src/enums/sendType";
import { Utils } from "../../../../common/src/misc/utils";
import { ErrorResponse } from "../../../../common/src/models/response/error.response";
import { ApiService } from "../../abstractions/api.service";
import { ApiService } from "../../../abstractions/api.service";
import {
FileUploadApiMethods,
FileUploadService,
} from "../../abstractions/file-upload/file-upload.service";
import { SendApiService as SendApiServiceAbstraction } from "../../abstractions/send/send-api.service.abstraction";
import { InternalSendService } from "../../abstractions/send/send.service.abstraction";
import { SendData } from "../../models/data/send.data";
import { EncArrayBuffer } from "../../models/domain/enc-array-buffer";
import { Send } from "../../models/domain/send";
import { SendAccessRequest } from "../../models/request/send-access.request";
import { SendRequest } from "../../models/request/send.request";
import { ListResponse } from "../../models/response/list.response";
import { SendAccessResponse } from "../../models/response/send-access.response";
import { SendFileDownloadDataResponse } from "../../models/response/send-file-download-data.response";
import { SendFileUploadDataResponse } from "../../models/response/send-file-upload-data.response";
import { SendResponse } from "../../models/response/send.response";
import { SendAccessView } from "../../models/view/send-access.view";
} from "../../../abstractions/file-upload/file-upload.service";
import { Utils } from "../../../misc/utils";
import { EncArrayBuffer } from "../../../models/domain/enc-array-buffer";
import { ErrorResponse } from "../../../models/response/error.response";
import { ListResponse } from "../../../models/response/list.response";
import { SendType } from "../enums/send-type";
import { SendData } from "../models/data/send.data";
import { Send } from "../models/domain/send";
import { SendAccessRequest } from "../models/request/send-access.request";
import { SendRequest } from "../models/request/send.request";
import { SendAccessResponse } from "../models/response/send-access.response";
import { SendFileDownloadDataResponse } from "../models/response/send-file-download-data.response";
import { SendFileUploadDataResponse } from "../models/response/send-file-upload-data.response";
import { SendResponse } from "../models/response/send.response";
import { SendAccessView } from "../models/view/send-access.view";
import { SendApiService as SendApiServiceAbstraction } from "./send-api.service.abstraction";
import { InternalSendService } from "./send.service.abstraction";
export class SendApiService implements SendApiServiceAbstraction {
constructor(

View File

@@ -1,10 +1,10 @@
import { Observable } from "rxjs";
import { SendData } from "../../models/data/send.data";
import { EncArrayBuffer } from "../../models/domain/enc-array-buffer";
import { Send } from "../../models/domain/send";
import { SymmetricCryptoKey } from "../../models/domain/symmetric-crypto-key";
import { SendView } from "../../models/view/send.view";
import { EncArrayBuffer } from "../../../models/domain/enc-array-buffer";
import { SymmetricCryptoKey } from "../../../models/domain/symmetric-crypto-key";
import { SendData } from "../models/data/send.data";
import { Send } from "../models/domain/send";
import { SendView } from "../models/view/send.view";
export abstract class SendService {
sends$: Observable<Send[]>;

View File

@@ -0,0 +1,179 @@
import { any, mock, MockProxy } from "jest-mock-extended";
import { BehaviorSubject, firstValueFrom } from "rxjs";
import { CryptoService } from "../../../abstractions/crypto.service";
import { CryptoFunctionService } from "../../../abstractions/cryptoFunction.service";
import { EncryptService } from "../../../abstractions/encrypt.service";
import { I18nService } from "../../../abstractions/i18n.service";
import { StateService } from "../../../abstractions/state.service";
import { EncString } from "../../../models/domain/enc-string";
import { ContainerService } from "../../../services/container.service";
import { SendData } from "../models/data/send.data";
import { Send } from "../models/domain/send";
import { SendView } from "../models/view/send.view";
import { SendService } from "./send.service";
describe("SendService", () => {
const cryptoService = mock<CryptoService>();
const i18nService = mock<I18nService>();
const cryptoFunctionService = mock<CryptoFunctionService>();
const encryptService = mock<EncryptService>();
let sendService: SendService;
let stateService: MockProxy<StateService>;
let activeAccount: BehaviorSubject<string>;
let activeAccountUnlocked: BehaviorSubject<boolean>;
beforeEach(() => {
activeAccount = new BehaviorSubject("123");
activeAccountUnlocked = new BehaviorSubject(true);
stateService = mock<StateService>();
stateService.activeAccount$ = activeAccount;
stateService.activeAccountUnlocked$ = activeAccountUnlocked;
(window as any).bitwardenContainerService = new ContainerService(cryptoService, encryptService);
stateService.getEncryptedSends.calledWith(any()).mockResolvedValue({
"1": sendData("1", "Test Send"),
});
stateService.getDecryptedSends
.calledWith(any())
.mockResolvedValue([sendView("1", "Test Send")]);
sendService = new SendService(cryptoService, i18nService, cryptoFunctionService, stateService);
});
afterEach(() => {
activeAccount.complete();
activeAccountUnlocked.complete();
});
describe("get", () => {
it("exists", async () => {
const result = sendService.get("1");
expect(result).toEqual(send("1", "Test Send"));
});
it("does not exist", async () => {
const result = sendService.get("2");
expect(result).toBe(undefined);
});
});
it("getAll", async () => {
const sends = await sendService.getAll();
const send1 = sends[0];
expect(sends).toHaveLength(1);
expect(send1).toEqual(send("1", "Test Send"));
});
describe("getFromState", () => {
it("exists", async () => {
const result = await sendService.getFromState("1");
expect(result).toEqual(send("1", "Test Send"));
});
it("does not exist", async () => {
const result = await sendService.getFromState("2");
expect(result).toBe(null);
});
});
it("getAllDecryptedFromState", async () => {
await sendService.getAllDecryptedFromState();
expect(stateService.getDecryptedSends).toHaveBeenCalledTimes(1);
});
// InternalSendService
it("upsert", async () => {
await sendService.upsert(sendData("2", "Test 2"));
expect(await firstValueFrom(sendService.sends$)).toEqual([
send("1", "Test Send"),
send("2", "Test 2"),
]);
});
it("replace", async () => {
await sendService.replace({ "2": sendData("2", "test 2") });
expect(await firstValueFrom(sendService.sends$)).toEqual([send("2", "test 2")]);
});
it("clear", async () => {
await sendService.clear();
expect(await firstValueFrom(sendService.sends$)).toEqual([]);
});
describe("delete", () => {
it("exists", async () => {
await sendService.delete("1");
expect(stateService.getEncryptedSends).toHaveBeenCalledTimes(2);
expect(stateService.setEncryptedSends).toHaveBeenCalledTimes(1);
});
it("does not exist", async () => {
sendService.delete("1");
expect(stateService.getEncryptedSends).toHaveBeenCalledTimes(2);
});
});
// Send object helper functions
function sendData(id: string, name: string) {
const data = new SendData({} as any);
data.id = id;
data.name = name;
data.disabled = false;
data.accessCount = 2;
data.accessId = "1";
data.revisionDate = null;
data.expirationDate = null;
data.deletionDate = null;
data.notes = "Notes!!";
data.key = null;
return data;
}
function sendView(id: string, name: string) {
const data = new SendView({} as any);
data.id = id;
data.name = name;
data.disabled = false;
data.accessCount = 2;
data.accessId = "1";
data.revisionDate = null;
data.expirationDate = null;
data.deletionDate = null;
data.notes = "Notes!!";
data.key = null;
return data;
}
function send(id: string, name: string) {
const data = new Send({} as any);
data.id = id;
data.name = new EncString(name);
data.disabled = false;
data.accessCount = 2;
data.accessId = "1";
data.revisionDate = null;
data.expirationDate = null;
data.deletionDate = null;
data.notes = new EncString("Notes!!");
data.key = null;
return data;
}
});

View File

@@ -1,21 +1,22 @@
import { BehaviorSubject, concatMap } from "rxjs";
import { CryptoService } from "../../abstractions/crypto.service";
import { CryptoFunctionService } from "../../abstractions/cryptoFunction.service";
import { I18nService } from "../../abstractions/i18n.service";
import { InternalSendService as InternalSendServiceAbstraction } from "../../abstractions/send/send.service.abstraction";
import { StateService } from "../../abstractions/state.service";
import { SEND_KDF_ITERATIONS } from "../../enums/kdfType";
import { SendType } from "../../enums/sendType";
import { Utils } from "../../misc/utils";
import { SendData } from "../../models/data/send.data";
import { EncArrayBuffer } from "../../models/domain/enc-array-buffer";
import { EncString } from "../../models/domain/enc-string";
import { Send } from "../../models/domain/send";
import { SendFile } from "../../models/domain/send-file";
import { SendText } from "../../models/domain/send-text";
import { SymmetricCryptoKey } from "../../models/domain/symmetric-crypto-key";
import { SendView } from "../../models/view/send.view";
import { CryptoService } from "../../../abstractions/crypto.service";
import { CryptoFunctionService } from "../../../abstractions/cryptoFunction.service";
import { I18nService } from "../../../abstractions/i18n.service";
import { StateService } from "../../../abstractions/state.service";
import { SEND_KDF_ITERATIONS } from "../../../enums/kdfType";
import { Utils } from "../../../misc/utils";
import { EncArrayBuffer } from "../../../models/domain/enc-array-buffer";
import { EncString } from "../../../models/domain/enc-string";
import { SymmetricCryptoKey } from "../../../models/domain/symmetric-crypto-key";
import { SendType } from "../enums/send-type";
import { SendData } from "../models/data/send.data";
import { Send } from "../models/domain/send";
import { SendFile } from "../models/domain/send-file";
import { SendText } from "../models/domain/send-text";
import { SendView } from "../models/view/send.view";
import { InternalSendService as InternalSendServiceAbstraction } from "./send.service.abstraction";
export class SendService implements InternalSendServiceAbstraction {
protected _sends: BehaviorSubject<Send[]> = new BehaviorSubject([]);

View File

@@ -3,7 +3,7 @@ import { PolicyResponse } from "../../../admin-console/models/response/policy.re
import { BaseResponse } from "../../../models/response/base.response";
import { DomainsResponse } from "../../../models/response/domains.response";
import { ProfileResponse } from "../../../models/response/profile.response";
import { SendResponse } from "../../../models/response/send.response";
import { SendResponse } from "../../../tools/send/models/response/send.response";
import { CipherResponse } from "./cipher.response";
import { FolderResponse } from "./folder.response";

View File

@@ -2,8 +2,6 @@ import { ApiService } from "../../../abstractions/api.service";
import { CryptoService } from "../../../abstractions/crypto.service";
import { LogService } from "../../../abstractions/log.service";
import { MessagingService } from "../../../abstractions/messaging.service";
import { SendApiService } from "../../../abstractions/send/send-api.service.abstraction";
import { InternalSendService } from "../../../abstractions/send/send.service.abstraction";
import { SettingsService } from "../../../abstractions/settings.service";
import { StateService } from "../../../abstractions/state.service";
import { CollectionService } from "../../../admin-console/abstractions/collection.service";
@@ -18,7 +16,6 @@ import { CollectionDetailsResponse } from "../../../admin-console/models/respons
import { PolicyResponse } from "../../../admin-console/models/response/policy.response";
import { KeyConnectorService } from "../../../auth/abstractions/key-connector.service";
import { sequentialize } from "../../../misc/sequentialize";
import { SendData } from "../../../models/data/send.data";
import { DomainsResponse } from "../../../models/response/domains.response";
import {
SyncCipherNotification,
@@ -26,7 +23,10 @@ import {
SyncSendNotification,
} from "../../../models/response/notification.response";
import { ProfileResponse } from "../../../models/response/profile.response";
import { SendResponse } from "../../../models/response/send.response";
import { SendData } from "../../../tools/send/models/data/send.data";
import { SendResponse } from "../../../tools/send/models/response/send.response";
import { SendApiService } from "../../../tools/send/services/send-api.service.abstraction";
import { InternalSendService } from "../../../tools/send/services/send.service.abstraction";
import { CipherService } from "../../../vault/abstractions/cipher.service";
import { FolderApiServiceAbstraction } from "../../../vault/abstractions/folder/folder-api.service.abstraction";
import { InternalFolderService } from "../../../vault/abstractions/folder/folder.service.abstraction";