diff --git a/jslib/angular/jest.config.js b/jslib/angular/jest.config.js deleted file mode 100644 index 19d250fc..00000000 --- a/jslib/angular/jest.config.js +++ /dev/null @@ -1,17 +0,0 @@ -const { pathsToModuleNameMapper } = require("ts-jest/utils"); - -const { compilerOptions } = require("./tsconfig"); - -module.exports = { - name: "angular", - displayName: "angular tests", - preset: "jest-preset-angular", - testMatch: ["**/+(*.)+(spec).+(ts)"], - setupFilesAfterEnv: ["/spec/test.ts"], - collectCoverage: true, - coverageReporters: ["html", "lcov"], - coverageDirectory: "coverage", - moduleNameMapper: pathsToModuleNameMapper(compilerOptions?.paths || {}, { - prefix: "/", - }), -}; diff --git a/jslib/angular/spec/test.ts b/jslib/angular/spec/test.ts deleted file mode 100644 index 6be6e7b8..00000000 --- a/jslib/angular/spec/test.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { webcrypto } from "crypto"; -import "jest-preset-angular/setup-jest"; - -Object.defineProperty(window, "CSS", { value: null }); -Object.defineProperty(window, "getComputedStyle", { - value: () => { - return { - display: "none", - appearance: ["-webkit-appearance"], - }; - }, -}); - -Object.defineProperty(document, "doctype", { - value: "", -}); -Object.defineProperty(document.body.style, "transform", { - value: () => { - return { - enumerable: true, - configurable: true, - }; - }, -}); - -Object.defineProperty(window, "crypto", { - value: webcrypto, -}); diff --git a/jslib/common/jest.config.js b/jslib/common/jest.config.js deleted file mode 100644 index 76856611..00000000 --- a/jslib/common/jest.config.js +++ /dev/null @@ -1,18 +0,0 @@ -const { pathsToModuleNameMapper } = require("ts-jest/utils"); - -const { compilerOptions } = require("./tsconfig"); - -module.exports = { - name: "common", - displayName: "common jslib tests", - preset: "ts-jest", - testEnvironment: "jsdom", - testMatch: ["**/+(*.)+(spec).+(ts)"], - setupFilesAfterEnv: ["/spec/test.ts"], - collectCoverage: true, - coverageReporters: ["html", "lcov"], - coverageDirectory: "coverage", - moduleNameMapper: pathsToModuleNameMapper(compilerOptions?.paths || {}, { - prefix: "/", - }), -}; diff --git a/jslib/common/spec/domain/attachment.spec.ts b/jslib/common/spec/domain/attachment.spec.ts deleted file mode 100644 index 318a2a80..00000000 --- a/jslib/common/spec/domain/attachment.spec.ts +++ /dev/null @@ -1,83 +0,0 @@ -import Substitute, { Arg } from "@fluffy-spoon/substitute"; - -import { CryptoService } from "@/jslib/common/src/abstractions/crypto.service"; -import { AttachmentData } from "@/jslib/common/src/models/data/attachmentData"; -import { Attachment } from "@/jslib/common/src/models/domain/attachment"; -import { SymmetricCryptoKey } from "@/jslib/common/src/models/domain/symmetricCryptoKey"; -import { ContainerService } from "@/jslib/common/src/services/container.service"; - -import { makeStaticByteArray, mockEnc } from "../utils"; - -describe("Attachment", () => { - let data: AttachmentData; - - beforeEach(() => { - data = { - id: "id", - url: "url", - fileName: "fileName", - key: "key", - size: "1100", - sizeName: "1.1 KB", - }; - }); - - it("Convert from empty", () => { - const data = new AttachmentData(); - const attachment = new Attachment(data); - - expect(attachment).toEqual({ - id: null, - url: null, - size: undefined, - sizeName: null, - key: null, - fileName: null, - }); - }); - - it("Convert", () => { - const attachment = new Attachment(data); - - expect(attachment).toEqual({ - size: "1100", - id: "id", - url: "url", - sizeName: "1.1 KB", - fileName: { encryptedString: "fileName", encryptionType: 0 }, - key: { encryptedString: "key", encryptionType: 0 }, - }); - }); - - it("toAttachmentData", () => { - const attachment = new Attachment(data); - expect(attachment.toAttachmentData()).toEqual(data); - }); - - it("Decrypt", async () => { - const attachment = new Attachment(); - attachment.id = "id"; - attachment.url = "url"; - attachment.size = "1100"; - attachment.sizeName = "1.1 KB"; - attachment.key = mockEnc("key"); - attachment.fileName = mockEnc("fileName"); - - const cryptoService = Substitute.for(); - cryptoService.getOrgKey(null).resolves(null); - cryptoService.decryptToBytes(Arg.any(), Arg.any()).resolves(makeStaticByteArray(32)); - - (window as any).bitwardenContainerService = new ContainerService(cryptoService); - - const view = await attachment.decrypt(null); - - expect(view).toEqual({ - id: "id", - url: "url", - size: "1100", - sizeName: "1.1 KB", - fileName: "fileName", - key: expect.any(SymmetricCryptoKey), - }); - }); -}); diff --git a/jslib/common/spec/domain/card.spec.ts b/jslib/common/spec/domain/card.spec.ts deleted file mode 100644 index ca41084b..00000000 --- a/jslib/common/spec/domain/card.spec.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { CardData } from "@/jslib/common/src/models/data/cardData"; -import { Card } from "@/jslib/common/src/models/domain/card"; - -import { mockEnc } from "../utils"; - -describe("Card", () => { - let data: CardData; - - beforeEach(() => { - data = { - cardholderName: "encHolder", - brand: "encBrand", - number: "encNumber", - expMonth: "encMonth", - expYear: "encYear", - code: "encCode", - }; - }); - - it("Convert from empty", () => { - const data = new CardData(); - const card = new Card(data); - - expect(card).toEqual({ - cardholderName: null, - brand: null, - number: null, - expMonth: null, - expYear: null, - code: null, - }); - }); - - it("Convert", () => { - const card = new Card(data); - - expect(card).toEqual({ - cardholderName: { encryptedString: "encHolder", encryptionType: 0 }, - brand: { encryptedString: "encBrand", encryptionType: 0 }, - number: { encryptedString: "encNumber", encryptionType: 0 }, - expMonth: { encryptedString: "encMonth", encryptionType: 0 }, - expYear: { encryptedString: "encYear", encryptionType: 0 }, - code: { encryptedString: "encCode", encryptionType: 0 }, - }); - }); - - it("toCardData", () => { - const card = new Card(data); - expect(card.toCardData()).toEqual(data); - }); - - it("Decrypt", async () => { - const card = new Card(); - card.cardholderName = mockEnc("cardHolder"); - card.brand = mockEnc("brand"); - card.number = mockEnc("number"); - card.expMonth = mockEnc("expMonth"); - card.expYear = mockEnc("expYear"); - card.code = mockEnc("code"); - - const view = await card.decrypt(null); - - expect(view).toEqual({ - _brand: "brand", - _number: "number", - _subTitle: null, - cardholderName: "cardHolder", - code: "code", - expMonth: "expMonth", - expYear: "expYear", - }); - }); -}); diff --git a/jslib/common/spec/domain/cipher.spec.ts b/jslib/common/spec/domain/cipher.spec.ts deleted file mode 100644 index 936cc08a..00000000 --- a/jslib/common/spec/domain/cipher.spec.ts +++ /dev/null @@ -1,599 +0,0 @@ -import Substitute, { Arg } from "@fluffy-spoon/substitute"; - -import { CipherRepromptType } from "@/jslib/common/src/enums/cipherRepromptType"; -import { CipherType } from "@/jslib/common/src/enums/cipherType"; -import { FieldType } from "@/jslib/common/src/enums/fieldType"; -import { SecureNoteType } from "@/jslib/common/src/enums/secureNoteType"; -import { UriMatchType } from "@/jslib/common/src/enums/uriMatchType"; -import { CipherData } from "@/jslib/common/src/models/data/cipherData"; -import { Card } from "@/jslib/common/src/models/domain/card"; -import { Cipher } from "@/jslib/common/src/models/domain/cipher"; -import { Identity } from "@/jslib/common/src/models/domain/identity"; -import { Login } from "@/jslib/common/src/models/domain/login"; -import { SecureNote } from "@/jslib/common/src/models/domain/secureNote"; -import { CardView } from "@/jslib/common/src/models/view/cardView"; -import { IdentityView } from "@/jslib/common/src/models/view/identityView"; -import { LoginView } from "@/jslib/common/src/models/view/loginView"; - -import { mockEnc } from "../utils"; - -describe("Cipher DTO", () => { - it("Convert from empty CipherData", () => { - const data = new CipherData(); - const cipher = new Cipher(data); - - expect(cipher).toEqual({ - id: null, - userId: null, - organizationId: null, - folderId: null, - name: null, - notes: null, - type: undefined, - favorite: undefined, - organizationUseTotp: undefined, - edit: undefined, - viewPassword: true, - revisionDate: null, - collectionIds: undefined, - localData: null, - deletedDate: null, - reprompt: undefined, - attachments: null, - fields: null, - passwordHistory: null, - }); - }); - - describe("LoginCipher", () => { - let cipherData: CipherData; - - beforeEach(() => { - cipherData = { - id: "id", - organizationId: "orgId", - folderId: "folderId", - userId: "userId", - edit: true, - viewPassword: true, - organizationUseTotp: true, - favorite: false, - revisionDate: "2022-01-31T12:00:00.000Z", - type: CipherType.Login, - name: "EncryptedString", - notes: "EncryptedString", - deletedDate: null, - reprompt: CipherRepromptType.None, - login: { - uris: [{ uri: "EncryptedString", match: UriMatchType.Domain }], - username: "EncryptedString", - password: "EncryptedString", - passwordRevisionDate: "2022-01-31T12:00:00.000Z", - totp: "EncryptedString", - autofillOnPageLoad: false, - }, - passwordHistory: [ - { password: "EncryptedString", lastUsedDate: "2022-01-31T12:00:00.000Z" }, - ], - attachments: [ - { - id: "a1", - url: "url", - size: "1100", - sizeName: "1.1 KB", - fileName: "file", - key: "EncKey", - }, - { - id: "a2", - url: "url", - size: "1100", - sizeName: "1.1 KB", - fileName: "file", - key: "EncKey", - }, - ], - fields: [ - { - name: "EncryptedString", - value: "EncryptedString", - type: FieldType.Text, - linkedId: null, - }, - { - name: "EncryptedString", - value: "EncryptedString", - type: FieldType.Hidden, - linkedId: null, - }, - ], - }; - }); - - it("Convert", () => { - const cipher = new Cipher(cipherData); - - expect(cipher).toEqual({ - id: "id", - userId: "userId", - organizationId: "orgId", - folderId: "folderId", - name: { encryptedString: "EncryptedString", encryptionType: 0 }, - notes: { encryptedString: "EncryptedString", encryptionType: 0 }, - type: 1, - favorite: false, - organizationUseTotp: true, - edit: true, - viewPassword: true, - revisionDate: new Date("2022-01-31T12:00:00.000Z"), - collectionIds: undefined, - localData: null, - deletedDate: null, - reprompt: 0, - login: { - passwordRevisionDate: new Date("2022-01-31T12:00:00.000Z"), - autofillOnPageLoad: false, - username: { encryptedString: "EncryptedString", encryptionType: 0 }, - password: { encryptedString: "EncryptedString", encryptionType: 0 }, - totp: { encryptedString: "EncryptedString", encryptionType: 0 }, - uris: [{ match: 0, uri: { encryptedString: "EncryptedString", encryptionType: 0 } }], - }, - attachments: [ - { - fileName: { encryptedString: "file", encryptionType: 0 }, - id: "a1", - key: { encryptedString: "EncKey", encryptionType: 0 }, - size: "1100", - sizeName: "1.1 KB", - url: "url", - }, - { - fileName: { encryptedString: "file", encryptionType: 0 }, - id: "a2", - key: { encryptedString: "EncKey", encryptionType: 0 }, - size: "1100", - sizeName: "1.1 KB", - url: "url", - }, - ], - fields: [ - { - linkedId: null, - name: { encryptedString: "EncryptedString", encryptionType: 0 }, - type: 0, - value: { encryptedString: "EncryptedString", encryptionType: 0 }, - }, - { - linkedId: null, - name: { encryptedString: "EncryptedString", encryptionType: 0 }, - type: 1, - value: { encryptedString: "EncryptedString", encryptionType: 0 }, - }, - ], - passwordHistory: [ - { - lastUsedDate: new Date("2022-01-31T12:00:00.000Z"), - password: { encryptedString: "EncryptedString", encryptionType: 0 }, - }, - ], - }); - }); - - it("toCipherData", () => { - const cipher = new Cipher(cipherData); - expect(cipher.toCipherData("userId")).toEqual(cipherData); - }); - - it("Decrypt", async () => { - const cipher = new Cipher(); - cipher.id = "id"; - cipher.organizationId = "orgId"; - cipher.folderId = "folderId"; - cipher.edit = true; - cipher.viewPassword = true; - cipher.organizationUseTotp = true; - cipher.favorite = false; - cipher.revisionDate = new Date("2022-01-31T12:00:00.000Z"); - cipher.type = CipherType.Login; - cipher.name = mockEnc("EncryptedString"); - cipher.notes = mockEnc("EncryptedString"); - cipher.deletedDate = null; - cipher.reprompt = CipherRepromptType.None; - - const loginView = new LoginView(); - loginView.username = "username"; - loginView.password = "password"; - - const login = Substitute.for(); - login.decrypt(Arg.any(), Arg.any()).resolves(loginView); - cipher.login = login; - - const cipherView = await cipher.decrypt(); - - expect(cipherView).toMatchObject({ - id: "id", - organizationId: "orgId", - folderId: "folderId", - name: "EncryptedString", - notes: "EncryptedString", - type: 1, - favorite: false, - organizationUseTotp: true, - edit: true, - viewPassword: true, - login: loginView, - attachments: null, - fields: null, - passwordHistory: null, - collectionIds: undefined, - revisionDate: new Date("2022-01-31T12:00:00.000Z"), - deletedDate: null, - reprompt: 0, - localData: undefined, - }); - }); - }); - - describe("SecureNoteCipher", () => { - let cipherData: CipherData; - - beforeEach(() => { - cipherData = { - id: "id", - organizationId: "orgId", - folderId: "folderId", - userId: "userId", - edit: true, - viewPassword: true, - organizationUseTotp: true, - favorite: false, - revisionDate: "2022-01-31T12:00:00.000Z", - type: CipherType.SecureNote, - name: "EncryptedString", - notes: "EncryptedString", - deletedDate: null, - reprompt: CipherRepromptType.None, - secureNote: { - type: SecureNoteType.Generic, - }, - }; - }); - - it("Convert", () => { - const cipher = new Cipher(cipherData); - - expect(cipher).toEqual({ - id: "id", - userId: "userId", - organizationId: "orgId", - folderId: "folderId", - name: { encryptedString: "EncryptedString", encryptionType: 0 }, - notes: { encryptedString: "EncryptedString", encryptionType: 0 }, - type: 2, - favorite: false, - organizationUseTotp: true, - edit: true, - viewPassword: true, - revisionDate: new Date("2022-01-31T12:00:00.000Z"), - collectionIds: undefined, - localData: null, - deletedDate: null, - reprompt: 0, - secureNote: { type: SecureNoteType.Generic }, - attachments: null, - fields: null, - passwordHistory: null, - }); - }); - - it("toCipherData", () => { - const cipher = new Cipher(cipherData); - expect(cipher.toCipherData("userId")).toEqual(cipherData); - }); - - it("Decrypt", async () => { - const cipher = new Cipher(); - cipher.id = "id"; - cipher.organizationId = "orgId"; - cipher.folderId = "folderId"; - cipher.edit = true; - cipher.viewPassword = true; - cipher.organizationUseTotp = true; - cipher.favorite = false; - cipher.revisionDate = new Date("2022-01-31T12:00:00.000Z"); - cipher.type = CipherType.SecureNote; - cipher.name = mockEnc("EncryptedString"); - cipher.notes = mockEnc("EncryptedString"); - cipher.deletedDate = null; - cipher.reprompt = CipherRepromptType.None; - cipher.secureNote = new SecureNote(); - cipher.secureNote.type = SecureNoteType.Generic; - - const cipherView = await cipher.decrypt(); - - expect(cipherView).toMatchObject({ - id: "id", - organizationId: "orgId", - folderId: "folderId", - name: "EncryptedString", - notes: "EncryptedString", - type: 2, - favorite: false, - organizationUseTotp: true, - edit: true, - viewPassword: true, - secureNote: { type: 0 }, - attachments: null, - fields: null, - passwordHistory: null, - collectionIds: undefined, - revisionDate: new Date("2022-01-31T12:00:00.000Z"), - deletedDate: null, - reprompt: 0, - localData: undefined, - }); - }); - }); - - describe("CardCipher", () => { - let cipherData: CipherData; - - beforeEach(() => { - cipherData = { - id: "id", - organizationId: "orgId", - folderId: "folderId", - userId: "userId", - edit: true, - viewPassword: true, - organizationUseTotp: true, - favorite: false, - revisionDate: "2022-01-31T12:00:00.000Z", - type: CipherType.Card, - name: "EncryptedString", - notes: "EncryptedString", - deletedDate: null, - reprompt: CipherRepromptType.None, - card: { - cardholderName: "EncryptedString", - brand: "EncryptedString", - number: "EncryptedString", - expMonth: "EncryptedString", - expYear: "EncryptedString", - code: "EncryptedString", - }, - }; - }); - - it("Convert", () => { - const cipher = new Cipher(cipherData); - - expect(cipher).toEqual({ - id: "id", - userId: "userId", - organizationId: "orgId", - folderId: "folderId", - name: { encryptedString: "EncryptedString", encryptionType: 0 }, - notes: { encryptedString: "EncryptedString", encryptionType: 0 }, - type: 3, - favorite: false, - organizationUseTotp: true, - edit: true, - viewPassword: true, - revisionDate: new Date("2022-01-31T12:00:00.000Z"), - collectionIds: undefined, - localData: null, - deletedDate: null, - reprompt: 0, - card: { - cardholderName: { encryptedString: "EncryptedString", encryptionType: 0 }, - brand: { encryptedString: "EncryptedString", encryptionType: 0 }, - number: { encryptedString: "EncryptedString", encryptionType: 0 }, - expMonth: { encryptedString: "EncryptedString", encryptionType: 0 }, - expYear: { encryptedString: "EncryptedString", encryptionType: 0 }, - code: { encryptedString: "EncryptedString", encryptionType: 0 }, - }, - attachments: null, - fields: null, - passwordHistory: null, - }); - }); - - it("toCipherData", () => { - const cipher = new Cipher(cipherData); - expect(cipher.toCipherData("userId")).toEqual(cipherData); - }); - - it("Decrypt", async () => { - const cipher = new Cipher(); - cipher.id = "id"; - cipher.organizationId = "orgId"; - cipher.folderId = "folderId"; - cipher.edit = true; - cipher.viewPassword = true; - cipher.organizationUseTotp = true; - cipher.favorite = false; - cipher.revisionDate = new Date("2022-01-31T12:00:00.000Z"); - cipher.type = CipherType.Card; - cipher.name = mockEnc("EncryptedString"); - cipher.notes = mockEnc("EncryptedString"); - cipher.deletedDate = null; - cipher.reprompt = CipherRepromptType.None; - - const cardView = new CardView(); - cardView.cardholderName = "cardholderName"; - cardView.number = "4111111111111111"; - - const card = Substitute.for(); - card.decrypt(Arg.any(), Arg.any()).resolves(cardView); - cipher.card = card; - - const cipherView = await cipher.decrypt(); - - expect(cipherView).toMatchObject({ - id: "id", - organizationId: "orgId", - folderId: "folderId", - name: "EncryptedString", - notes: "EncryptedString", - type: 3, - favorite: false, - organizationUseTotp: true, - edit: true, - viewPassword: true, - card: cardView, - attachments: null, - fields: null, - passwordHistory: null, - collectionIds: undefined, - revisionDate: new Date("2022-01-31T12:00:00.000Z"), - deletedDate: null, - reprompt: 0, - localData: undefined, - }); - }); - }); - - describe("IdentityCipher", () => { - let cipherData: CipherData; - - beforeEach(() => { - cipherData = { - id: "id", - organizationId: "orgId", - folderId: "folderId", - userId: "userId", - edit: true, - viewPassword: true, - organizationUseTotp: true, - favorite: false, - revisionDate: "2022-01-31T12:00:00.000Z", - type: CipherType.Identity, - name: "EncryptedString", - notes: "EncryptedString", - deletedDate: null, - reprompt: CipherRepromptType.None, - identity: { - title: "EncryptedString", - firstName: "EncryptedString", - middleName: "EncryptedString", - lastName: "EncryptedString", - address1: "EncryptedString", - address2: "EncryptedString", - address3: "EncryptedString", - city: "EncryptedString", - state: "EncryptedString", - postalCode: "EncryptedString", - country: "EncryptedString", - company: "EncryptedString", - email: "EncryptedString", - phone: "EncryptedString", - ssn: "EncryptedString", - username: "EncryptedString", - passportNumber: "EncryptedString", - licenseNumber: "EncryptedString", - }, - }; - }); - - it("Convert", () => { - const cipher = new Cipher(cipherData); - - expect(cipher).toEqual({ - id: "id", - userId: "userId", - organizationId: "orgId", - folderId: "folderId", - name: { encryptedString: "EncryptedString", encryptionType: 0 }, - notes: { encryptedString: "EncryptedString", encryptionType: 0 }, - type: 4, - favorite: false, - organizationUseTotp: true, - edit: true, - viewPassword: true, - revisionDate: new Date("2022-01-31T12:00:00.000Z"), - collectionIds: undefined, - localData: null, - deletedDate: null, - reprompt: 0, - identity: { - title: { encryptedString: "EncryptedString", encryptionType: 0 }, - firstName: { encryptedString: "EncryptedString", encryptionType: 0 }, - middleName: { encryptedString: "EncryptedString", encryptionType: 0 }, - lastName: { encryptedString: "EncryptedString", encryptionType: 0 }, - address1: { encryptedString: "EncryptedString", encryptionType: 0 }, - address2: { encryptedString: "EncryptedString", encryptionType: 0 }, - address3: { encryptedString: "EncryptedString", encryptionType: 0 }, - city: { encryptedString: "EncryptedString", encryptionType: 0 }, - state: { encryptedString: "EncryptedString", encryptionType: 0 }, - postalCode: { encryptedString: "EncryptedString", encryptionType: 0 }, - country: { encryptedString: "EncryptedString", encryptionType: 0 }, - company: { encryptedString: "EncryptedString", encryptionType: 0 }, - email: { encryptedString: "EncryptedString", encryptionType: 0 }, - phone: { encryptedString: "EncryptedString", encryptionType: 0 }, - ssn: { encryptedString: "EncryptedString", encryptionType: 0 }, - username: { encryptedString: "EncryptedString", encryptionType: 0 }, - passportNumber: { encryptedString: "EncryptedString", encryptionType: 0 }, - licenseNumber: { encryptedString: "EncryptedString", encryptionType: 0 }, - }, - attachments: null, - fields: null, - passwordHistory: null, - }); - }); - - it("toCipherData", () => { - const cipher = new Cipher(cipherData); - expect(cipher.toCipherData("userId")).toEqual(cipherData); - }); - - it("Decrypt", async () => { - const cipher = new Cipher(); - cipher.id = "id"; - cipher.organizationId = "orgId"; - cipher.folderId = "folderId"; - cipher.edit = true; - cipher.viewPassword = true; - cipher.organizationUseTotp = true; - cipher.favorite = false; - cipher.revisionDate = new Date("2022-01-31T12:00:00.000Z"); - cipher.type = CipherType.Identity; - cipher.name = mockEnc("EncryptedString"); - cipher.notes = mockEnc("EncryptedString"); - cipher.deletedDate = null; - cipher.reprompt = CipherRepromptType.None; - - const identityView = new IdentityView(); - identityView.firstName = "firstName"; - identityView.lastName = "lastName"; - - const identity = Substitute.for(); - identity.decrypt(Arg.any(), Arg.any()).resolves(identityView); - cipher.identity = identity; - - const cipherView = await cipher.decrypt(); - - expect(cipherView).toMatchObject({ - id: "id", - organizationId: "orgId", - folderId: "folderId", - name: "EncryptedString", - notes: "EncryptedString", - type: 4, - favorite: false, - organizationUseTotp: true, - edit: true, - viewPassword: true, - identity: identityView, - attachments: null, - fields: null, - passwordHistory: null, - collectionIds: undefined, - revisionDate: new Date("2022-01-31T12:00:00.000Z"), - deletedDate: null, - reprompt: 0, - localData: undefined, - }); - }); - }); -}); diff --git a/jslib/common/spec/domain/collection.spec.ts b/jslib/common/spec/domain/collection.spec.ts deleted file mode 100644 index e5cf1d66..00000000 --- a/jslib/common/spec/domain/collection.spec.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { CollectionData } from "@/jslib/common/src/models/data/collectionData"; -import { Collection } from "@/jslib/common/src/models/domain/collection"; - -import { mockEnc } from "../utils"; - -describe("Collection", () => { - let data: CollectionData; - - beforeEach(() => { - data = { - id: "id", - organizationId: "orgId", - name: "encName", - externalId: "extId", - readOnly: true, - }; - }); - - it("Convert from empty", () => { - const data = new CollectionData({} as any); - const card = new Collection(data); - - expect(card).toEqual({ - externalId: null, - hidePasswords: null, - id: null, - name: null, - organizationId: null, - readOnly: null, - }); - }); - - it("Convert", () => { - const collection = new Collection(data); - - expect(collection).toEqual({ - id: "id", - organizationId: "orgId", - name: { encryptedString: "encName", encryptionType: 0 }, - externalId: "extId", - readOnly: true, - hidePasswords: null, - }); - }); - - it("Decrypt", async () => { - const collection = new Collection(); - collection.id = "id"; - collection.organizationId = "orgId"; - collection.name = mockEnc("encName"); - collection.externalId = "extId"; - collection.readOnly = false; - collection.hidePasswords = false; - - const view = await collection.decrypt(); - - expect(view).toEqual({ - externalId: "extId", - hidePasswords: false, - id: "id", - name: "encName", - organizationId: "orgId", - readOnly: false, - }); - }); -}); diff --git a/jslib/common/spec/domain/encString.spec.ts b/jslib/common/spec/domain/encString.spec.ts deleted file mode 100644 index 8caaaf87..00000000 --- a/jslib/common/spec/domain/encString.spec.ts +++ /dev/null @@ -1,195 +0,0 @@ -import Substitute, { Arg } from "@fluffy-spoon/substitute"; - -import { CryptoService } from "@/jslib/common/src/abstractions/crypto.service"; -import { EncryptionType } from "@/jslib/common/src/enums/encryptionType"; -import { EncString } from "@/jslib/common/src/models/domain/encString"; -import { SymmetricCryptoKey } from "@/jslib/common/src/models/domain/symmetricCryptoKey"; -import { ContainerService } from "@/jslib/common/src/services/container.service"; - -describe("EncString", () => { - afterEach(() => { - (window as any).bitwardenContainerService = undefined; - }); - - describe("Rsa2048_OaepSha256_B64", () => { - it("constructor", () => { - const encString = new EncString(EncryptionType.Rsa2048_OaepSha256_B64, "data"); - - expect(encString).toEqual({ - data: "data", - encryptedString: "3.data", - encryptionType: 3, - }); - }); - - describe("parse existing", () => { - it("valid", () => { - const encString = new EncString("3.data"); - - expect(encString).toEqual({ - data: "data", - encryptedString: "3.data", - encryptionType: 3, - }); - }); - - it("invalid", () => { - const encString = new EncString("3.data|test"); - - expect(encString).toEqual({ - encryptedString: "3.data|test", - encryptionType: 3, - }); - }); - }); - - describe("decrypt", () => { - const encString = new EncString(EncryptionType.Rsa2048_OaepSha256_B64, "data"); - - const cryptoService = Substitute.for(); - cryptoService.getOrgKey(null).resolves(null); - cryptoService.decryptToUtf8(encString, Arg.any()).resolves("decrypted"); - - beforeEach(() => { - (window as any).bitwardenContainerService = new ContainerService(cryptoService); - }); - - it("decrypts correctly", async () => { - const decrypted = await encString.decrypt(null); - - expect(decrypted).toBe("decrypted"); - }); - - it("result should be cached", async () => { - const decrypted = await encString.decrypt(null); - cryptoService.received(1).decryptToUtf8(Arg.any(), Arg.any()); - - expect(decrypted).toBe("decrypted"); - }); - }); - }); - - describe("AesCbc256_B64", () => { - it("constructor", () => { - const encString = new EncString(EncryptionType.AesCbc256_B64, "data", "iv"); - - expect(encString).toEqual({ - data: "data", - encryptedString: "0.iv|data", - encryptionType: 0, - iv: "iv", - }); - }); - - describe("parse existing", () => { - it("valid", () => { - const encString = new EncString("0.iv|data"); - - expect(encString).toEqual({ - data: "data", - encryptedString: "0.iv|data", - encryptionType: 0, - iv: "iv", - }); - }); - - it("invalid", () => { - const encString = new EncString("0.iv|data|mac"); - - expect(encString).toEqual({ - encryptedString: "0.iv|data|mac", - encryptionType: 0, - }); - }); - }); - }); - - describe("AesCbc256_HmacSha256_B64", () => { - it("constructor", () => { - const encString = new EncString(EncryptionType.AesCbc256_HmacSha256_B64, "data", "iv", "mac"); - - expect(encString).toEqual({ - data: "data", - encryptedString: "2.iv|data|mac", - encryptionType: 2, - iv: "iv", - mac: "mac", - }); - }); - - it("valid", () => { - const encString = new EncString("2.iv|data|mac"); - - expect(encString).toEqual({ - data: "data", - encryptedString: "2.iv|data|mac", - encryptionType: 2, - iv: "iv", - mac: "mac", - }); - }); - - it("invalid", () => { - const encString = new EncString("2.iv|data"); - - expect(encString).toEqual({ - encryptedString: "2.iv|data", - encryptionType: 2, - }); - }); - }); - - it("Exit early if null", () => { - const encString = new EncString(null); - - expect(encString).toEqual({ - encryptedString: null, - }); - }); - - describe("decrypt", () => { - it("throws exception when bitwarden container not initialized", async () => { - const encString = new EncString(null); - - expect.assertions(1); - try { - await encString.decrypt(null); - } catch (e) { - expect(e.message).toEqual("global bitwardenContainerService not initialized."); - } - }); - - it("handles value it can't decrypt", async () => { - const encString = new EncString(null); - - const cryptoService = Substitute.for(); - cryptoService.getOrgKey(null).resolves(null); - cryptoService.decryptToUtf8(encString, Arg.any()).throws("error"); - - (window as any).bitwardenContainerService = new ContainerService(cryptoService); - - const decrypted = await encString.decrypt(null); - - expect(decrypted).toBe("[error: cannot decrypt]"); - - expect(encString).toEqual({ - decryptedValue: "[error: cannot decrypt]", - encryptedString: null, - }); - }); - - it("passes along key", async () => { - const encString = new EncString(null); - const key = Substitute.for(); - - const cryptoService = Substitute.for(); - cryptoService.getOrgKey(null).resolves(null); - - (window as any).bitwardenContainerService = new ContainerService(cryptoService); - - await encString.decrypt(null, key); - - cryptoService.received().decryptToUtf8(encString, key); - }); - }); -}); diff --git a/jslib/common/spec/domain/field.spec.ts b/jslib/common/spec/domain/field.spec.ts deleted file mode 100644 index 452b0cd9..00000000 --- a/jslib/common/spec/domain/field.spec.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { FieldType } from "@/jslib/common/src/enums/fieldType"; -import { FieldData } from "@/jslib/common/src/models/data/fieldData"; -import { Field } from "@/jslib/common/src/models/domain/field"; - -import { mockEnc } from "../utils"; - -describe("Field", () => { - let data: FieldData; - - beforeEach(() => { - data = { - type: FieldType.Text, - name: "encName", - value: "encValue", - linkedId: null, - }; - }); - - it("Convert from empty", () => { - const data = new FieldData(); - const field = new Field(data); - - expect(field).toEqual({ - type: undefined, - name: null, - value: null, - linkedId: undefined, - }); - }); - - it("Convert", () => { - const field = new Field(data); - - expect(field).toEqual({ - type: FieldType.Text, - name: { encryptedString: "encName", encryptionType: 0 }, - value: { encryptedString: "encValue", encryptionType: 0 }, - linkedId: null, - }); - }); - - it("toFieldData", () => { - const field = new Field(data); - expect(field.toFieldData()).toEqual(data); - }); - - it("Decrypt", async () => { - const field = new Field(); - field.type = FieldType.Text; - field.name = mockEnc("encName"); - field.value = mockEnc("encValue"); - - const view = await field.decrypt(null); - - expect(view).toEqual({ - type: 0, - name: "encName", - value: "encValue", - newField: false, - showCount: false, - showValue: false, - }); - }); -}); diff --git a/jslib/common/spec/domain/folder.spec.ts b/jslib/common/spec/domain/folder.spec.ts deleted file mode 100644 index dc22f829..00000000 --- a/jslib/common/spec/domain/folder.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { FolderData } from "@/jslib/common/src/models/data/folderData"; -import { Folder } from "@/jslib/common/src/models/domain/folder"; - -import { mockEnc } from "../utils"; - -describe("Folder", () => { - let data: FolderData; - - beforeEach(() => { - data = { - id: "id", - userId: "userId", - name: "encName", - revisionDate: "2022-01-31T12:00:00.000Z", - }; - }); - - it("Convert", () => { - const field = new Folder(data); - - expect(field).toEqual({ - id: "id", - name: { encryptedString: "encName", encryptionType: 0 }, - revisionDate: new Date("2022-01-31T12:00:00.000Z"), - }); - }); - - it("Decrypt", async () => { - const folder = new Folder(); - folder.id = "id"; - folder.name = mockEnc("encName"); - folder.revisionDate = new Date("2022-01-31T12:00:00.000Z"); - - const view = await folder.decrypt(); - - expect(view).toEqual({ - id: "id", - name: "encName", - revisionDate: new Date("2022-01-31T12:00:00.000Z"), - }); - }); -}); diff --git a/jslib/common/spec/domain/identity.spec.ts b/jslib/common/spec/domain/identity.spec.ts deleted file mode 100644 index f77459aa..00000000 --- a/jslib/common/spec/domain/identity.spec.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { IdentityData } from "@/jslib/common/src/models/data/identityData"; -import { Identity } from "@/jslib/common/src/models/domain/identity"; - -import { mockEnc } from "../utils"; - -describe("Identity", () => { - let data: IdentityData; - - beforeEach(() => { - data = { - title: "enctitle", - firstName: "encfirstName", - middleName: "encmiddleName", - lastName: "enclastName", - address1: "encaddress1", - address2: "encaddress2", - address3: "encaddress3", - city: "enccity", - state: "encstate", - postalCode: "encpostalCode", - country: "enccountry", - company: "enccompany", - email: "encemail", - phone: "encphone", - ssn: "encssn", - username: "encusername", - passportNumber: "encpassportNumber", - licenseNumber: "enclicenseNumber", - }; - }); - - it("Convert from empty", () => { - const data = new IdentityData(); - const identity = new Identity(data); - - expect(identity).toEqual({ - address1: null, - address2: null, - address3: null, - city: null, - company: null, - country: null, - email: null, - firstName: null, - lastName: null, - licenseNumber: null, - middleName: null, - passportNumber: null, - phone: null, - postalCode: null, - ssn: null, - state: null, - title: null, - username: null, - }); - }); - - it("Convert", () => { - const identity = new Identity(data); - - expect(identity).toEqual({ - title: { encryptedString: "enctitle", encryptionType: 0 }, - firstName: { encryptedString: "encfirstName", encryptionType: 0 }, - middleName: { encryptedString: "encmiddleName", encryptionType: 0 }, - lastName: { encryptedString: "enclastName", encryptionType: 0 }, - address1: { encryptedString: "encaddress1", encryptionType: 0 }, - address2: { encryptedString: "encaddress2", encryptionType: 0 }, - address3: { encryptedString: "encaddress3", encryptionType: 0 }, - city: { encryptedString: "enccity", encryptionType: 0 }, - state: { encryptedString: "encstate", encryptionType: 0 }, - postalCode: { encryptedString: "encpostalCode", encryptionType: 0 }, - country: { encryptedString: "enccountry", encryptionType: 0 }, - company: { encryptedString: "enccompany", encryptionType: 0 }, - email: { encryptedString: "encemail", encryptionType: 0 }, - phone: { encryptedString: "encphone", encryptionType: 0 }, - ssn: { encryptedString: "encssn", encryptionType: 0 }, - username: { encryptedString: "encusername", encryptionType: 0 }, - passportNumber: { encryptedString: "encpassportNumber", encryptionType: 0 }, - licenseNumber: { encryptedString: "enclicenseNumber", encryptionType: 0 }, - }); - }); - - it("toIdentityData", () => { - const identity = new Identity(data); - expect(identity.toIdentityData()).toEqual(data); - }); - - it("Decrypt", async () => { - const identity = new Identity(); - - identity.title = mockEnc("mockTitle"); - identity.firstName = mockEnc("mockFirstName"); - identity.middleName = mockEnc("mockMiddleName"); - identity.lastName = mockEnc("mockLastName"); - identity.address1 = mockEnc("mockAddress1"); - identity.address2 = mockEnc("mockAddress2"); - identity.address3 = mockEnc("mockAddress3"); - identity.city = mockEnc("mockCity"); - identity.state = mockEnc("mockState"); - identity.postalCode = mockEnc("mockPostalCode"); - identity.country = mockEnc("mockCountry"); - identity.company = mockEnc("mockCompany"); - identity.email = mockEnc("mockEmail"); - identity.phone = mockEnc("mockPhone"); - identity.ssn = mockEnc("mockSsn"); - identity.username = mockEnc("mockUsername"); - identity.passportNumber = mockEnc("mockPassportNumber"); - identity.licenseNumber = mockEnc("mockLicenseNumber"); - - const view = await identity.decrypt(null); - - expect(view).toEqual({ - _firstName: "mockFirstName", - _lastName: "mockLastName", - _subTitle: null, - address1: "mockAddress1", - address2: "mockAddress2", - address3: "mockAddress3", - city: "mockCity", - company: "mockCompany", - country: "mockCountry", - email: "mockEmail", - licenseNumber: "mockLicenseNumber", - middleName: "mockMiddleName", - passportNumber: "mockPassportNumber", - phone: "mockPhone", - postalCode: "mockPostalCode", - ssn: "mockSsn", - state: "mockState", - title: "mockTitle", - username: "mockUsername", - }); - }); -}); diff --git a/jslib/common/spec/domain/login.spec.ts b/jslib/common/spec/domain/login.spec.ts deleted file mode 100644 index 56f8c2c3..00000000 --- a/jslib/common/spec/domain/login.spec.ts +++ /dev/null @@ -1,101 +0,0 @@ -import Substitute, { Arg } from "@fluffy-spoon/substitute"; - -import { UriMatchType } from "@/jslib/common/src/enums/uriMatchType"; -import { LoginData } from "@/jslib/common/src/models/data/loginData"; -import { Login } from "@/jslib/common/src/models/domain/login"; -import { LoginUri } from "@/jslib/common/src/models/domain/loginUri"; -import { LoginUriView } from "@/jslib/common/src/models/view/loginUriView"; - -import { mockEnc } from "../utils"; - -describe("Login DTO", () => { - it("Convert from empty LoginData", () => { - const data = new LoginData(); - const login = new Login(data); - - expect(login).toEqual({ - passwordRevisionDate: null, - autofillOnPageLoad: undefined, - username: null, - password: null, - totp: null, - }); - }); - - it("Convert from full LoginData", () => { - const data: LoginData = { - uris: [{ uri: "uri", match: UriMatchType.Domain }], - username: "username", - password: "password", - passwordRevisionDate: "2022-01-31T12:00:00.000Z", - totp: "123", - autofillOnPageLoad: false, - }; - const login = new Login(data); - - expect(login).toEqual({ - passwordRevisionDate: new Date("2022-01-31T12:00:00.000Z"), - autofillOnPageLoad: false, - username: { encryptedString: "username", encryptionType: 0 }, - password: { encryptedString: "password", encryptionType: 0 }, - totp: { encryptedString: "123", encryptionType: 0 }, - uris: [{ match: 0, uri: { encryptedString: "uri", encryptionType: 0 } }], - }); - }); - - it("Initialize without LoginData", () => { - const login = new Login(); - - expect(login).toEqual({}); - }); - - it("Decrypts correctly", async () => { - const loginUri = Substitute.for(); - const loginUriView = new LoginUriView(); - loginUriView.uri = "decrypted uri"; - loginUri.decrypt(Arg.any()).resolves(loginUriView); - - const login = new Login(); - login.uris = [loginUri]; - login.username = mockEnc("encrypted username"); - login.password = mockEnc("encrypted password"); - login.passwordRevisionDate = new Date("2022-01-31T12:00:00.000Z"); - login.totp = mockEnc("encrypted totp"); - login.autofillOnPageLoad = true; - - const loginView = await login.decrypt(null); - expect(loginView).toEqual({ - username: "encrypted username", - password: "encrypted password", - passwordRevisionDate: new Date("2022-01-31T12:00:00.000Z"), - totp: "encrypted totp", - uris: [ - { - match: null, - _uri: "decrypted uri", - _domain: null, - _hostname: null, - _host: null, - _canLaunch: null, - }, - ], - autofillOnPageLoad: true, - }); - }); - - it("Converts from LoginData and back", () => { - const data: LoginData = { - uris: [{ uri: "uri", match: UriMatchType.Domain }], - username: "username", - password: "password", - passwordRevisionDate: "2022-01-31T12:00:00.000Z", - totp: "123", - autofillOnPageLoad: false, - }; - const login = new Login(data); - - const loginData = login.toLoginData(); - - expect(loginData).toEqual(data); - }); -}); diff --git a/jslib/common/spec/domain/loginUri.spec.ts b/jslib/common/spec/domain/loginUri.spec.ts deleted file mode 100644 index 1522d374..00000000 --- a/jslib/common/spec/domain/loginUri.spec.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { UriMatchType } from "@/jslib/common/src/enums/uriMatchType"; -import { LoginUriData } from "@/jslib/common/src/models/data/loginUriData"; -import { LoginUri } from "@/jslib/common/src/models/domain/loginUri"; - -import { mockEnc } from "../utils"; - -describe("LoginUri", () => { - let data: LoginUriData; - - beforeEach(() => { - data = { - uri: "encUri", - match: UriMatchType.Domain, - }; - }); - - it("Convert from empty", () => { - const data = new LoginUriData(); - const loginUri = new LoginUri(data); - - expect(loginUri).toEqual({ - match: null, - uri: null, - }); - }); - - it("Convert", () => { - const loginUri = new LoginUri(data); - - expect(loginUri).toEqual({ - match: 0, - uri: { encryptedString: "encUri", encryptionType: 0 }, - }); - }); - - it("toLoginUriData", () => { - const loginUri = new LoginUri(data); - expect(loginUri.toLoginUriData()).toEqual(data); - }); - - it("Decrypt", async () => { - const loginUri = new LoginUri(); - loginUri.match = UriMatchType.Exact; - loginUri.uri = mockEnc("uri"); - - const view = await loginUri.decrypt(null); - - expect(view).toEqual({ - _canLaunch: null, - _domain: null, - _host: null, - _hostname: null, - _uri: "uri", - match: 3, - }); - }); -}); diff --git a/jslib/common/spec/domain/password.spec.ts b/jslib/common/spec/domain/password.spec.ts deleted file mode 100644 index 1ddbb46f..00000000 --- a/jslib/common/spec/domain/password.spec.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { PasswordHistoryData } from "@/jslib/common/src/models/data/passwordHistoryData"; -import { Password } from "@/jslib/common/src/models/domain/password"; - -import { mockEnc } from "../utils"; - -describe("Password", () => { - let data: PasswordHistoryData; - - beforeEach(() => { - data = { - password: "encPassword", - lastUsedDate: "2022-01-31T12:00:00.000Z", - }; - }); - - it("Convert from empty", () => { - const data = new PasswordHistoryData(); - const password = new Password(data); - - expect(password).toMatchObject({ - password: null, - }); - }); - - it("Convert", () => { - const password = new Password(data); - - expect(password).toEqual({ - password: { encryptedString: "encPassword", encryptionType: 0 }, - lastUsedDate: new Date("2022-01-31T12:00:00.000Z"), - }); - }); - - it("toPasswordHistoryData", () => { - const password = new Password(data); - expect(password.toPasswordHistoryData()).toEqual(data); - }); - - it("Decrypt", async () => { - const password = new Password(); - password.password = mockEnc("password"); - password.lastUsedDate = new Date("2022-01-31T12:00:00.000Z"); - - const view = await password.decrypt(null); - - expect(view).toEqual({ - password: "password", - lastUsedDate: new Date("2022-01-31T12:00:00.000Z"), - }); - }); -}); diff --git a/jslib/common/spec/domain/secureNote.spec.ts b/jslib/common/spec/domain/secureNote.spec.ts deleted file mode 100644 index 710b96cc..00000000 --- a/jslib/common/spec/domain/secureNote.spec.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { SecureNoteType } from "@/jslib/common/src/enums/secureNoteType"; -import { SecureNoteData } from "@/jslib/common/src/models/data/secureNoteData"; -import { SecureNote } from "@/jslib/common/src/models/domain/secureNote"; - -describe("SecureNote", () => { - let data: SecureNoteData; - - beforeEach(() => { - data = { - type: SecureNoteType.Generic, - }; - }); - - it("Convert from empty", () => { - const data = new SecureNoteData(); - const secureNote = new SecureNote(data); - - expect(secureNote).toEqual({ - type: undefined, - }); - }); - - it("Convert", () => { - const secureNote = new SecureNote(data); - - expect(secureNote).toEqual({ - type: 0, - }); - }); - - it("toSecureNoteData", () => { - const secureNote = new SecureNote(data); - expect(secureNote.toSecureNoteData()).toEqual(data); - }); - - it("Decrypt", async () => { - const secureNote = new SecureNote(); - secureNote.type = SecureNoteType.Generic; - - const view = await secureNote.decrypt(null); - - expect(view).toEqual({ - type: 0, - }); - }); -}); diff --git a/jslib/common/spec/domain/send.spec.ts b/jslib/common/spec/domain/send.spec.ts deleted file mode 100644 index c25bab3a..00000000 --- a/jslib/common/spec/domain/send.spec.ts +++ /dev/null @@ -1,144 +0,0 @@ -import Substitute, { Arg, SubstituteOf } from "@fluffy-spoon/substitute"; - -import { CryptoService } from "@/jslib/common/src/abstractions/crypto.service"; -import { SendType } from "@/jslib/common/src/enums/sendType"; -import { SendData } from "@/jslib/common/src/models/data/sendData"; -import { EncString } from "@/jslib/common/src/models/domain/encString"; -import { Send } from "@/jslib/common/src/models/domain/send"; -import { SendText } from "@/jslib/common/src/models/domain/sendText"; -import { ContainerService } from "@/jslib/common/src/services/container.service"; - -import { makeStaticByteArray, mockEnc } from "../utils"; - -describe("Send", () => { - let data: SendData; - - beforeEach(() => { - data = { - id: "id", - accessId: "accessId", - userId: "userId", - 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, - userId: 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", - userId: "userId", - 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(); - text.decrypt(Arg.any()).resolves("textView" as any); - - const send = new Send(); - send.id = "id"; - send.accessId = "accessId"; - send.userId = "userId"; - 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.decryptToBytes(send.key, null).resolves(makeStaticByteArray(32)); - cryptoService.makeSendKey(Arg.any()).resolves("cryptoKey" as any); - - (window as any).bitwardenContainerService = new ContainerService(cryptoService); - - const view = await send.decrypt(); - - text.received(1).decrypt("cryptoKey" as any); - (send.name as SubstituteOf).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, - }); - }); -}); diff --git a/jslib/common/spec/domain/sendAccess.spec.ts b/jslib/common/spec/domain/sendAccess.spec.ts deleted file mode 100644 index f10dfe4d..00000000 --- a/jslib/common/spec/domain/sendAccess.spec.ts +++ /dev/null @@ -1,84 +0,0 @@ -import Substitute, { Arg } from "@fluffy-spoon/substitute"; - -import { SendType } from "@/jslib/common/src/enums/sendType"; -import { SendAccess } from "@/jslib/common/src/models/domain/sendAccess"; -import { SendText } from "@/jslib/common/src/models/domain/sendText"; -import { SendAccessResponse } from "@/jslib/common/src/models/response/sendAccessResponse"; - -import { mockEnc } from "../utils"; - -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(); - 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", - }); - }); -}); diff --git a/jslib/common/spec/domain/sendFile.spec.ts b/jslib/common/spec/domain/sendFile.spec.ts deleted file mode 100644 index 70da0b03..00000000 --- a/jslib/common/spec/domain/sendFile.spec.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { SendFileData } from "@/jslib/common/src/models/data/sendFileData"; -import { SendFile } from "@/jslib/common/src/models/domain/sendFile"; - -import { mockEnc } from "../utils"; - -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", - }); - }); -}); diff --git a/jslib/common/spec/domain/sendText.spec.ts b/jslib/common/spec/domain/sendText.spec.ts deleted file mode 100644 index eb82c93c..00000000 --- a/jslib/common/spec/domain/sendText.spec.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { SendTextData } from "@/jslib/common/src/models/data/sendTextData"; -import { SendText } from "@/jslib/common/src/models/domain/sendText"; - -import { mockEnc } from "../utils"; - -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, - }); - }); -}); diff --git a/jslib/common/spec/domain/symmetricCryptoKey.spec.ts b/jslib/common/spec/domain/symmetricCryptoKey.spec.ts deleted file mode 100644 index 5d379129..00000000 --- a/jslib/common/spec/domain/symmetricCryptoKey.spec.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { EncryptionType } from "@/jslib/common/src/enums/encryptionType"; -import { SymmetricCryptoKey } from "@/jslib/common/src/models/domain/symmetricCryptoKey"; - -import { makeStaticByteArray } from "../utils"; - -describe("SymmetricCryptoKey", () => { - it("errors if no key", () => { - const t = () => { - new SymmetricCryptoKey(null); - }; - - expect(t).toThrowError("Must provide key"); - }); - - describe("guesses encKey from key length", () => { - it("AesCbc256_B64", () => { - const key = makeStaticByteArray(32); - const cryptoKey = new SymmetricCryptoKey(key); - - expect(cryptoKey).toEqual({ - encKey: key, - encKeyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=", - encType: 0, - key: key, - keyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=", - macKey: null, - }); - }); - - it("AesCbc128_HmacSha256_B64", () => { - const key = makeStaticByteArray(32); - const cryptoKey = new SymmetricCryptoKey(key, EncryptionType.AesCbc128_HmacSha256_B64); - - expect(cryptoKey).toEqual({ - encKey: key.slice(0, 16), - encKeyB64: "AAECAwQFBgcICQoLDA0ODw==", - encType: 1, - key: key, - keyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=", - macKey: key.slice(16, 32), - macKeyB64: "EBESExQVFhcYGRobHB0eHw==", - }); - }); - - it("AesCbc256_HmacSha256_B64", () => { - const key = makeStaticByteArray(64); - const cryptoKey = new SymmetricCryptoKey(key); - - expect(cryptoKey).toEqual({ - encKey: key.slice(0, 32), - encKeyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=", - encType: 2, - key: key, - keyB64: - "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+Pw==", - macKey: key.slice(32, 64), - macKeyB64: "ICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj8=", - }); - }); - - it("unknown length", () => { - const t = () => { - new SymmetricCryptoKey(makeStaticByteArray(30)); - }; - - expect(t).toThrowError("Unable to determine encType."); - }); - }); -}); diff --git a/jslib/common/spec/importers/bitwardenJsonImporter.spec.ts b/jslib/common/spec/importers/bitwardenJsonImporter.spec.ts deleted file mode 100644 index 9dc6d020..00000000 --- a/jslib/common/spec/importers/bitwardenJsonImporter.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Substitute, SubstituteOf } from "@fluffy-spoon/substitute"; - -import { CryptoService } from "@/jslib/common/src/abstractions/crypto.service"; -import { I18nService } from "@/jslib/common/src/abstractions/i18n.service"; -import { BitwardenJsonImporter } from "@/jslib/common/src/importers/bitwardenJsonImporter"; - -import { data as passwordProtectedData } from "./testData/bitwardenJson/passwordProtected.json"; - -describe("bitwarden json importer", () => { - let sut: BitwardenJsonImporter; - let cryptoService: SubstituteOf; - let i18nService: SubstituteOf; - - beforeEach(() => { - cryptoService = Substitute.for(); - i18nService = Substitute.for(); - - sut = new BitwardenJsonImporter(cryptoService, i18nService); - }); - - it("should fail if password is needed", async () => { - expect((await sut.parse(passwordProtectedData)).success).toBe(false); - }); - - it("should return password needed error message", async () => { - const expected = "Password required error message"; - i18nService.t("importPasswordRequired").returns(expected); - - expect((await sut.parse(passwordProtectedData)).errorMessage).toEqual(expected); - }); -}); diff --git a/jslib/common/spec/importers/bitwardenPasswordProtectedImporter.spec.ts b/jslib/common/spec/importers/bitwardenPasswordProtectedImporter.spec.ts deleted file mode 100644 index e44ce987..00000000 --- a/jslib/common/spec/importers/bitwardenPasswordProtectedImporter.spec.ts +++ /dev/null @@ -1,113 +0,0 @@ -import Substitute, { Arg, SubstituteOf } from "@fluffy-spoon/substitute"; - -import { CryptoService } from "@/jslib/common/src/abstractions/crypto.service"; -import { I18nService } from "@/jslib/common/src/abstractions/i18n.service"; -import { KdfType } from "@/jslib/common/src/enums/kdfType"; -import { BitwardenPasswordProtectedImporter } from "@/jslib/common/src/importers/bitwardenPasswordProtectedImporter"; -import { Utils } from "@/jslib/common/src/misc/utils"; -import { ImportResult } from "@/jslib/common/src/models/domain/importResult"; - -import { data as emptyDecryptedData } from "./testData/bitwardenJson/empty.json"; - -describe("BitwardenPasswordProtectedImporter", () => { - let importer: BitwardenPasswordProtectedImporter; - let cryptoService: SubstituteOf; - let i18nService: SubstituteOf; - const password = Utils.newGuid(); - const result = new ImportResult(); - let jDoc: { - encrypted?: boolean; - passwordProtected?: boolean; - salt?: string; - kdfIterations?: any; - kdfType?: any; - encKeyValidation_DO_NOT_EDIT?: string; - data?: string; - }; - - beforeEach(() => { - cryptoService = Substitute.for(); - i18nService = Substitute.for(); - - jDoc = { - encrypted: true, - passwordProtected: true, - salt: "c2FsdA==", - kdfIterations: 100000, - kdfType: KdfType.PBKDF2_SHA256, - encKeyValidation_DO_NOT_EDIT: Utils.newGuid(), - data: Utils.newGuid(), - }; - - result.success = true; - importer = new BitwardenPasswordProtectedImporter(cryptoService, i18nService, password); - }); - - describe("Required Json Data", () => { - it("succeeds with default jdoc", async () => { - cryptoService.decryptToUtf8(Arg.any(), Arg.any()).resolves(emptyDecryptedData); - - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(true); - }); - - it("fails if encrypted === false", async () => { - jDoc.encrypted = false; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if encrypted === null", async () => { - jDoc.encrypted = null; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if passwordProtected === false", async () => { - jDoc.passwordProtected = false; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if passwordProtected === null", async () => { - jDoc.passwordProtected = null; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if salt === null", async () => { - jDoc.salt = null; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if kdfIterations === null", async () => { - jDoc.kdfIterations = null; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if kdfIterations is not a number", async () => { - jDoc.kdfIterations = "not a number"; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if kdfType === null", async () => { - jDoc.kdfType = null; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if kdfType is not a string", async () => { - jDoc.kdfType = "not a valid kdf type"; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if kdfType is not a known kdfType", async () => { - jDoc.kdfType = -1; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if encKeyValidation_DO_NOT_EDIT === null", async () => { - jDoc.encKeyValidation_DO_NOT_EDIT = null; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if data === null", async () => { - jDoc.data = null; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - }); -}); diff --git a/jslib/common/spec/importers/dashlaneCsvImporter.spec.ts b/jslib/common/spec/importers/dashlaneCsvImporter.spec.ts deleted file mode 100644 index 8aab8351..00000000 --- a/jslib/common/spec/importers/dashlaneCsvImporter.spec.ts +++ /dev/null @@ -1,367 +0,0 @@ -import { CipherType } from "@/jslib/common/src/enums/cipherType"; -import { DashlaneCsvImporter as Importer } from "@/jslib/common/src/importers/dashlaneImporters/dashlaneCsvImporter"; - -import { credentialsData } from "./testData/dashlaneCsv/credentials.csv"; -import { identityData } from "./testData/dashlaneCsv/id.csv"; -import { multiplePersonalInfoData } from "./testData/dashlaneCsv/multiplePersonalInfo.csv"; -import { paymentsData } from "./testData/dashlaneCsv/payments.csv"; -import { personalInfoData } from "./testData/dashlaneCsv/personalInfo.csv"; -import { secureNoteData } from "./testData/dashlaneCsv/securenotes.csv"; - -describe("Dashlane CSV Importer", () => { - let importer: Importer; - beforeEach(() => { - importer = new Importer(); - }); - - it("should parse login records", async () => { - const result = await importer.parse(credentialsData); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.name).toEqual("example.com"); - expect(cipher.login.username).toEqual("jdoe"); - expect(cipher.login.password).toEqual("somePassword"); - expect(cipher.login.totp).toEqual("someTOTPSeed"); - expect(cipher.login.uris.length).toEqual(1); - const uriView = cipher.login.uris.shift(); - expect(uriView.uri).toEqual("https://www.example.com"); - expect(cipher.notes).toEqual("some note for example.com"); - }); - - it("should parse an item and create a folder", async () => { - const result = await importer.parse(credentialsData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.folders.length).toBe(1); - expect(result.folders[0].name).toBe("Entertainment"); - expect(result.folderRelationships[0]).toEqual([0, 0]); - }); - - it("should parse payment records", async () => { - const result = await importer.parse(paymentsData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(2); - - // Account - const cipher = result.ciphers.shift(); - expect(cipher.type).toBe(CipherType.Card); - expect(cipher.name).toBe("John's savings account"); - expect(cipher.card.brand).toBeNull(); - expect(cipher.card.cardholderName).toBe("John Doe"); - expect(cipher.card.number).toBe("accountNumber"); - expect(cipher.card.code).toBeNull(); - expect(cipher.card.expMonth).toBeNull(); - expect(cipher.card.expYear).toBeNull(); - - expect(cipher.fields.length).toBe(4); - - expect(cipher.fields[0].name).toBe("type"); - expect(cipher.fields[0].value).toBe("bank"); - - expect(cipher.fields[1].name).toBe("routing_number"); - expect(cipher.fields[1].value).toBe("routingNumber"); - - expect(cipher.fields[2].name).toBe("country"); - expect(cipher.fields[2].value).toBe("US"); - - expect(cipher.fields[3].name).toBe("issuing_bank"); - expect(cipher.fields[3].value).toBe("US-ALLY"); - - // CreditCard - const cipher2 = result.ciphers.shift(); - expect(cipher2.type).toBe(CipherType.Card); - expect(cipher2.name).toBe("John Doe"); - expect(cipher2.card.brand).toBe("Visa"); - expect(cipher2.card.cardholderName).toBe("John Doe"); - expect(cipher2.card.number).toBe("41111111111111111"); - expect(cipher2.card.code).toBe("123"); - expect(cipher2.card.expMonth).toBe("01"); - expect(cipher2.card.expYear).toBe("23"); - - expect(cipher2.fields.length).toBe(2); - - expect(cipher2.fields[0].name).toBe("type"); - expect(cipher2.fields[0].value).toBe("credit_card"); - - expect(cipher2.fields[1].name).toBe("country"); - expect(cipher2.fields[1].value).toBe("US"); - }); - - it("should parse ids records", async () => { - const result = await importer.parse(identityData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - - // Type card - const cipher = result.ciphers.shift(); - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("John Doe card"); - expect(cipher.identity.fullName).toBe("John Doe"); - expect(cipher.identity.firstName).toBe("John"); - expect(cipher.identity.middleName).toBeNull(); - expect(cipher.identity.lastName).toBe("Doe"); - expect(cipher.identity.licenseNumber).toBe("123123123"); - - expect(cipher.fields.length).toBe(3); - - expect(cipher.fields[0].name).toEqual("type"); - expect(cipher.fields[0].value).toEqual("card"); - - expect(cipher.fields[1].name).toEqual("issue_date"); - expect(cipher.fields[1].value).toEqual("2022-1-30"); - - expect(cipher.fields[2].name).toEqual("expiration_date"); - expect(cipher.fields[2].value).toEqual("2032-1-30"); - - // Type passport - const cipher2 = result.ciphers.shift(); - expect(cipher2.type).toBe(CipherType.Identity); - expect(cipher2.name).toBe("John Doe passport"); - expect(cipher2.identity.fullName).toBe("John Doe"); - expect(cipher2.identity.firstName).toBe("John"); - expect(cipher2.identity.middleName).toBeNull(); - expect(cipher2.identity.lastName).toBe("Doe"); - expect(cipher2.identity.passportNumber).toBe("123123123"); - - expect(cipher2.fields.length).toBe(4); - - expect(cipher2.fields[0].name).toEqual("type"); - expect(cipher2.fields[0].value).toEqual("passport"); - expect(cipher2.fields[1].name).toEqual("issue_date"); - expect(cipher2.fields[1].value).toEqual("2022-1-30"); - expect(cipher2.fields[2].name).toEqual("expiration_date"); - expect(cipher2.fields[2].value).toEqual("2032-1-30"); - expect(cipher2.fields[3].name).toEqual("place_of_issue"); - expect(cipher2.fields[3].value).toEqual("somewhere in Germany"); - - // Type license - const cipher3 = result.ciphers.shift(); - expect(cipher3.type).toBe(CipherType.Identity); - expect(cipher3.name).toBe("John Doe license"); - expect(cipher3.identity.fullName).toBe("John Doe"); - expect(cipher3.identity.firstName).toBe("John"); - expect(cipher3.identity.middleName).toBeNull(); - expect(cipher3.identity.lastName).toBe("Doe"); - expect(cipher3.identity.licenseNumber).toBe("1234556"); - expect(cipher3.identity.state).toBe("DC"); - - expect(cipher3.fields.length).toBe(3); - expect(cipher3.fields[0].name).toEqual("type"); - expect(cipher3.fields[0].value).toEqual("license"); - expect(cipher3.fields[1].name).toEqual("issue_date"); - expect(cipher3.fields[1].value).toEqual("2022-8-10"); - expect(cipher3.fields[2].name).toEqual("expiration_date"); - expect(cipher3.fields[2].value).toEqual("2022-10-10"); - - // Type social_security - const cipher4 = result.ciphers.shift(); - expect(cipher4.type).toBe(CipherType.Identity); - expect(cipher4.name).toBe("John Doe social_security"); - expect(cipher4.identity.fullName).toBe("John Doe"); - expect(cipher4.identity.firstName).toBe("John"); - expect(cipher4.identity.middleName).toBeNull(); - expect(cipher4.identity.lastName).toBe("Doe"); - expect(cipher4.identity.ssn).toBe("123123123"); - - expect(cipher4.fields.length).toBe(1); - expect(cipher4.fields[0].name).toEqual("type"); - expect(cipher4.fields[0].value).toEqual("social_security"); - - // Type tax_number - const cipher5 = result.ciphers.shift(); - expect(cipher5.type).toBe(CipherType.Identity); - expect(cipher5.name).toBe("tax_number"); - expect(cipher5.identity.licenseNumber).toBe("123123123"); - - expect(cipher5.fields.length).toBe(1); - expect(cipher5.fields[0].name).toEqual("type"); - expect(cipher5.fields[0].value).toEqual("tax_number"); - }); - - it("should parse secureNote records", async () => { - const result = await importer.parse(secureNoteData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - - const cipher = result.ciphers.shift(); - expect(cipher.type).toBe(CipherType.SecureNote); - expect(cipher.name).toBe("01"); - expect(cipher.notes).toBe("test"); - }); - - it("should parse personal information records (multiple identities)", async () => { - const result = await importer.parse(multiplePersonalInfoData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(6); - - // name - const cipher = result.ciphers.shift(); - expect(cipher.type).toBe(CipherType.SecureNote); - expect(cipher.name).toBe("MR John Doe"); - - expect(cipher.fields.length).toBe(7); - expect(cipher.fields[0].name).toEqual("type"); - expect(cipher.fields[0].value).toEqual("name"); - expect(cipher.fields[1].name).toEqual("title"); - expect(cipher.fields[1].value).toEqual("MR"); - expect(cipher.fields[2].name).toEqual("first_name"); - expect(cipher.fields[2].value).toEqual("John"); - expect(cipher.fields[3].name).toEqual("last_name"); - expect(cipher.fields[3].value).toEqual("Doe"); - expect(cipher.fields[4].name).toEqual("login"); - expect(cipher.fields[4].value).toEqual("jdoe"); - expect(cipher.fields[5].name).toEqual("date_of_birth"); - expect(cipher.fields[5].value).toEqual("2022-01-30"); - expect(cipher.fields[6].name).toEqual("place_of_birth"); - expect(cipher.fields[6].value).toEqual("world"); - - // email - const cipher2 = result.ciphers.shift(); - expect(cipher2.type).toBe(CipherType.SecureNote); - expect(cipher2.name).toBe("Johns email"); - - expect(cipher2.fields.length).toBe(4); - expect(cipher2.fields[0].name).toEqual("type"); - expect(cipher2.fields[0].value).toEqual("email"); - expect(cipher2.fields[1].name).toEqual("email"); - expect(cipher2.fields[1].value).toEqual("jdoe@example.com"); - expect(cipher2.fields[2].name).toEqual("email_type"); - expect(cipher2.fields[2].value).toEqual("personal"); - expect(cipher2.fields[3].name).toEqual("item_name"); - expect(cipher2.fields[3].value).toEqual("Johns email"); - - // number - const cipher3 = result.ciphers.shift(); - expect(cipher3.type).toBe(CipherType.SecureNote); - expect(cipher3.name).toBe("John's number"); - - expect(cipher3.fields.length).toBe(3); - expect(cipher3.fields[0].name).toEqual("type"); - expect(cipher3.fields[0].value).toEqual("number"); - expect(cipher3.fields[1].name).toEqual("item_name"); - expect(cipher3.fields[1].value).toEqual("John's number"); - expect(cipher3.fields[2].name).toEqual("phone_number"); - expect(cipher3.fields[2].value).toEqual("+49123123123"); - - // address - const cipher4 = result.ciphers.shift(); - expect(cipher4.type).toBe(CipherType.SecureNote); - expect(cipher4.name).toBe("John's home address"); - - expect(cipher4.fields.length).toBe(12); - expect(cipher4.fields[0].name).toEqual("type"); - expect(cipher4.fields[0].value).toEqual("address"); - expect(cipher4.fields[1].name).toEqual("item_name"); - expect(cipher4.fields[1].value).toEqual("John's home address"); - expect(cipher4.fields[2].name).toEqual("address"); - expect(cipher4.fields[2].value).toEqual("1 some street"); - expect(cipher4.fields[3].name).toEqual("country"); - expect(cipher4.fields[3].value).toEqual("de"); - expect(cipher4.fields[4].name).toEqual("state"); - expect(cipher4.fields[4].value).toEqual("DE-0-NW"); - expect(cipher4.fields[5].name).toEqual("city"); - expect(cipher4.fields[5].value).toEqual("some city"); - expect(cipher4.fields[6].name).toEqual("zip"); - expect(cipher4.fields[6].value).toEqual("123123"); - expect(cipher4.fields[7].name).toEqual("address_recipient"); - expect(cipher4.fields[7].value).toEqual("John"); - expect(cipher4.fields[8].name).toEqual("address_building"); - expect(cipher4.fields[8].value).toEqual("1"); - expect(cipher4.fields[9].name).toEqual("address_apartment"); - expect(cipher4.fields[9].value).toEqual("1"); - expect(cipher4.fields[10].name).toEqual("address_floor"); - expect(cipher4.fields[10].value).toEqual("1"); - expect(cipher4.fields[11].name).toEqual("address_door_code"); - expect(cipher4.fields[11].value).toEqual("123"); - - // website - const cipher5 = result.ciphers.shift(); - expect(cipher5.type).toBe(CipherType.SecureNote); - expect(cipher5.name).toBe("Website"); - - expect(cipher5.fields.length).toBe(3); - expect(cipher5.fields[0].name).toEqual("type"); - expect(cipher5.fields[0].value).toEqual("website"); - expect(cipher5.fields[1].name).toEqual("item_name"); - expect(cipher5.fields[1].value).toEqual("Website"); - expect(cipher5.fields[2].name).toEqual("url"); - expect(cipher5.fields[2].value).toEqual("website.com"); - - // 2nd name/identity - const cipher6 = result.ciphers.shift(); - expect(cipher6.type).toBe(CipherType.SecureNote); - expect(cipher6.name).toBe("Mrs Jane Doe"); - - expect(cipher6.fields.length).toBe(7); - expect(cipher6.fields[0].name).toEqual("type"); - expect(cipher6.fields[0].value).toEqual("name"); - expect(cipher6.fields[1].name).toEqual("title"); - expect(cipher6.fields[1].value).toEqual("Mrs"); - expect(cipher6.fields[2].name).toEqual("first_name"); - expect(cipher6.fields[2].value).toEqual("Jane"); - expect(cipher6.fields[3].name).toEqual("last_name"); - expect(cipher6.fields[3].value).toEqual("Doe"); - expect(cipher6.fields[4].name).toEqual("login"); - expect(cipher6.fields[4].value).toEqual("jdoe"); - expect(cipher6.fields[5].name).toEqual("date_of_birth"); - expect(cipher6.fields[5].value).toEqual("2022-01-30"); - expect(cipher6.fields[6].name).toEqual("place_of_birth"); - expect(cipher6.fields[6].value).toEqual("earth"); - }); - - it("should combine personal information records to one identity if only one identity present", async () => { - const result = await importer.parse(personalInfoData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("MR John Doe"); - expect(cipher.identity.fullName).toBe("MR John Doe"); - expect(cipher.identity.title).toBe("MR"); - expect(cipher.identity.firstName).toBe("John"); - expect(cipher.identity.middleName).toBeNull(); - expect(cipher.identity.lastName).toBe("Doe"); - expect(cipher.identity.username).toBe("jdoe"); - expect(cipher.identity.email).toBe("jdoe@example.com"); - expect(cipher.identity.phone).toBe("+49123123123"); - - expect(cipher.fields.length).toBe(9); - expect(cipher.fields[0].name).toBe("date_of_birth"); - expect(cipher.fields[0].value).toBe("2022-01-30"); - - expect(cipher.fields[1].name).toBe("place_of_birth"); - expect(cipher.fields[1].value).toBe("world"); - - expect(cipher.fields[2].name).toBe("email_type"); - expect(cipher.fields[2].value).toBe("personal"); - - expect(cipher.fields[3].name).toBe("address_recipient"); - expect(cipher.fields[3].value).toBe("John"); - - expect(cipher.fields[4].name).toBe("address_building"); - expect(cipher.fields[4].value).toBe("1"); - - expect(cipher.fields[5].name).toBe("address_apartment"); - expect(cipher.fields[5].value).toBe("1"); - - expect(cipher.fields[6].name).toBe("address_floor"); - expect(cipher.fields[6].value).toBe("1"); - - expect(cipher.fields[7].name).toBe("address_door_code"); - expect(cipher.fields[7].value).toBe("123"); - - expect(cipher.fields[8].name).toBe("url"); - expect(cipher.fields[8].value).toBe("website.com"); - }); -}); diff --git a/jslib/common/spec/importers/firefoxCsvImporter.spec.ts b/jslib/common/spec/importers/firefoxCsvImporter.spec.ts deleted file mode 100644 index fdc786b5..00000000 --- a/jslib/common/spec/importers/firefoxCsvImporter.spec.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { FirefoxCsvImporter as Importer } from "@/jslib/common/src/importers/firefoxCsvImporter"; -import { CipherView } from "@/jslib/common/src/models/view/cipherView"; -import { LoginUriView } from "@/jslib/common/src/models/view/loginUriView"; -import { LoginView } from "@/jslib/common/src/models/view/loginView"; - -import { data as firefoxAccountsData } from "./testData/firefoxCsv/firefoxAccountsData.csv"; -import { data as simplePasswordData } from "./testData/firefoxCsv/simplePasswordData.csv"; - -const CipherData = [ - { - title: "should parse password", - csv: simplePasswordData, - expected: Object.assign(new CipherView(), { - id: null, - organizationId: null, - folderId: null, - name: "example.com", - login: Object.assign(new LoginView(), { - username: "foo", - password: "bar", - uris: [ - Object.assign(new LoginUriView(), { - uri: "https://example.com", - }), - ], - }), - notes: null, - type: 1, - }), - }, - { - title: 'should skip "chrome://FirefoxAccounts"', - csv: firefoxAccountsData, - expected: Object.assign(new CipherView(), { - id: null, - organizationId: null, - folderId: null, - name: "example.com", - login: Object.assign(new LoginView(), { - username: "foo", - password: "bar", - uris: [ - Object.assign(new LoginUriView(), { - uri: "https://example.com", - }), - ], - }), - notes: null, - type: 1, - }), - }, -]; - -describe("Firefox CSV Importer", () => { - CipherData.forEach((data) => { - it(data.title, async () => { - const importer = new Importer(); - const result = await importer.parse(data.csv); - expect(result != null).toBe(true); - expect(result.ciphers.length).toBeGreaterThan(0); - - const cipher = result.ciphers.shift(); - let property: keyof typeof data.expected; - for (property in data.expected) { - // eslint-disable-next-line - if (data.expected.hasOwnProperty(property)) { - // eslint-disable-next-line - expect(cipher.hasOwnProperty(property)).toBe(true); - expect(cipher[property]).toEqual(data.expected[property]); - } - } - }); - }); -}); diff --git a/jslib/common/spec/importers/fsecureFskImporter.spec.ts b/jslib/common/spec/importers/fsecureFskImporter.spec.ts deleted file mode 100644 index 4fe4af56..00000000 --- a/jslib/common/spec/importers/fsecureFskImporter.spec.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { FSecureFskImporter as Importer } from "@/jslib/common/src/importers/fsecureFskImporter"; - -const TestDataWithStyleSetToWebsite: string = JSON.stringify({ - data: { - "8d58b5cf252dd06fbd98f5289e918ab1": { - color: "#00baff", - reatedDate: 1609302913, - creditCvv: "", - creditExpiry: "", - creditNumber: "", - favorite: 0, - modifiedDate: 1609302913, - notes: "note", - password: "word", - passwordList: [], - passwordModifiedDate: 1609302913, - rev: 1, - service: "My first pass", - style: "website", - type: 1, - url: "https://bitwarden.com", - username: "pass", - }, - }, -}); - -const TestDataWithStyleSetToGlobe: string = JSON.stringify({ - data: { - "8d58b5cf252dd06fbd98f5289e918ab1": { - color: "#00baff", - reatedDate: 1609302913, - creditCvv: "", - creditExpiry: "", - creditNumber: "", - favorite: 0, - modifiedDate: 1609302913, - notes: "note", - password: "word", - passwordList: [], - passwordModifiedDate: 1609302913, - rev: 1, - service: "My first pass", - style: "globe", - type: 1, - url: "https://bitwarden.com", - username: "pass", - }, - }, -}); - -describe("FSecure FSK Importer", () => { - it("should parse data with style set to website", async () => { - const importer = new Importer(); - const result = await importer.parse(TestDataWithStyleSetToWebsite); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.login.username).toEqual("pass"); - expect(cipher.login.password).toEqual("word"); - expect(cipher.login.uris.length).toEqual(1); - const uriView = cipher.login.uris.shift(); - expect(uriView.uri).toEqual("https://bitwarden.com"); - }); - - it("should parse data with style set to globe", async () => { - const importer = new Importer(); - const result = await importer.parse(TestDataWithStyleSetToGlobe); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.login.username).toEqual("pass"); - expect(cipher.login.password).toEqual("word"); - expect(cipher.login.uris.length).toEqual(1); - const uriView = cipher.login.uris.shift(); - expect(uriView.uri).toEqual("https://bitwarden.com"); - }); -}); diff --git a/jslib/common/spec/importers/keepass2XmlImporter.spec.ts b/jslib/common/spec/importers/keepass2XmlImporter.spec.ts deleted file mode 100644 index b3305dd5..00000000 --- a/jslib/common/spec/importers/keepass2XmlImporter.spec.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { KeePass2XmlImporter as Importer } from "@/jslib/common/src/importers/keepass2XmlImporter"; - -const TestData = ` - - - KeePass - - 2016-12-31T21:33:52Z - - 2016-12-31T21:33:52Z - - 2016-12-31T21:33:52Z - 365 - - 2016-12-31T21:33:59Z - -1 - -1 - - False - False - True - False - False - - True - AAAAAAAAAAAAAAAAAAAAAA== - 2016-12-31T21:33:52Z - AAAAAAAAAAAAAAAAAAAAAA== - 2016-12-31T21:33:52Z - 10 - 6291456 - AAAAAAAAAAAAAAAAAAAAAA== - AAAAAAAAAAAAAAAAAAAAAA== - - - - - - KvS57lVwl13AfGFLwkvq4Q== - Root - - 48 - - 2016-12-31T21:33:52Z - 2016-12-31T21:33:52Z - 2017-01-01T22:58:00Z - 2016-12-31T21:33:52Z - False - 1 - 2016-12-31T21:33:52Z - - True - - null - null - AAAAAAAAAAAAAAAAAAAAAA== - - P0ParXgGMBW6caOL2YrhqQ== - Folder2 - a note about the folder - 48 - - 2016-12-31T21:43:30Z - 2016-12-31T21:43:43Z - 2017-01-01T22:58:00Z - 2016-12-31T21:43:30Z - False - 1 - 2016-12-31T21:43:43Z - - True - - null - null - AAAAAAAAAAAAAAAAAAAAAA== - - fAa543oYlgnJKkhKag5HLw== - 1 - - - - - - 2016-12-31T21:34:13Z - 2016-12-31T21:40:23Z - 2016-12-31T21:40:23Z - 2016-12-31T21:34:13Z - False - 0 - 2016-12-31T21:43:48Z - - - att2 - att2value - - - attr1 - att1value - -line1 -line2 - - - Notes - This is a note!!! - -line1 -line2 - - - Password - googpass - - - Title - Google - - - URL - google.com - - - UserName - googleuser - - - True - 0 - - - - fAa543oYlgnJKkhKag5HLw== - 0 - - - - - - 2016-12-31T21:34:13Z - 2016-12-31T21:34:40Z - 2016-12-31T21:34:40Z - 2016-12-31T21:34:13Z - False - 0 - 2016-12-31T21:34:40Z - - - Notes - This is a note!!! - -line1 -line2 - - - Password - googpass - - - Title - Google - - - URL - google.com - - - UserName - googleuser - - - True - 0 - - - - - - - - -`; - -describe("KeePass2 Xml Importer", () => { - it("should parse XML data", async () => { - const importer = new Importer(); - const result = await importer.parse(TestData); - expect(result != null).toBe(true); - }); -}); diff --git a/jslib/common/spec/importers/keeperJsonImporter.spec.ts b/jslib/common/spec/importers/keeperJsonImporter.spec.ts deleted file mode 100644 index 70b8f3c3..00000000 --- a/jslib/common/spec/importers/keeperJsonImporter.spec.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { KeeperJsonImporter as Importer } from "@/jslib/common/src/importers/keeperImporters/keeperJsonImporter"; -import { Utils } from "@/jslib/common/src/misc/utils"; - -import { testData as TestData } from "./testData/keeperJson/testData"; - -describe("Keeper Json Importer", () => { - const testDataJson = JSON.stringify(TestData); - - let importer: Importer; - beforeEach(() => { - importer = new Importer(); - }); - - it("should parse login data", async () => { - const result = await importer.parse(testDataJson); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.name).toEqual("Bank Account 1"); - expect(cipher.login.username).toEqual("customer1234"); - expect(cipher.login.password).toEqual("4813fJDHF4239fdk"); - expect(cipher.login.uris.length).toEqual(1); - const uriView = cipher.login.uris.shift(); - expect(uriView.uri).toEqual("https://chase.com"); - expect(cipher.notes).toEqual("These are some notes."); - - const cipher2 = result.ciphers.shift(); - expect(cipher2.name).toEqual("Bank Account 2"); - expect(cipher2.login.username).toEqual("mybankusername"); - expect(cipher2.login.password).toEqual("w4k4k193f$^&@#*%2"); - expect(cipher2.login.uris.length).toEqual(1); - const uriView2 = cipher2.login.uris.shift(); - expect(uriView2.uri).toEqual("https://amex.com"); - expect(cipher2.notes).toEqual("Some great information here."); - - const cipher3 = result.ciphers.shift(); - expect(cipher3.name).toEqual("Some Account"); - expect(cipher3.login.username).toEqual("someUserName"); - expect(cipher3.login.password).toEqual("w4k4k1wergf$^&@#*%2"); - expect(cipher3.notes).toBeNull(); - expect(cipher3.fields).toBeNull(); - expect(cipher3.login.uris.length).toEqual(1); - const uriView3 = cipher3.login.uris.shift(); - expect(uriView3.uri).toEqual("https://example.com"); - }); - - it("should import TOTP when present", async () => { - const result = await importer.parse(testDataJson); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.login.totp).toBeNull(); - - // 2nd Cipher - const cipher2 = result.ciphers.shift(); - expect(cipher2.login.totp).toEqual( - "otpauth://totp/Amazon:me@company.com?secret=JBSWY3DPEHPK3PXP&issuer=Amazon&algorithm=SHA1&digits=6&period=30" - ); - }); - - it("should parse custom fields", async () => { - const result = await importer.parse(testDataJson); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.fields.length).toBe(1); - expect(cipher.fields[0].name).toEqual("Account Number"); - expect(cipher.fields[0].value).toEqual("123-456-789"); - - // 2nd Cipher - const cipher2 = result.ciphers.shift(); - expect(cipher2.fields.length).toBe(2); - expect(cipher2.fields[0].name).toEqual("Security Group"); - expect(cipher2.fields[0].value).toEqual("Public"); - - expect(cipher2.fields[1].name).toEqual("IP Address"); - expect(cipher2.fields[1].value).toEqual("12.45.67.8"); - }); - - it("should create folders and assigned ciphers to them", async () => { - const result = await importer.parse(testDataJson); - expect(result != null).toBe(true); - - const folders = result.folders; - expect(folders.length).toBe(2); - expect(folders[0].name).toBe("Optional Private Folder 1"); - expect(folders[1].name).toBe("My Customer 1"); - - expect(result.folderRelationships[0]).toEqual([0, 0]); - expect(result.folderRelationships[1]).toEqual([1, 0]); - expect(result.folderRelationships[2]).toEqual([1, 1]); - }); - - it("should create collections if part of an organization", async () => { - importer.organizationId = Utils.newGuid(); - const result = await importer.parse(testDataJson); - expect(result != null).toBe(true); - - const collections = result.collections; - expect(collections.length).toBe(2); - expect(collections[0].name).toBe("Optional Private Folder 1"); - expect(collections[1].name).toBe("My Customer 1"); - - expect(result.collectionRelationships[0]).toEqual([0, 0]); - expect(result.collectionRelationships[1]).toEqual([1, 0]); - expect(result.collectionRelationships[2]).toEqual([1, 1]); - }); -}); diff --git a/jslib/common/spec/importers/lastpassCsvImporter.spec.ts b/jslib/common/spec/importers/lastpassCsvImporter.spec.ts deleted file mode 100644 index 5014d8c8..00000000 --- a/jslib/common/spec/importers/lastpassCsvImporter.spec.ts +++ /dev/null @@ -1,202 +0,0 @@ -import { CipherType } from "@/jslib/common/src/enums/cipherType"; -import { FieldType } from "@/jslib/common/src/enums/fieldType"; -import { LastPassCsvImporter as Importer } from "@/jslib/common/src/importers/lastpassCsvImporter"; -import { ImportResult } from "@/jslib/common/src/models/domain/importResult"; -import { CipherView } from "@/jslib/common/src/models/view/cipherView"; -import { FieldView } from "@/jslib/common/src/models/view/fieldView"; - -function baseExcept(result: ImportResult) { - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); -} - -function expectLogin(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Login); - - expect(cipher.name).toBe("example.com"); - expect(cipher.notes).toBe("super secure notes"); - expect(cipher.login.uri).toBe("http://example.com"); - expect(cipher.login.username).toBe("someUser"); - expect(cipher.login.password).toBe("myPassword"); - expect(cipher.login.totp).toBe("Y64VEVMBTSXCYIWRSHRNDZW62MPGVU2G"); -} - -const CipherData = [ - { - title: "should parse expiration date", - csv: `url,username,password,extra,name,grouping,fav -http://sn,,,"NoteType:Credit Card -Name on Card:John Doe -Type: -Number:1234567812345678 -Security Code:123 -Start Date:October,2017 -Expiration Date:June,2020 -Notes:some text -",Credit-card,,0`, - expected: Object.assign(new CipherView(), { - id: null, - organizationId: null, - folderId: null, - name: "Credit-card", - notes: "some text\n", - type: 3, - card: { - cardholderName: "John Doe", - number: "1234567812345678", - code: "123", - expYear: "2020", - expMonth: "6", - }, - fields: [ - Object.assign(new FieldView(), { - name: "Start Date", - value: "October,2017", - type: FieldType.Text, - }), - ], - }), - }, - { - title: "should parse blank card note", - csv: `url,username,password,extra,name,grouping,fav -http://sn,,,"NoteType:Credit Card -Name on Card: -Type: -Number: -Security Code: -Start Date:, -Expiration Date:, -Notes:",empty,,0`, - expected: Object.assign(new CipherView(), { - id: null, - organizationId: null, - folderId: null, - name: "empty", - notes: null, - type: 3, - card: { - expMonth: undefined, - }, - fields: [ - Object.assign(new FieldView(), { - name: "Start Date", - value: ",", - type: FieldType.Text, - }), - ], - }), - }, - { - title: "should parse card expiration date w/ no exp year", - csv: `url,username,password,extra,name,grouping,fav -http://sn,,,"NoteType:Credit Card -Name on Card:John Doe -Type:Visa -Number:1234567887654321 -Security Code:321 -Start Date:, -Expiration Date:January, -Notes:",noyear,,0`, - expected: Object.assign(new CipherView(), { - id: null, - organizationId: null, - folderId: null, - name: "noyear", - notes: null, - type: 3, - card: { - cardholderName: "John Doe", - number: "1234567887654321", - code: "321", - expMonth: "1", - }, - fields: [ - Object.assign(new FieldView(), { - name: "Type", - value: "Visa", - type: FieldType.Text, - }), - Object.assign(new FieldView(), { - name: "Start Date", - value: ",", - type: FieldType.Text, - }), - ], - }), - }, - { - title: "should parse card expiration date w/ no month", - csv: `url,username,password,extra,name,grouping,fav -http://sn,,,"NoteType:Credit Card -Name on Card:John Doe -Type:Mastercard -Number:8765432112345678 -Security Code:987 -Start Date:, -Expiration Date:,2020 -Notes:",nomonth,,0`, - expected: Object.assign(new CipherView(), { - id: null, - organizationId: null, - folderId: null, - name: "nomonth", - notes: null, - type: 3, - card: { - cardholderName: "John Doe", - number: "8765432112345678", - code: "987", - expYear: "2020", - expMonth: undefined, - }, - fields: [ - Object.assign(new FieldView(), { - name: "Type", - value: "Mastercard", - type: FieldType.Text, - }), - Object.assign(new FieldView(), { - name: "Start Date", - value: ",", - type: FieldType.Text, - }), - ], - }), - }, -]; - -describe("Lastpass CSV Importer", () => { - CipherData.forEach((data) => { - it(data.title, async () => { - const importer = new Importer(); - const result = await importer.parse(data.csv); - expect(result != null).toBe(true); - expect(result.ciphers.length).toBeGreaterThan(0); - - const cipher = result.ciphers.shift(); - let property: keyof typeof data.expected; - for (property in data.expected) { - // eslint-disable-next-line - if (data.expected.hasOwnProperty(property)) { - // eslint-disable-next-line - expect(cipher.hasOwnProperty(property)).toBe(true); - expect(cipher[property]).toEqual(data.expected[property]); - } - } - }); - }); - - it("should parse login with totp", async () => { - const input = `url,username,password,totp,extra,name,grouping,fav - http://example.com,someUser,myPassword,Y64VEVMBTSXCYIWRSHRNDZW62MPGVU2G,super secure notes,example.com,,0`; - - const importer = new Importer(); - const result = await importer.parse(input); - baseExcept(result); - - const cipher = result.ciphers[0]; - expectLogin(cipher); - }); -}); diff --git a/jslib/common/spec/importers/mykiCsvImporter.spec.ts b/jslib/common/spec/importers/mykiCsvImporter.spec.ts deleted file mode 100644 index 72283b3c..00000000 --- a/jslib/common/spec/importers/mykiCsvImporter.spec.ts +++ /dev/null @@ -1,633 +0,0 @@ -import { CipherType } from "@/jslib/common/src/enums/cipherType"; -import { MykiCsvImporter as Importer } from "@/jslib/common/src/importers/mykiCsvImporter"; -import { CipherView } from "@/jslib/common/src/models/view/cipherView"; - -import { userAccountData } from "./testData/mykiCsv/UserAccount.csv"; -import { userCreditCardData } from "./testData/mykiCsv/UserCreditCard.csv"; -import { userIdCardData } from "./testData/mykiCsv/UserIdCard.csv"; -import { userIdentityData } from "./testData/mykiCsv/UserIdentity.csv"; -import { userNoteData } from "./testData/mykiCsv/UserNote.csv"; -import { userTwoFaData } from "./testData/mykiCsv/UserTwofa.csv"; - -function expectDriversLicense(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Joe User's nickname"); - expect(cipher.notes).toBe("Additional information"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("123456"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Driver's License"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("02/02/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("02/02/2024"); -} - -function expectPassport(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Passport ID card"); - expect(cipher.notes).toBe("Additional information field"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.passportNumber).toBe("1234567"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Passport"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectSocialSecurity(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Social Security ID card"); - expect(cipher.notes).toBe("Additional information field text"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.ssn).toBe("123455678"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Social Security"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectIdCard(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("ID card type ID card"); - expect(cipher.notes).toBe("Additional Information field text"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("1234566"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("ID Card"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectTaxNumber(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Tax number ID card"); - expect(cipher.notes).toBe("Additinoal information text field"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("12345678"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Tax Number"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectBankAccount(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Bank account ID card"); - expect(cipher.notes).toBe("Additional text information here"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("12344556677"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Bank Account"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectInsuranceCard(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Insurance card ID card"); - expect(cipher.notes).toBe("Additional information text goes here"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("123456677"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Insurance Card"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2022"); -} - -function expectHealthCard(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Health card Id card"); - expect(cipher.notes).toBe("More info"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("1234670"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Health Card"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectMembershipCard(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Membership ID card"); - expect(cipher.notes).toBe("Add'l info"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("12345709"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Membership"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectDatabase(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Database ID card"); - expect(cipher.notes).toBe("Addin't info"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("12345089u"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Database"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectOutdoorLicense(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Outdoor license ID card"); - expect(cipher.notes).toBe("Additional info"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("123890090"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Outdoor License"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectRewardProgram(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Reward program Id card"); - expect(cipher.notes).toBe("1234890"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("12345890b"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Reward Program"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectSoftwareLicense(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Software license ID card"); - expect(cipher.notes).toBe( - "It seems like the fields don't change, which makes it pretty useless that they have so many ID card types." - ); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("1234567c"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Software License"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectTourVisa(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Tour visa ID card"); - expect(cipher.notes).toBe("Additional Informaion text"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("123456lkhj"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Tour Visa"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -describe("Myki CSV Importer", () => { - let importer: Importer; - beforeEach(() => { - importer = new Importer(); - }); - - it("should parse userAccount records", async () => { - const result = await importer.parse(userAccountData); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - - expect(cipher.name).toEqual("PasswordNickname"); - expect(cipher.login.username).toEqual("user.name@email.com"); - expect(cipher.login.password).toEqual("abc123"); - expect(cipher.login.totp).toEqual("someTOTPSeed"); - expect(cipher.login.uris.length).toEqual(1); - const uriView = cipher.login.uris.shift(); - expect(uriView.uri).toEqual("http://www.google.com"); - expect(cipher.notes).toEqual("This is the additional information text."); - - expect(cipher.fields.length).toBe(2); - - expect(cipher.fields[0].name).toBe("status"); - expect(cipher.fields[0].value).toBe("active"); - - expect(cipher.fields[1].name).toBe("tags"); - expect(cipher.fields[1].value).toBe("someTag"); - }); - - it("should parse userTwoFa records", async () => { - const result = await importer.parse(userTwoFaData); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - - expect(cipher.name).toEqual("2FA nickname"); - expect(cipher.login.username).toBeNull(); - expect(cipher.login.password).toBeNull(); - expect(cipher.login.totp).toBe("someTOTPSeed"); - expect(cipher.notes).toEqual("Additional information field content."); - - expect(cipher.fields.length).toBe(2); - - expect(cipher.fields[0].name).toBe("status"); - expect(cipher.fields[0].value).toBe("active"); - - expect(cipher.fields[1].name).toBe("tags"); - expect(cipher.fields[1].value).toBe("someTag"); - }); - - it("should parse creditCard records", async () => { - const result = await importer.parse(userCreditCardData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - - const cipher = result.ciphers.shift(); - expect(cipher.type).toBe(CipherType.Card); - expect(cipher.name).toBe("Visa test card"); - expect(cipher.card.brand).toBe("Visa"); - expect(cipher.card.cardholderName).toBe("Joe User"); - expect(cipher.card.number).toBe("4111111111111111"); - expect(cipher.card.code).toBe("222"); - expect(cipher.card.expMonth).toBe("04"); - expect(cipher.card.expYear).toBe("24"); - - expect(cipher.notes).toBe("This is the additional information field"); - - expect(cipher.fields.length).toBe(2); - - expect(cipher.fields[0].name).toBe("status"); - expect(cipher.fields[0].value).toBe("active"); - - expect(cipher.fields[1].name).toBe("tags"); - expect(cipher.fields[1].value).toBe("someTag"); - }); - - it("should parse identity records", async () => { - const result = await importer.parse(userIdentityData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Joe User's nickname"); - expect(cipher.identity.fullName).toBe("Mr Joe M User"); - expect(cipher.identity.title).toBe("Mr"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.email).toBe("joe.user@email.com"); - - expect(cipher.identity.address1).toBe("1 Example House"); - expect(cipher.identity.address2).toBe("Suite 300"); - - expect(cipher.identity.city).toBe("Portland"); - expect(cipher.identity.postalCode).toBe("04101"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(4); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toBe("tags"); - expect(cipher.fields[1].value).toBe("someTag"); - - expect(cipher.fields[2].name).toEqual("gender"); - expect(cipher.fields[2].value).toEqual("Male"); - - expect(cipher.fields[3].name).toEqual("number"); - expect(cipher.fields[3].value).toEqual("2223334444"); - }); - - it("should parse secureNote records", async () => { - const result = await importer.parse(userNoteData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - - const cipher = result.ciphers.shift(); - expect(cipher.type).toBe(CipherType.SecureNote); - expect(cipher.name).toBe("The title of a secure note"); - expect(cipher.notes).toBe("The content of a secure note. Lorem ipsum, etc."); - - expect(cipher.fields.length).toBe(1); - - expect(cipher.fields[0].name).toBe("status"); - expect(cipher.fields[0].value).toBe("active"); - }); - - it("should parse idCard records", async () => { - const result = await importer.parse(userIdCardData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - - expect(result.ciphers.length).toBe(14); - - // Driver's license - const cipher = result.ciphers.shift(); - expectDriversLicense(cipher); - - // Passport - const cipher2 = result.ciphers.shift(); - expectPassport(cipher2); - - // Social Security - const cipher3 = result.ciphers.shift(); - expectSocialSecurity(cipher3); - - // Id Card - const cipher4 = result.ciphers.shift(); - expectIdCard(cipher4); - - // Tax Number - const cipher5 = result.ciphers.shift(); - expectTaxNumber(cipher5); - - // Bank Account - const cipher6 = result.ciphers.shift(); - expectBankAccount(cipher6); - - // Insurance card - const cipher7 = result.ciphers.shift(); - expectInsuranceCard(cipher7); - - // Health card - const cipher8 = result.ciphers.shift(); - expectHealthCard(cipher8); - - // Membership card - const cipher9 = result.ciphers.shift(); - expectMembershipCard(cipher9); - - // Database card - const cipher10 = result.ciphers.shift(); - expectDatabase(cipher10); - - // Outdoor license - const cipher11 = result.ciphers.shift(); - expectOutdoorLicense(cipher11); - - // Reward program - const cipher12 = result.ciphers.shift(); - expectRewardProgram(cipher12); - - // Software license - const cipher13 = result.ciphers.shift(); - expectSoftwareLicense(cipher13); - - // Tour visa - const cipher14 = result.ciphers.shift(); - expectTourVisa(cipher14); - }); -}); diff --git a/jslib/common/spec/importers/nordpassCsvImporter.spec.ts b/jslib/common/spec/importers/nordpassCsvImporter.spec.ts deleted file mode 100644 index 1c1f14cd..00000000 --- a/jslib/common/spec/importers/nordpassCsvImporter.spec.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { CipherType } from "@/jslib/common/src/enums/cipherType"; -import { SecureNoteType } from "@/jslib/common/src/enums/secureNoteType"; -import { NordPassCsvImporter as Importer } from "@/jslib/common/src/importers/nordpassCsvImporter"; -import { CipherView } from "@/jslib/common/src/models/view/cipherView"; -import { IdentityView } from "@/jslib/common/src/models/view/identityView"; - -import { data as creditCardData } from "./testData/nordpassCsv/nordpass.card.csv"; -import { data as identityData } from "./testData/nordpassCsv/nordpass.identity.csv"; -import { data as loginData } from "./testData/nordpassCsv/nordpass.login.csv"; -import { data as secureNoteData } from "./testData/nordpassCsv/nordpass.secureNote.csv"; - -const namesTestData = [ - { - title: "Given #fullName should set firstName", - fullName: "MyFirstName", - expected: Object.assign(new IdentityView(), { - firstName: "MyFirstName", - middleName: null, - lastName: null, - }), - }, - { - title: "Given #fullName should set first- and lastName", - fullName: "MyFirstName MyLastName", - expected: Object.assign(new IdentityView(), { - firstName: "MyFirstName", - middleName: null, - lastName: "MyLastName", - }), - }, - { - title: "Given #fullName should set first-, middle and lastName", - fullName: "MyFirstName MyMiddleName MyLastName", - expected: Object.assign(new IdentityView(), { - firstName: "MyFirstName", - middleName: "MyMiddleName", - lastName: "MyLastName", - }), - }, - { - title: "Given #fullName should set first-, middle and lastName with Jr", - fullName: "MyFirstName MyMiddleName MyLastName Jr", - expected: Object.assign(new IdentityView(), { - firstName: "MyFirstName", - middleName: "MyMiddleName", - lastName: "MyLastName Jr", - }), - }, - { - title: "Given #fullName should set first-, middle and lastName with Jr and III", - fullName: "MyFirstName MyMiddleName MyLastName Jr III", - expected: Object.assign(new IdentityView(), { - firstName: "MyFirstName", - middleName: "MyMiddleName", - lastName: "MyLastName Jr III", - }), - }, -]; - -function expectLogin(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Login); - - expect(cipher.name).toBe("SomeVaultItemName"); - expect(cipher.notes).toBe("Some note for the VaultItem"); - expect(cipher.login.uri).toBe("https://example.com"); - expect(cipher.login.username).toBe("hello@bitwarden.com"); - expect(cipher.login.password).toBe("someStrongPassword"); -} - -function expectCreditCard(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Card); - - expect(cipher.name).toBe("SomeVisa"); - expect(cipher.card.brand).toBe("Visa"); - expect(cipher.card.cardholderName).toBe("SomeHolder"); - expect(cipher.card.number).toBe("4024007103939509"); - expect(cipher.card.code).toBe("123"); - expect(cipher.card.expMonth).toBe("1"); - expect(cipher.card.expYear).toBe("22"); -} - -function expectIdentity(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - - expect(cipher.name).toBe("SomeTitle"); - expect(cipher.identity.fullName).toBe("MyFirstName MyMiddleName MyLastName"); - expect(cipher.identity.firstName).toBe("MyFirstName"); - expect(cipher.identity.middleName).toBe("MyMiddleName"); - expect(cipher.identity.lastName).toBe("MyLastName"); - expect(cipher.identity.email).toBe("hello@bitwarden.com"); - expect(cipher.identity.phone).toBe("123456789"); - - expect(cipher.identity.address1).toBe("Test street 123"); - expect(cipher.identity.address2).toBe("additional addressinfo"); - expect(cipher.identity.postalCode).toBe("123456"); - expect(cipher.identity.city).toBe("Cologne"); - expect(cipher.identity.state).toBe("North-Rhine-Westphalia"); - expect(cipher.identity.country).toBe("GERMANY"); - expect(cipher.notes).toBe("SomeNoteToMyIdentity"); -} - -function expectSecureNote(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.SecureNote); - - expect(cipher.name).toBe("MySuperSecureNoteTitle"); - expect(cipher.secureNote.type).toBe(SecureNoteType.Generic); - expect(cipher.notes).toBe("MySuperSecureNote"); -} - -describe("NordPass CSV Importer", () => { - let importer: Importer; - beforeEach(() => { - importer = new Importer(); - }); - - it("should parse login records", async () => { - const result = await importer.parse(loginData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - const cipher = result.ciphers[0]; - expectLogin(cipher); - }); - - it("should parse credit card records", async () => { - const result = await importer.parse(creditCardData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - const cipher = result.ciphers[0]; - expectCreditCard(cipher); - }); - - it("should parse identity records", async () => { - const result = await importer.parse( - identityData.replace("#fullName", "MyFirstName MyMiddleName MyLastName") - ); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - const cipher = result.ciphers[0]; - expectIdentity(cipher); - }); - - namesTestData.forEach((data) => { - it(data.title.replace("#fullName", data.fullName), async () => { - const result = await importer.parse(identityData.replace("#fullName", data.fullName)); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - const cipher = result.ciphers[0]; - expect(cipher.identity.firstName).toBe(data.expected.firstName); - expect(cipher.identity.middleName).toBe(data.expected.middleName); - expect(cipher.identity.lastName).toBe(data.expected.lastName); - }); - }); - - it("should parse secureNote records", async () => { - const result = await importer.parse(secureNoteData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - const cipher = result.ciphers[0]; - expectSecureNote(cipher); - }); - - it("should parse an item and create a folder", async () => { - const result = await importer.parse(secureNoteData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.folders.length).toBe(1); - const folder = result.folders[0]; - expect(folder.name).toBe("notesFolder"); - }); -}); diff --git a/jslib/common/spec/importers/onepassword1PifImporter.spec.ts b/jslib/common/spec/importers/onepassword1PifImporter.spec.ts deleted file mode 100644 index 739b0fad..00000000 --- a/jslib/common/spec/importers/onepassword1PifImporter.spec.ts +++ /dev/null @@ -1,527 +0,0 @@ -import { FieldType } from "@/jslib/common/src/enums/fieldType"; -import { OnePassword1PifImporter as Importer } from "@/jslib/common/src/importers/onepasswordImporters/onepassword1PifImporter"; - -const TestData: string = - "***aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee***\n" + - JSON.stringify({ - uuid: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - updatedAt: 1486071244, - securityLevel: "SL5", - contentsHash: "aaaaaaaa", - title: "Imported Entry", - location: "https://www.google.com", - secureContents: { - fields: [ - { - value: "user@test.net", - id: "email-input", - name: "email", - type: "T", - designation: "username", - }, - { - value: "myservicepassword", - id: "password-input", - name: "password", - type: "P", - designation: "password", - }, - ], - sections: [ - { - fields: [ - { - k: "concealed", - n: "AAAAAAAAAAAABBBBBBBBBBBCCCCCCCCC", - v: "console-password-123", - t: "console password", - }, - ], - title: "Admin Console", - name: "admin_console", - }, - ], - passwordHistory: [ - { - value: "old-password", - time: 1447791421, - }, - ], - }, - URLs: [ - { - label: "website", - url: "https://www.google.com", - }, - ], - txTimestamp: 1508941334, - createdAt: 1390426636, - typeName: "webforms.WebForm", - }); - -const WindowsOpVaultTestData = JSON.stringify({ - category: "001", - created: 1544823719, - hmac: "NtyBmTTPOb88HV3JUKPx1xl/vcMhac9kvCfe/NtszY0=", - k: "**REMOVED LONG LINE FOR LINTER** -Kyle", - tx: 1553395669, - updated: 1553395669, - uuid: "528AB076FB5F4FBF960884B8E01619AC", - overview: { - title: "Google", - URLs: [ - { - u: "google.com", - }, - ], - url: "google.com", - ps: 26, - ainfo: "googluser", - }, - details: { - passwordHistory: [ - { - value: "oldpass1", - time: 1553394449, - }, - { - value: "oldpass2", - time: 1553394457, - }, - { - value: "oldpass3", - time: 1553394458, - }, - { - value: "oldpass4", - time: 1553394459, - }, - { - value: "oldpass5", - time: 1553394460, - }, - { - value: "oldpass6", - time: 1553394461, - }, - ], - fields: [ - { - type: "T", - id: "username", - name: "username", - value: "googluser", - designation: "username", - }, - { - type: "P", - id: "password", - name: "password", - value: "12345678901", - designation: "password", - }, - ], - notesPlain: "This is a note\r\n\r\nline1\r\nline2", - sections: [ - { - title: "test", - name: "1214FD88CD30405D9EED14BEB4D61B60", - fields: [ - { - k: "string", - n: "6CC3BD77482D4559A4B8BB2D360F821B", - v: "fgfg", - t: "fgggf", - }, - { - k: "concealed", - n: "5CFE7BCAA1DF4578BBF7EB508959BFF3", - v: "dfgdfgfdg", - t: "pwfield", - }, - ], - }, - ], - }, -}); - -const IdentityTestData = JSON.stringify({ - uuid: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - updatedAt: 1553365894, - securityLevel: "SL5", - contentsHash: "eeeeeeee", - title: "Test Identity", - secureContents: { - lastname: "Fritzenberger", - zip: "223344", - birthdate_dd: "11", - homephone: "+49 333 222 111", - company: "Web Inc.", - firstname: "Frank", - birthdate_mm: "3", - country: "de", - sex: "male", - sections: [ - { - fields: [ - { - k: "string", - inputTraits: { - autocapitalization: "Words", - }, - n: "firstname", - v: "Frank", - a: { - guarded: "yes", - }, - t: "first name", - }, - { - k: "string", - inputTraits: { - autocapitalization: "Words", - }, - n: "initial", - v: "MD", - a: { - guarded: "yes", - }, - t: "initial", - }, - { - k: "string", - inputTraits: { - autocapitalization: "Words", - }, - n: "lastname", - v: "Fritzenberger", - a: { - guarded: "yes", - }, - t: "last name", - }, - { - k: "menu", - v: "male", - n: "sex", - a: { - guarded: "yes", - }, - t: "sex", - }, - { - k: "date", - v: 1552305660, - n: "birthdate", - a: { - guarded: "yes", - }, - t: "birth date", - }, - { - k: "string", - inputTraits: { - autocapitalization: "Words", - }, - n: "occupation", - v: "Engineer", - a: { - guarded: "yes", - }, - t: "occupation", - }, - { - k: "string", - inputTraits: { - autocapitalization: "Words", - }, - n: "company", - v: "Web Inc.", - a: { - guarded: "yes", - }, - t: "company", - }, - { - k: "string", - inputTraits: { - autocapitalization: "Words", - }, - n: "department", - v: "IT", - a: { - guarded: "yes", - }, - t: "department", - }, - { - k: "string", - inputTraits: { - autocapitalization: "Words", - }, - n: "jobtitle", - v: "Developer", - a: { - guarded: "yes", - }, - t: "job title", - }, - ], - title: "Identification", - name: "name", - }, - { - fields: [ - { - k: "address", - inputTraits: { - autocapitalization: "Sentences", - }, - n: "address", - v: { - street: "Mainstreet 1", - city: "Berlin", - country: "de", - zip: "223344", - }, - a: { - guarded: "yes", - }, - t: "address", - }, - { - k: "phone", - v: "+49 001 222 333 44", - n: "defphone", - a: { - guarded: "yes", - }, - t: "default phone", - }, - { - k: "phone", - v: "+49 333 222 111", - n: "homephone", - a: { - guarded: "yes", - }, - t: "home", - }, - { - k: "phone", - n: "cellphone", - a: { - guarded: "yes", - }, - t: "mobile", - }, - { - k: "phone", - n: "busphone", - a: { - guarded: "yes", - }, - t: "business", - }, - ], - title: "Address", - name: "address", - }, - { - fields: [ - { - k: "string", - n: "username", - a: { - guarded: "yes", - }, - t: "username", - }, - { - k: "string", - n: "reminderq", - t: "reminder question", - }, - { - k: "string", - n: "remindera", - t: "reminder answer", - }, - { - k: "string", - inputTraits: { - keyboard: "EmailAddress", - }, - n: "email", - v: "test@web.de", - a: { - guarded: "yes", - }, - t: "email", - }, - { - k: "string", - n: "website", - inputTraits: { - keyboard: "URL", - }, - t: "website", - }, - { - k: "string", - n: "icq", - t: "ICQ", - }, - { - k: "string", - n: "skype", - t: "skype", - }, - { - k: "string", - n: "aim", - t: "AOL/AIM", - }, - { - k: "string", - n: "yahoo", - t: "Yahoo", - }, - { - k: "string", - n: "msn", - t: "MSN", - }, - { - k: "string", - n: "forumsig", - t: "forum signature", - }, - ], - title: "Internet Details", - name: "internet", - }, - { - title: "Related Items", - name: "linked items", - }, - ], - initial: "MD", - address1: "Mainstreet 1", - city: "Berlin", - jobtitle: "Developer", - occupation: "Engineer", - department: "IT", - email: "test@web.de", - birthdate_yy: "2019", - homephone_local: "+49 333 222 111", - defphone_local: "+49 001 222 333 44", - defphone: "+49 001 222 333 44", - }, - txTimestamp: 1553365894, - createdAt: 1553364679, - typeName: "identities.Identity", -}); - -describe("1Password 1Pif Importer", () => { - it("should parse data", async () => { - const importer = new Importer(); - const result = await importer.parse(TestData); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.login.username).toEqual("user@test.net"); - expect(cipher.login.password).toEqual("myservicepassword"); - expect(cipher.login.uris.length).toEqual(1); - const uriView = cipher.login.uris.shift(); - expect(uriView.uri).toEqual("https://www.google.com"); - }); - - it('should create concealed field as "hidden" type', async () => { - const importer = new Importer(); - const result = await importer.parse(TestData); - expect(result != null).toBe(true); - - const ciphers = result.ciphers; - expect(ciphers.length).toEqual(1); - - const cipher = ciphers.shift(); - const fields = cipher.fields; - expect(fields.length).toEqual(1); - - const field = fields.shift(); - expect(field.name).toEqual("console password"); - expect(field.value).toEqual("console-password-123"); - expect(field.type).toEqual(FieldType.Hidden); - }); - - it("should create identity records", async () => { - const importer = new Importer(); - const result = await importer.parse(IdentityTestData); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.name).toEqual("Test Identity"); - - const identity = cipher.identity; - expect(identity.firstName).toEqual("Frank"); - expect(identity.middleName).toEqual("MD"); - expect(identity.lastName).toEqual("Fritzenberger"); - expect(identity.company).toEqual("Web Inc."); - expect(identity.address1).toEqual("Mainstreet 1"); - expect(identity.country).toEqual("DE"); - expect(identity.city).toEqual("Berlin"); - expect(identity.postalCode).toEqual("223344"); - expect(identity.phone).toEqual("+49 001 222 333 44"); - expect(identity.email).toEqual("test@web.de"); - - // remaining fields as custom fields - expect(cipher.fields.length).toEqual(6); - const fields = cipher.fields; - expect(fields[0].name).toEqual("sex"); - expect(fields[0].value).toEqual("male"); - expect(fields[1].name).toEqual("birth date"); - expect(fields[1].value).toEqual("Mon, 11 Mar 2019 12:01:00 GMT"); - expect(fields[2].name).toEqual("occupation"); - expect(fields[2].value).toEqual("Engineer"); - expect(fields[3].name).toEqual("department"); - expect(fields[3].value).toEqual("IT"); - expect(fields[4].name).toEqual("job title"); - expect(fields[4].value).toEqual("Developer"); - expect(fields[5].name).toEqual("home"); - expect(fields[5].value).toEqual("+49 333 222 111"); - }); - - it("should create password history", async () => { - const importer = new Importer(); - const result = await importer.parse(TestData); - const cipher = result.ciphers.shift(); - - expect(cipher.passwordHistory.length).toEqual(1); - const ph = cipher.passwordHistory.shift(); - expect(ph.password).toEqual("old-password"); - expect(ph.lastUsedDate.toISOString()).toEqual("2015-11-17T20:17:01.000Z"); - }); - - it("should create password history from windows opvault 1pif format", async () => { - const importer = new Importer(); - const result = await importer.parse(WindowsOpVaultTestData); - const cipher = result.ciphers.shift(); - - expect(cipher.passwordHistory.length).toEqual(5); - let ph = cipher.passwordHistory.shift(); - expect(ph.password).toEqual("oldpass6"); - expect(ph.lastUsedDate.toISOString()).toEqual("2019-03-24T02:27:41.000Z"); - ph = cipher.passwordHistory.shift(); - expect(ph.password).toEqual("oldpass5"); - expect(ph.lastUsedDate.toISOString()).toEqual("2019-03-24T02:27:40.000Z"); - ph = cipher.passwordHistory.shift(); - expect(ph.password).toEqual("oldpass4"); - expect(ph.lastUsedDate.toISOString()).toEqual("2019-03-24T02:27:39.000Z"); - ph = cipher.passwordHistory.shift(); - expect(ph.password).toEqual("oldpass3"); - expect(ph.lastUsedDate.toISOString()).toEqual("2019-03-24T02:27:38.000Z"); - ph = cipher.passwordHistory.shift(); - expect(ph.password).toEqual("oldpass2"); - expect(ph.lastUsedDate.toISOString()).toEqual("2019-03-24T02:27:37.000Z"); - }); -}); diff --git a/jslib/common/spec/importers/onepassword1PuxImporter.spec.ts b/jslib/common/spec/importers/onepassword1PuxImporter.spec.ts deleted file mode 100644 index 2d73ffea..00000000 --- a/jslib/common/spec/importers/onepassword1PuxImporter.spec.ts +++ /dev/null @@ -1,689 +0,0 @@ -import { CipherType } from "@/jslib/common/src/enums/cipherType"; -import { FieldType } from "@/jslib/common/src/enums/fieldType"; -import { SecureNoteType } from "@/jslib/common/src/enums/secureNoteType"; -import { OnePassword1PuxImporter as Importer } from "@/jslib/common/src/importers/onepasswordImporters/onepassword1PuxImporter"; -import { Utils } from "@/jslib/common/src/misc/utils"; -import { FieldView } from "@/jslib/common/src/models/view/fieldView"; - -import { APICredentialsData } from "./testData/onePassword1Pux/APICredentials"; -import { BankAccountData } from "./testData/onePassword1Pux/BankAccount"; -import { CreditCardData } from "./testData/onePassword1Pux/CreditCard"; -import { DatabaseData } from "./testData/onePassword1Pux/Database"; -import { DriversLicenseData } from "./testData/onePassword1Pux/DriversLicense"; -import { EmailAccountData } from "./testData/onePassword1Pux/EmailAccount"; -import { EmailFieldData } from "./testData/onePassword1Pux/Emailfield"; -import { EmailFieldOnIdentityData } from "./testData/onePassword1Pux/EmailfieldOnIdentity"; -import { EmailFieldOnIdentityPrefilledData } from "./testData/onePassword1Pux/EmailfieldOnIdentity_Prefilled"; -import { IdentityData } from "./testData/onePassword1Pux/IdentityData"; -import { LoginData } from "./testData/onePassword1Pux/LoginData"; -import { MedicalRecordData } from "./testData/onePassword1Pux/MedicalRecord"; -import { MembershipData } from "./testData/onePassword1Pux/Membership"; -import { OnePuxExampleFile } from "./testData/onePassword1Pux/Onepux_example"; -import { OutdoorLicenseData } from "./testData/onePassword1Pux/OutdoorLicense"; -import { PassportData } from "./testData/onePassword1Pux/Passport"; -import { PasswordData } from "./testData/onePassword1Pux/Password"; -import { RewardsProgramData } from "./testData/onePassword1Pux/RewardsProgram"; -import { SSNData } from "./testData/onePassword1Pux/SSN"; -import { SanitizedExport } from "./testData/onePassword1Pux/SanitizedExport"; -import { SecureNoteData } from "./testData/onePassword1Pux/SecureNote"; -import { ServerData } from "./testData/onePassword1Pux/Server"; -import { SoftwareLicenseData } from "./testData/onePassword1Pux/SoftwareLicense"; -import { WirelessRouterData } from "./testData/onePassword1Pux/WirelessRouter"; - -function validateCustomField(fields: FieldView[], fieldName: string, expectedValue: any) { - expect(fields).toBeDefined(); - const customField = fields.find((f) => f.name === fieldName); - expect(customField).toBeDefined(); - - expect(customField.value).toEqual(expectedValue); -} - -describe("1Password 1Pux Importer", () => { - const OnePuxExampleFileJson = JSON.stringify(OnePuxExampleFile); - const LoginDataJson = JSON.stringify(LoginData); - const CreditCardDataJson = JSON.stringify(CreditCardData); - const IdentityDataJson = JSON.stringify(IdentityData); - const SecureNoteDataJson = JSON.stringify(SecureNoteData); - const SanitizedExportJson = JSON.stringify(SanitizedExport); - - it("should parse login data", async () => { - const importer = new Importer(); - const result = await importer.parse(LoginDataJson); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Login); - expect(cipher.name).toEqual("eToro"); - - expect(cipher.login.username).toEqual("username123123123@gmail.com"); - expect(cipher.login.password).toEqual("password!"); - expect(cipher.login.uris.length).toEqual(1); - expect(cipher.login.uri).toEqual("https://www.fakesite.com"); - expect(cipher.login.totp).toEqual("otpseed777"); - - // remaining fields as custom fields - expect(cipher.fields.length).toEqual(3); - validateCustomField(cipher.fields, "terms", "false"); - validateCustomField(cipher.fields, "policies", "true"); - validateCustomField(cipher.fields, "cyqyggt2otns6tbbqtsl6w2ceu", "username123123"); - }); - - it("should parse notes", async () => { - const importer = new Importer(); - const result = await importer.parse(OnePuxExampleFileJson); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.notes).toEqual("This is a note. *bold*! _italic_!"); - }); - - it("should set favourite if favIndex equals 1", async () => { - const importer = new Importer(); - const result = await importer.parse(OnePuxExampleFileJson); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.favorite).toBe(true); - }); - - it("should handle custom boolean fields", async () => { - const importer = new Importer(); - const result = await importer.parse(LoginDataJson); - expect(result != null).toBe(true); - - const ciphers = result.ciphers; - expect(ciphers.length).toEqual(1); - - const cipher = ciphers.shift(); - expect(cipher.fields[0].name).toEqual("terms"); - expect(cipher.fields[0].value).toEqual("false"); - expect(cipher.fields[0].type).toBe(FieldType.Boolean); - - expect(cipher.fields[1].name).toEqual("policies"); - expect(cipher.fields[1].value).toEqual("true"); - expect(cipher.fields[1].type).toBe(FieldType.Boolean); - }); - - it("should add fields of type email as custom fields", async () => { - const importer = new Importer(); - const EmailFieldDataJson = JSON.stringify(EmailFieldData); - const result = await importer.parse(EmailFieldDataJson); - expect(result != null).toBe(true); - - const ciphers = result.ciphers; - expect(ciphers.length).toEqual(1); - const cipher = ciphers.shift(); - - expect(cipher.fields[0].name).toEqual("reg_email"); - expect(cipher.fields[0].value).toEqual("kriddler@nullvalue.test"); - expect(cipher.fields[0].type).toBe(FieldType.Text); - - expect(cipher.fields[1].name).toEqual("provider"); - expect(cipher.fields[1].value).toEqual("myEmailProvider"); - expect(cipher.fields[1].type).toBe(FieldType.Text); - }); - - it('should create concealed field as "hidden" type', async () => { - const importer = new Importer(); - const result = await importer.parse(OnePuxExampleFileJson); - expect(result != null).toBe(true); - - const ciphers = result.ciphers; - expect(ciphers.length).toEqual(1); - - const cipher = ciphers.shift(); - const fields = cipher.fields; - expect(fields.length).toEqual(1); - - const field = fields.shift(); - expect(field.name).toEqual("PIN"); - expect(field.value).toEqual("12345"); - expect(field.type).toEqual(FieldType.Hidden); - }); - - it("should create password history", async () => { - const importer = new Importer(); - const result = await importer.parse(OnePuxExampleFileJson); - const cipher = result.ciphers.shift(); - - expect(cipher.passwordHistory.length).toEqual(1); - const ph = cipher.passwordHistory.shift(); - expect(ph.password).toEqual("12345password"); - expect(ph.lastUsedDate.toISOString()).toEqual("2016-03-18T17:32:35.000Z"); - }); - - it("should create credit card records", async () => { - const importer = new Importer(); - const result = await importer.parse(CreditCardDataJson); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.name).toEqual("Parent's Credit Card"); - expect(cipher.notes).toEqual("My parents' credit card."); - - const card = cipher.card; - expect(card.cardholderName).toEqual("Fred Engels"); - expect(card.number).toEqual("6011111111111117"); - expect(card.code).toEqual("1312"); - expect(card.brand).toEqual("Discover"); - expect(card.expMonth).toEqual("12"); - expect(card.expYear).toEqual("2099"); - - // remaining fields as custom fields - expect(cipher.fields.length).toEqual(12); - validateCustomField(cipher.fields, "txbzvwzpck7ejhfres3733rbpm", "card"); - validateCustomField(cipher.fields, "cashLimit", "$500"); - validateCustomField(cipher.fields, "creditLimit", "$1312"); - validateCustomField(cipher.fields, "validFrom", "200101"); - validateCustomField(cipher.fields, "bank", "Some bank"); - validateCustomField(cipher.fields, "phoneLocal", "123456"); - validateCustomField(cipher.fields, "phoneTollFree", "0800123456"); - validateCustomField(cipher.fields, "phoneIntl", "+49123456"); - validateCustomField(cipher.fields, "website", "somebank.com"); - validateCustomField(cipher.fields, "pin", "1234"); - validateCustomField(cipher.fields, "interest", "1%"); - validateCustomField(cipher.fields, "issuenumber", "123456"); - }); - - it("should create identity records", async () => { - const importer = new Importer(); - const result = await importer.parse(IdentityDataJson); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.name).toEqual("George Engels"); - - const identity = cipher.identity; - expect(identity.firstName).toEqual("George"); - expect(identity.middleName).toEqual("S"); - expect(identity.lastName).toEqual("Engels"); - expect(identity.company).toEqual("Acme Inc."); - expect(identity.address1).toEqual("1312 Main St."); - expect(identity.country).toEqual("US"); - expect(identity.state).toEqual("California"); - expect(identity.city).toEqual("Atlantis"); - expect(identity.postalCode).toEqual("90210"); - expect(identity.phone).toEqual("4565555555"); - expect(identity.email).toEqual("gengels@nullvalue.test"); - expect(identity.username).toEqual("gengels"); - - // remaining fields as custom fields - expect(cipher.fields.length).toEqual(17); - validateCustomField(cipher.fields, "sex", "male"); - validateCustomField(cipher.fields, "birthdate", "Thu, 01 Jan 1981 12:01:00 GMT"); - validateCustomField(cipher.fields, "occupation", "Steel Worker"); - validateCustomField(cipher.fields, "department", "QA"); - validateCustomField(cipher.fields, "jobtitle", "Quality Assurance Manager"); - validateCustomField(cipher.fields, "homephone", "4575555555"); - validateCustomField(cipher.fields, "cellphone", "4585555555"); - validateCustomField(cipher.fields, "busphone", "4595555555"); - validateCustomField(cipher.fields, "reminderq", "Who's a super cool guy?"); - validateCustomField(cipher.fields, "remindera", "Me, buddy."); - validateCustomField(cipher.fields, "website", "cv.gengels.nullvalue.test"); - validateCustomField(cipher.fields, "icq", "12345678"); - validateCustomField(cipher.fields, "skype", "skypeisbad1619"); - validateCustomField(cipher.fields, "aim", "aollol@lololol.aol.com"); - validateCustomField(cipher.fields, "yahoo", "sk8rboi13@yah00.com"); - validateCustomField(cipher.fields, "msn", "msnothankyou@msn&m&m.com"); - validateCustomField(cipher.fields, "forumsig", "super cool guy"); - }); - - it("emails fields on identity types should be added to the identity email field", async () => { - const importer = new Importer(); - const EmailFieldOnIdentityDataJson = JSON.stringify(EmailFieldOnIdentityData); - const result = await importer.parse(EmailFieldOnIdentityDataJson); - expect(result != null).toBe(true); - - const ciphers = result.ciphers; - expect(ciphers.length).toEqual(1); - const cipher = ciphers.shift(); - - const identity = cipher.identity; - expect(identity.email).toEqual("gengels@nullvalue.test"); - - expect(cipher.fields[0].name).toEqual("provider"); - expect(cipher.fields[0].value).toEqual("myEmailProvider"); - expect(cipher.fields[0].type).toBe(FieldType.Text); - }); - - it("emails fields on identity types should be added to custom fields if identity.email has been filled", async () => { - const importer = new Importer(); - const EmailFieldOnIdentityPrefilledDataJson = JSON.stringify(EmailFieldOnIdentityPrefilledData); - const result = await importer.parse(EmailFieldOnIdentityPrefilledDataJson); - expect(result != null).toBe(true); - - const ciphers = result.ciphers; - expect(ciphers.length).toEqual(1); - const cipher = ciphers.shift(); - - const identity = cipher.identity; - expect(identity.email).toEqual("gengels@nullvalue.test"); - - expect(cipher.fields[0].name).toEqual("2nd_email"); - expect(cipher.fields[0].value).toEqual("kriddler@nullvalue.test"); - expect(cipher.fields[0].type).toBe(FieldType.Text); - - expect(cipher.fields[1].name).toEqual("provider"); - expect(cipher.fields[1].value).toEqual("myEmailProvider"); - expect(cipher.fields[1].type).toBe(FieldType.Text); - }); - - it("should parse category 005 - Password (Legacy)", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(PasswordData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.type).toEqual(CipherType.Login); - expect(cipher.name).toEqual("SuperSecret Password"); - expect(cipher.notes).toEqual("SuperSecret Password Notes"); - - expect(cipher.login.password).toEqual("GBq[AGb]4*Si3tjwuab^"); - expect(cipher.login.uri).toEqual("https://n0t.y0ur.n0rm4l.w3bs1t3"); - }); - - it("should parse category 100 - SoftwareLicense", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(SoftwareLicenseData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.type).toEqual(CipherType.SecureNote); - expect(cipher.name).toEqual("Limux Product Key"); - expect(cipher.notes).toEqual("My Software License"); - - expect(cipher.fields.length).toEqual(13); - validateCustomField(cipher.fields, "product_version", "5.10.1000"); - validateCustomField(cipher.fields, "reg_code", "265453-13457355-847327"); - validateCustomField(cipher.fields, "reg_name", "Kay Riddler"); - validateCustomField(cipher.fields, "reg_email", "kriddler@nullvalue.test"); - validateCustomField(cipher.fields, "company", "Riddles and Jigsaw Puzzles GmbH"); - validateCustomField( - cipher.fields, - "download_link", - "https://limuxcompany.nullvalue.test/5.10.1000/isos" - ); - validateCustomField(cipher.fields, "publisher_name", "Limux Software and Hardware"); - validateCustomField(cipher.fields, "publisher_website", "https://limuxcompany.nullvalue.test/"); - validateCustomField(cipher.fields, "retail_price", "$999"); - validateCustomField(cipher.fields, "support_email", "support@nullvalue.test"); - validateCustomField(cipher.fields, "order_date", "Thu, 01 Apr 2021 12:01:00 GMT"); - validateCustomField(cipher.fields, "order_number", "594839"); - validateCustomField(cipher.fields, "order_total", "$1086.59"); - }); - - it("should parse category 101 - BankAccount", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(BankAccountData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.type).toEqual(CipherType.Card); - expect(cipher.name).toEqual("Bank Account"); - expect(cipher.notes).toEqual("My Bank Account"); - - expect(cipher.card.cardholderName).toEqual("Cool Guy"); - - expect(cipher.fields.length).toEqual(9); - validateCustomField(cipher.fields, "bankName", "Super Credit Union"); - validateCustomField(cipher.fields, "accountType", "checking"); - validateCustomField(cipher.fields, "routingNo", "111000999"); - validateCustomField(cipher.fields, "accountNo", "192837465918273645"); - validateCustomField(cipher.fields, "swift", "123456"); - validateCustomField(cipher.fields, "iban", "DE12 123456"); - validateCustomField(cipher.fields, "telephonePin", "5555"); - validateCustomField(cipher.fields, "branchPhone", "9399399933"); - validateCustomField(cipher.fields, "branchAddress", "1 Fifth Avenue"); - }); - - it("should parse category 102 - Database", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(DatabaseData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Login); - expect(cipher.name).toEqual("Database"); - expect(cipher.notes).toEqual("My Database"); - - const login = cipher.login; - expect(login.username).toEqual("cooldbuser"); - expect(login.password).toEqual("^+kTjhLaN7wVPAhGU)*J"); - - expect(cipher.fields.length).toEqual(7); - validateCustomField(cipher.fields, "database_type", "postgresql"); - validateCustomField(cipher.fields, "hostname", "my.secret.db.server"); - validateCustomField(cipher.fields, "port", "1337"); - validateCustomField(cipher.fields, "database", "user_database"); - validateCustomField(cipher.fields, "sid", "ASDIUFU-283234"); - validateCustomField(cipher.fields, "alias", "cdbu"); - validateCustomField(cipher.fields, "options", "ssh"); - }); - - it("should parse category 103 - Drivers license", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(DriversLicenseData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.name).toEqual("Michael Scarn"); - expect(cipher.subTitle).toEqual("Michael Scarn"); - expect(cipher.notes).toEqual("My Driver's License"); - - const identity = cipher.identity; - expect(identity.firstName).toEqual("Michael"); - expect(identity.middleName).toBeNull(); - expect(identity.lastName).toEqual("Scarn"); - expect(identity.address1).toEqual("2120 Mifflin Rd."); - expect(identity.state).toEqual("Pennsylvania"); - expect(identity.country).toEqual("United States"); - expect(identity.licenseNumber).toEqual("12345678901"); - - expect(cipher.fields.length).toEqual(6); - validateCustomField(cipher.fields, "birthdate", "Sun, 01 Jan 1978 12:01:00 GMT"); - validateCustomField(cipher.fields, "sex", "male"); - validateCustomField(cipher.fields, "height", "5'11\""); - validateCustomField(cipher.fields, "class", "C"); - validateCustomField(cipher.fields, "conditions", "B"); - validateCustomField(cipher.fields, "expiry_date", "203012"); - }); - - it("should parse category 104 - Outdoor License", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(OutdoorLicenseData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Identity); - expect(cipher.name).toEqual("Harvest License"); - expect(cipher.subTitle).toEqual("Cash Bandit"); - expect(cipher.notes).toEqual("My Outdoor License"); - - const identity = cipher.identity; - expect(identity.firstName).toEqual("Cash"); - expect(identity.middleName).toBeNull(); - expect(identity.lastName).toEqual("Bandit"); - expect(identity.state).toEqual("Washington"); - expect(identity.country).toEqual("United States of America"); - - expect(cipher.fields.length).toEqual(4); - validateCustomField(cipher.fields, "valid_from", "Thu, 01 Apr 2021 12:01:00 GMT"); - validateCustomField(cipher.fields, "expires", "Fri, 01 Apr 2044 12:01:00 GMT"); - validateCustomField(cipher.fields, "game", "Bananas,blueberries,corn"); - validateCustomField(cipher.fields, "quota", "100/each"); - }); - - it("should parse category 105 - Membership", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(MembershipData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Identity); - expect(cipher.name).toEqual("Library Card"); - - const identity = cipher.identity; - expect(identity.firstName).toEqual("George"); - expect(identity.middleName).toBeNull(); - expect(identity.lastName).toEqual("Engels"); - expect(identity.company).toEqual("National Public Library"); - expect(identity.phone).toEqual("9995555555"); - - expect(cipher.fields.length).toEqual(5); - validateCustomField(cipher.fields, "website", "https://npl.nullvalue.gov.test"); - validateCustomField(cipher.fields, "member_since", "199901"); - validateCustomField(cipher.fields, "expiry_date", "203412"); - validateCustomField(cipher.fields, "membership_no", "64783862"); - validateCustomField(cipher.fields, "pin", "19191"); - }); - - it("should parse category 106 - Passport", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(PassportData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Identity); - expect(cipher.name).toEqual("Mr. Globewide"); - - const identity = cipher.identity; - expect(identity.firstName).toEqual("David"); - expect(identity.middleName).toBeNull(); - expect(identity.lastName).toEqual("Global"); - expect(identity.passportNumber).toEqual("76436847"); - - expect(cipher.fields.length).toEqual(8); - validateCustomField(cipher.fields, "type", "US Passport"); - validateCustomField(cipher.fields, "sex", "female"); - validateCustomField(cipher.fields, "nationality", "International"); - validateCustomField(cipher.fields, "issuing_authority", "Department of State"); - validateCustomField(cipher.fields, "birthdate", "Fri, 01 Apr 1983 12:01:00 GMT"); - validateCustomField(cipher.fields, "birthplace", "A cave somewhere in Maine"); - validateCustomField(cipher.fields, "issue_date", "Wed, 01 Jan 2020 12:01:00 GMT"); - validateCustomField(cipher.fields, "expiry_date", "Sat, 01 Jan 2050 12:01:00 GMT"); - }); - - it("should parse category 107 - RewardsProgram", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(RewardsProgramData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Identity); - expect(cipher.name).toEqual("Retail Reward Thing"); - - const identity = cipher.identity; - expect(identity.firstName).toEqual("Chef"); - expect(identity.middleName).toBeNull(); - expect(identity.lastName).toEqual("Coldroom"); - expect(identity.company).toEqual("Super Cool Store Co."); - - expect(cipher.fields.length).toEqual(7); - validateCustomField(cipher.fields, "membership_no", "member-29813569"); - validateCustomField(cipher.fields, "pin", "99913"); - validateCustomField(cipher.fields, "additional_no", "additional member id"); - validateCustomField(cipher.fields, "member_since", "202101"); - validateCustomField(cipher.fields, "customer_service_phone", "123456"); - validateCustomField(cipher.fields, "reservations_phone", "123456"); - validateCustomField(cipher.fields, "website", "supercoolstore.com"); - }); - - it("should parse category 108 - SSN", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(SSNData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.name).toEqual("SSN"); - - const identity = cipher.identity; - expect(identity.firstName).toEqual("Jack"); - expect(identity.middleName).toBeNull(); - expect(identity.lastName).toEqual("Judd"); - expect(identity.ssn).toEqual("131-216-1900"); - }); - - it("should parse category 109 - WirelessRouter", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(WirelessRouterData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Login); - expect(cipher.name).toEqual("Wireless Router"); - expect(cipher.notes).toEqual("My Wifi Router Config"); - - expect(cipher.login.password).toEqual("BqatGTVQ9TCN72tLbjrsHqkb"); - - expect(cipher.fields.length).toEqual(7); - validateCustomField(cipher.fields, "name", "pixel 2Xl"); - validateCustomField(cipher.fields, "server", "127.0.0.1"); - validateCustomField(cipher.fields, "airport_id", "some airportId"); - validateCustomField(cipher.fields, "network_name", "some network name"); - validateCustomField(cipher.fields, "wireless_security", "WPA"); - validateCustomField(cipher.fields, "wireless_password", "wifipassword"); - validateCustomField(cipher.fields, "disk_password", "diskpassword"); - }); - - it("should parse category 110 - Server", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(ServerData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Login); - expect(cipher.name).toEqual("Super Cool Server"); - expect(cipher.notes).toEqual("My Server"); - - expect(cipher.login.username).toEqual("frankly-notsure"); - expect(cipher.login.password).toEqual("*&YHJI87yjy78u"); - expect(cipher.login.uri).toEqual("https://coolserver.nullvalue.test"); - - expect(cipher.fields.length).toEqual(7); - validateCustomField( - cipher.fields, - "admin_console_url", - "https://coolserver.nullvalue.test/admin" - ); - validateCustomField(cipher.fields, "admin_console_username", "frankly-idontknowwhatimdoing"); - validateCustomField(cipher.fields, "admin_console_password", "^%RY&^YUiju8iUYHJI(U"); - validateCustomField(cipher.fields, "name", "Private Hosting Provider Inc."); - validateCustomField(cipher.fields, "website", "https://phpi.nullvalue.test"); - validateCustomField( - cipher.fields, - "support_contact_url", - "https://phpi.nullvalue.test/support" - ); - validateCustomField(cipher.fields, "support_contact_phone", "8882569382"); - }); - - it("should parse category 111 - EmailAccount", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(EmailAccountData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.SecureNote); - expect(cipher.name).toEqual("Email Config"); - expect(cipher.notes).toEqual("My Email Config"); - - expect(cipher.fields.length).toEqual(17); - validateCustomField(cipher.fields, "pop_type", "either"); - validateCustomField(cipher.fields, "pop_username", "someuser@nullvalue.test"); - validateCustomField(cipher.fields, "pop_server", "mailserver.nullvalue.test"); - validateCustomField(cipher.fields, "pop_port", "587"); - validateCustomField(cipher.fields, "pop_password", "u1jsf { - const importer = new Importer(); - const jsonString = JSON.stringify(APICredentialsData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Login); - expect(cipher.name).toEqual("API Credential"); - expect(cipher.notes).toEqual("My API Credential"); - - expect(cipher.login.username).toEqual("apiuser@nullvalue.test"); - expect(cipher.login.password).toEqual("apiapiapiapiapiapiappy"); - expect(cipher.login.uri).toEqual("http://not.your.everyday.hostname"); - - expect(cipher.fields.length).toEqual(4); - validateCustomField(cipher.fields, "type", "jwt"); - validateCustomField(cipher.fields, "filename", "filename.jwt"); - validateCustomField(cipher.fields, "validFrom", "Mon, 04 Apr 2011 12:01:00 GMT"); - validateCustomField(cipher.fields, "expires", "Tue, 01 Apr 2031 12:01:00 GMT"); - }); - - it("should create secure notes", async () => { - const importer = new Importer(); - const result = await importer.parse(SecureNoteDataJson); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.name).toEqual("Secure Note #1"); - expect(cipher.notes).toEqual( - "This is my secure note. \n\nLorem ipsum expecto patronum. \nThe quick brown fox jumped over the lazy dog." - ); - expect(cipher.secureNote.type).toEqual(SecureNoteType.Generic); - }); - - it("should parse category 113 - Medical Record", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(MedicalRecordData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.type).toEqual(CipherType.SecureNote); - expect(cipher.name).toEqual("Some Health Record"); - expect(cipher.notes).toEqual("Some notes about my medical history"); - expect(cipher.secureNote.type).toEqual(SecureNoteType.Generic); - - expect(cipher.fields.length).toEqual(8); - validateCustomField(cipher.fields, "date", "Sat, 01 Jan 2022 12:01:00 GMT"); - validateCustomField(cipher.fields, "location", "some hospital/clinic"); - validateCustomField(cipher.fields, "healthcareprofessional", "Some Doctor"); - validateCustomField(cipher.fields, "patient", "Me"); - validateCustomField(cipher.fields, "reason", "unwell"); - validateCustomField(cipher.fields, "medication", "Insuline"); - validateCustomField(cipher.fields, "dosage", "1"); - validateCustomField(cipher.fields, "notes", "multiple times a day"); - }); - - it("should create folders", async () => { - const importer = new Importer(); - const result = await importer.parse(SanitizedExportJson); - expect(result != null).toBe(true); - - const folders = result.folders; - expect(folders.length).toBe(5); - expect(folders[0].name).toBe("Movies"); - expect(folders[1].name).toBe("Finance"); - expect(folders[2].name).toBe("Travel"); - expect(folders[3].name).toBe("Education"); - expect(folders[4].name).toBe("Starter Kit"); - - // Check that ciphers have a folder assigned to them - expect(result.ciphers.filter((c) => c.folderId === folders[0].id).length).toBeGreaterThan(0); - expect(result.ciphers.filter((c) => c.folderId === folders[1].id).length).toBeGreaterThan(0); - expect(result.ciphers.filter((c) => c.folderId === folders[2].id).length).toBeGreaterThan(0); - expect(result.ciphers.filter((c) => c.folderId === folders[3].id).length).toBeGreaterThan(0); - expect(result.ciphers.filter((c) => c.folderId === folders[4].id).length).toBeGreaterThan(0); - }); - - it("should create collections if part of an organization", async () => { - const importer = new Importer(); - importer.organizationId = Utils.newGuid(); - const result = await importer.parse(SanitizedExportJson); - expect(result != null).toBe(true); - - const collections = result.collections; - expect(collections.length).toBe(5); - expect(collections[0].name).toBe("Movies"); - expect(collections[1].name).toBe("Finance"); - expect(collections[2].name).toBe("Travel"); - expect(collections[3].name).toBe("Education"); - expect(collections[4].name).toBe("Starter Kit"); - }); -}); diff --git a/jslib/common/spec/importers/onepasswordMacCsvImporter.spec.ts b/jslib/common/spec/importers/onepasswordMacCsvImporter.spec.ts deleted file mode 100644 index a9c53a52..00000000 --- a/jslib/common/spec/importers/onepasswordMacCsvImporter.spec.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { CipherType } from "@/jslib/common/src/enums/cipherType"; -import { OnePasswordMacCsvImporter as Importer } from "@/jslib/common/src/importers/onepasswordImporters/onepasswordMacCsvImporter"; -import { CipherView } from "@/jslib/common/src/models/view/cipherView"; - -import { data as creditCardData } from "./testData/onePasswordCsv/creditCard.mac.csv"; -import { data as identityData } from "./testData/onePasswordCsv/identity.mac.csv"; -import { data as multiTypeData } from "./testData/onePasswordCsv/multipleItems.mac.csv"; - -function expectIdentity(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - - expect(cipher.identity).toEqual( - expect.objectContaining({ - firstName: "first name", - middleName: "mi", - lastName: "last name", - username: "userNam3", - company: "bitwarden", - phone: "8005555555", - email: "email@bitwarden.com", - }) - ); - - expect(cipher.notes).toContain("address\ncity state zip\nUnited States"); -} - -function expectCreditCard(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Card); - - expect(cipher.card).toEqual( - expect.objectContaining({ - number: "4111111111111111", - code: "111", - cardholderName: "test", - expMonth: "1", - expYear: "2030", - }) - ); -} - -describe("1Password mac CSV Importer", () => { - it("should parse identity records", async () => { - const importer = new Importer(); - const result = await importer.parse(identityData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - const cipher = result.ciphers[0]; - expectIdentity(cipher); - }); - - it("should parse credit card records", async () => { - const importer = new Importer(); - const result = await importer.parse(creditCardData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - const cipher = result.ciphers[0]; - expectCreditCard(cipher); - }); - - it("should parse csv's with multiple record type", async () => { - const importer = new Importer(); - const result = await importer.parse(multiTypeData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(4); - expectIdentity(result.ciphers[1]); - expectCreditCard(result.ciphers[2]); - }); -}); diff --git a/jslib/common/spec/importers/onepasswordWinCsvImporter.spec.ts b/jslib/common/spec/importers/onepasswordWinCsvImporter.spec.ts deleted file mode 100644 index 49693f3c..00000000 --- a/jslib/common/spec/importers/onepasswordWinCsvImporter.spec.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { CipherType } from "@/jslib/common/src/enums/cipherType"; -import { FieldType } from "@/jslib/common/src/enums/fieldType"; -import { OnePasswordWinCsvImporter as Importer } from "@/jslib/common/src/importers/onepasswordImporters/onepasswordWinCsvImporter"; -import { CipherView } from "@/jslib/common/src/models/view/cipherView"; -import { FieldView } from "@/jslib/common/src/models/view/fieldView"; - -import { data as creditCardData } from "./testData/onePasswordCsv/creditCard.windows.csv"; -import { data as identityData } from "./testData/onePasswordCsv/identity.windows.csv"; -import { data as multiTypeData } from "./testData/onePasswordCsv/multipleItems.windows.csv"; - -function expectIdentity(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - - expect(cipher.identity).toEqual( - expect.objectContaining({ - firstName: "first name", - middleName: "mi", - lastName: "last name", - username: "userNam3", - company: "bitwarden", - phone: "8005555555", - email: "email@bitwarden.com", - }) - ); - - expect(cipher.fields).toEqual( - expect.arrayContaining([ - Object.assign(new FieldView(), { - type: FieldType.Text, - name: "address", - value: "address city state zip us", - }), - ]) - ); -} - -function expectCreditCard(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Card); - - expect(cipher.card).toEqual( - expect.objectContaining({ - number: "4111111111111111", - code: "111", - cardholderName: "test", - expMonth: "1", - expYear: "1970", - }) - ); -} - -describe("1Password windows CSV Importer", () => { - let importer: Importer; - beforeEach(() => { - importer = new Importer(); - }); - - it("should parse identity records", async () => { - const result = await importer.parse(identityData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - const cipher = result.ciphers[0]; - expectIdentity(cipher); - }); - - it("should parse credit card records", async () => { - const result = await importer.parse(creditCardData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - const cipher = result.ciphers[0]; - expectCreditCard(cipher); - }); - - it("should parse csv's with multiple record types", async () => { - const result = await importer.parse(multiTypeData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(4); - - expectIdentity(result.ciphers[1]); - expectCreditCard(result.ciphers[2]); - }); -}); diff --git a/jslib/common/spec/importers/safariCsvImporter.spec.ts b/jslib/common/spec/importers/safariCsvImporter.spec.ts deleted file mode 100644 index 4cbc56f8..00000000 --- a/jslib/common/spec/importers/safariCsvImporter.spec.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { SafariCsvImporter as Importer } from "@/jslib/common/src/importers/safariCsvImporter"; -import { CipherView } from "@/jslib/common/src/models/view/cipherView"; -import { LoginUriView } from "@/jslib/common/src/models/view/loginUriView"; -import { LoginView } from "@/jslib/common/src/models/view/loginView"; - -import { data as oldSimplePasswordData } from "./testData/safariCsv/oldSimplePasswordData.csv"; -import { data as simplePasswordData } from "./testData/safariCsv/simplePasswordData.csv"; - -const CipherData = [ - { - title: "should parse URLs in new CSV format", - csv: simplePasswordData, - expected: Object.assign(new CipherView(), { - id: null, - organizationId: null, - folderId: null, - name: "example.com (example_user)", - login: Object.assign(new LoginView(), { - username: "example_user", - password: "example_p@ssword", - uris: [ - Object.assign(new LoginUriView(), { - uri: "https://example.com", - }), - ], - totp: "otpauth://totp/test?secret=examplesecret", - }), - notes: "Example note\nMore notes on new line", - type: 1, - }), - }, - { - title: "should parse URLs in old CSV format", - csv: oldSimplePasswordData, - expected: Object.assign(new CipherView(), { - id: null, - organizationId: null, - folderId: null, - name: "example.com (example_user)", - login: Object.assign(new LoginView(), { - username: "example_user", - password: "example_p@ssword", - uris: [ - Object.assign(new LoginUriView(), { - uri: "https://example.com", - }), - ], - }), - type: 1, - }), - }, -]; - -describe("Safari CSV Importer", () => { - CipherData.forEach((data) => { - it(data.title, async () => { - const importer = new Importer(); - const result = await importer.parse(data.csv); - expect(result != null).toBe(true); - expect(result.ciphers.length).toBeGreaterThan(0); - - const cipher = result.ciphers.shift(); - let property: keyof typeof data.expected; - for (property in data.expected) { - // eslint-disable-next-line - if (data.expected.hasOwnProperty(property)) { - // eslint-disable-next-line - expect(cipher.hasOwnProperty(property)).toBe(true); - expect(cipher[property]).toEqual(data.expected[property]); - } - } - }); - }); -}); diff --git a/jslib/common/spec/importers/testData/bitwardenJson/empty.json.ts b/jslib/common/spec/importers/testData/bitwardenJson/empty.json.ts deleted file mode 100644 index 43ab8c76..00000000 --- a/jslib/common/spec/importers/testData/bitwardenJson/empty.json.ts +++ /dev/null @@ -1 +0,0 @@ -export const data = '{"encrypted":false,"folders":[],"items":[]}'; diff --git a/jslib/common/spec/importers/testData/bitwardenJson/passwordProtected.json.ts b/jslib/common/spec/importers/testData/bitwardenJson/passwordProtected.json.ts deleted file mode 100644 index 0462e834..00000000 --- a/jslib/common/spec/importers/testData/bitwardenJson/passwordProtected.json.ts +++ /dev/null @@ -1,9 +0,0 @@ -export const data = `{ - "encrypted": true, - "passwordProtected": true, - "salt": "Oy0xcgVRzxQ+9NpB5GLehw==", - "kdfIterations": 100000, - "kdfType": 0, - "encKeyValidation_DO_NOT_EDIT": "2.sZs4Jc1HW9rhABzRRYR/gQ==|8kTDaDxafulnybpWoqVX8RAybhVRTr+dffNjms271Y7amQmIE1VSMwLbk+b2vxZb|IqOo6oXQtmv/Xb/GHDi42XG9c9ILePYtP5qq584VWcg=", - "data": "2.D0AXAf7G/XIwq6EC7A0Suw==|4w+m0wHRo25y1T1Syh5wdAUyF8voqEy54waMEsbnK0Nzee959w54ru5D1NntvxZL4HFqkQLyR6jCFkn5g40f+MGJgihS/wvf4NcJJfLiiFo6MEDOQNBkxw7ZBGuHiKfVuBO5u36JgzQtZ8lyFaduGxFszuF5c+URiE9PDh9jY0//poVgHKwuLZuYFIW+f7h6T+shUWK0ya11lcHn/B/CA2xiI+YiKdNZreJrwN0yslpJ/f+MrOzagvftRjt0GNkwveCtwcYUw/zFvqvibUpKeHcRiXs8SaGoHJ5RTm69FbJ7C5tnLwoVT89Af156uvRAXV7yAC4oPcbU/3TGb6hqYosvi1QNyaqG3M9gxS6+AK0C4yWuNbMLDEr+MWiw0SWLVMKQEkCZ4oM+oTCx52otW3+2V9I8Pv3KmmhkvVvE4wBdweOJeRX53Tf5ySkmpIhCfzj6JMmxO+nmTXIhWnJChr4hPVh+ixv1GQK5thIPTCMXmAtXoTIFUx1KWjS6LjOdi2hKQueVI+XZjf0qnY2vTMxRg0ZsLBA2znQTx+DSEqumORb5T/lV73pWZiCNePSAE2msOm7tep+lm4O/VCViCfXjITAY196syhOK0XnhxJvPALchZY8sYRAfuw6hHoDiVr+JUieRoI7eUrhXBp+D6Py9TL/dS/rHe+C2Zhx+xwx2NfGt+xEp8ZAOOCxgZ0UTeSA/abm0Oz7tJIK1n26acQrgbr7rMeBymAX+5L5OWlwI1hGgEBfj6W0rrbSXf3VMfaFXZ5UsXi1VhzQmU3LyWENoDeImXFQj6zMbUSfcVwLsG5Fg8Ee/kO/wJPfG5BO51+/vFqQj6AkaMEcwg5xNrObHYfQ/DMhIn7YDM2zdzbNTdhnobGkz6YRKFPCgFe3EmIEPEpeh9S3eKE9C7MQsrR8jVSiseR/FipJLsN+W7iOwzeXdwxUFlC/0a98bTKvdrbMgNi6ZVXykHY/t2UyEGpxZGTHoZwhX01kiQrwzC4/+v/676ldxPluO9GY7MtrLveCDsiyBz15u43IGHayDEBNT0rqrOKLYmfzwCWoahRLZQrSmepe/FXqgPqRfyWc/Ro+w3sT9dXUkx3B5xxWgSyABowPV48yBUSJuefhKTpqgzkU+LzhNnWHjnxJzzQ2/|IhlRjnyhIoDM85qHX/bY2zaIU5YaRO/iFVTQDd3uFDo=" -}`; diff --git a/jslib/common/spec/importers/testData/dashlaneCsv/credentials.csv.ts b/jslib/common/spec/importers/testData/dashlaneCsv/credentials.csv.ts deleted file mode 100644 index 78e42cb1..00000000 --- a/jslib/common/spec/importers/testData/dashlaneCsv/credentials.csv.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const credentialsData = `username,username2,username3,title,password,note,url,category,otpSecret -jdoe,,,example.com,somePassword,some note for example.com,https://www.example.com,Entertainment,someTOTPSeed`; diff --git a/jslib/common/spec/importers/testData/dashlaneCsv/id.csv.ts b/jslib/common/spec/importers/testData/dashlaneCsv/id.csv.ts deleted file mode 100644 index 1c939557..00000000 --- a/jslib/common/spec/importers/testData/dashlaneCsv/id.csv.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const identityData = `type,number,name,issue_date,expiration_date,place_of_issue,state -card,123123123,John Doe,2022-1-30,2032-1-30,, -passport,123123123,John Doe,2022-1-30,2032-1-30,somewhere in Germany, -license,1234556,John Doe,2022-8-10,2022-10-10,,DC -social_security,123123123,John Doe,,,, -tax_number,123123123,,,,,`; diff --git a/jslib/common/spec/importers/testData/dashlaneCsv/multiplePersonalInfo.csv.ts b/jslib/common/spec/importers/testData/dashlaneCsv/multiplePersonalInfo.csv.ts deleted file mode 100644 index cca5748b..00000000 --- a/jslib/common/spec/importers/testData/dashlaneCsv/multiplePersonalInfo.csv.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const multiplePersonalInfoData = `type,title,first_name,middle_name,last_name,login,date_of_birth,place_of_birth,email,email_type,item_name,phone_number,address,country,state,city,zip,address_recipient,address_building,address_apartment,address_floor,address_door_code,job_title,url -name,MR,John,,Doe,jdoe,2022-01-30,world,,,,,,,,,,,,,,,, -email,,,,,,,,jdoe@example.com,personal,Johns email,,,,,,,,,,,,, -number,,,,,,,,,,John's number,+49123123123,,,,,,,,,,,, -address,,,,,,,,,,John's home address,,1 some street,de,DE-0-NW,some city,123123,John,1,1,1,123,, -website,,,,,,,,,,Website,,,,,,,,,,,,,website.com -name,Mrs,Jane,,Doe,jdoe,2022-01-30,earth,,,,,,,,,,,,,,,,`; diff --git a/jslib/common/spec/importers/testData/dashlaneCsv/payments.csv.ts b/jslib/common/spec/importers/testData/dashlaneCsv/payments.csv.ts deleted file mode 100644 index 336986c1..00000000 --- a/jslib/common/spec/importers/testData/dashlaneCsv/payments.csv.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const paymentsData = `type,account_name,account_holder,cc_number,code,expiration_month,expiration_year,routing_number,account_number,country,issuing_bank -bank,John's savings account,John Doe,,,,,routingNumber,accountNumber,US,US-ALLY -credit_card,John Doe,,41111111111111111,123,01,2023,,,US,`; diff --git a/jslib/common/spec/importers/testData/dashlaneCsv/personalInfo.csv.ts b/jslib/common/spec/importers/testData/dashlaneCsv/personalInfo.csv.ts deleted file mode 100644 index ec99f800..00000000 --- a/jslib/common/spec/importers/testData/dashlaneCsv/personalInfo.csv.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const personalInfoData = `type,title,first_name,middle_name,last_name,login,date_of_birth,place_of_birth,email,email_type,item_name,phone_number,address,country,state,city,zip,address_recipient,address_building,address_apartment,address_floor,address_door_code,job_title,url -name,MR,John,,Doe,jdoe,2022-01-30,world,,,,,,,,,,,,,,,, -email,,,,,,,,jdoe@example.com,personal,Johns email,,,,,,,,,,,,, -number,,,,,,,,,,John's number,+49123123123,,,,,,,,,,,, -address,,,,,,,,,,John's home address,,1 some street,de,DE-0-NW,some city,123123,John,1,1,1,123,, -website,,,,,,,,,,Website,,,,,,,,,,,,,website.com`; diff --git a/jslib/common/spec/importers/testData/dashlaneCsv/securenotes.csv.ts b/jslib/common/spec/importers/testData/dashlaneCsv/securenotes.csv.ts deleted file mode 100644 index 22a3b904..00000000 --- a/jslib/common/spec/importers/testData/dashlaneCsv/securenotes.csv.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const secureNoteData = `title,note -01,test`; diff --git a/jslib/common/spec/importers/testData/firefoxCsv/firefoxAccountsData.csv.ts b/jslib/common/spec/importers/testData/firefoxCsv/firefoxAccountsData.csv.ts deleted file mode 100644 index 2f2c1b55..00000000 --- a/jslib/common/spec/importers/testData/firefoxCsv/firefoxAccountsData.csv.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const data = `"url","username","password","httpRealm","formActionOrigin","guid","timeCreated","timeLastUsed","timePasswordChanged" -"chrome://FirefoxAccounts","bla-bla-foo-bar","{""version"":1,""accountData"":{""kSync"":""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"",""kXCS"":""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"",""kExtSync"":""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"",""kExtKbHash"":""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"",""scopedKeys"":{""https://identity.mozilla.com/apps/oldsync"":{""kid"":""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",""k"":""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"",""kty"":""xxx""},""sync:addon_storage"":{""kid"":""xxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"",""k"":""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"",""kty"":""xxx""}}}}","Firefox Accounts credentials",,"{d61e37fa-2bc4-469a-bd66-41fd3b0005e0}","1612345678900","1612345678900","1612345678900" -"https://example.com","foo","bar",,"","{d61e37fa-2bc4-469a-bd66-41fd3b0005e0}","1612345678900","1612345678900","1612345678900" -`; diff --git a/jslib/common/spec/importers/testData/firefoxCsv/simplePasswordData.csv.ts b/jslib/common/spec/importers/testData/firefoxCsv/simplePasswordData.csv.ts deleted file mode 100644 index 90e19f19..00000000 --- a/jslib/common/spec/importers/testData/firefoxCsv/simplePasswordData.csv.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const data = `"url","username","password","httpRealm","formActionOrigin","guid","timeCreated","timeLastUsed","timePasswordChanged" -"https://example.com","foo","bar",,"","{d61e37fa-2bc4-469a-bd66-41fd3b0005e0}","1612345678900","1612345678900","1612345678900"`; diff --git a/jslib/common/spec/importers/testData/keeperJson/testData.ts b/jslib/common/spec/importers/testData/keeperJson/testData.ts deleted file mode 100644 index d537c1ee..00000000 --- a/jslib/common/spec/importers/testData/keeperJson/testData.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { KeeperJsonExport } from "@/jslib/common/src/importers/keeperImporters/types/keeperJsonTypes"; - -export const testData: KeeperJsonExport = { - shared_folders: [ - { - path: "My Customer 1", - manage_users: true, - manage_records: true, - can_edit: true, - can_share: true, - permissions: [ - { - uid: "kVM96KGEoGxhskZoSTd_jw", - manage_users: true, - manage_records: true, - }, - { - name: "user@mycompany.com", - manage_users: true, - manage_records: true, - }, - ], - }, - { - path: "Testing\\My Customer 2", - manage_users: true, - manage_records: true, - can_edit: true, - can_share: true, - permissions: [ - { - uid: "ih1CggiQ-3ENXcn4G0sl-g", - manage_users: true, - manage_records: true, - }, - { - name: "user@mycompany.com", - manage_users: true, - manage_records: true, - }, - ], - }, - ], - records: [ - { - title: "Bank Account 1", - login: "customer1234", - password: "4813fJDHF4239fdk", - login_url: "https://chase.com", - notes: "These are some notes.", - custom_fields: { - "Account Number": "123-456-789", - }, - folders: [ - { - folder: "Optional Private Folder 1", - }, - ], - }, - { - title: "Bank Account 2", - login: "mybankusername", - password: "w4k4k193f$^&@#*%2", - login_url: "https://amex.com", - notes: "Some great information here.", - custom_fields: { - "Security Group": "Public", - "IP Address": "12.45.67.8", - "TFC:Keeper": - "otpauth://totp/Amazon:me@company.com?secret=JBSWY3DPEHPK3PXP&issuer=Amazon&algorithm=SHA1&digits=6&period=30", - }, - folders: [ - { - folder: "Optional Private Folder 1", - }, - { - shared_folder: "My Customer 1", - can_edit: true, - can_share: true, - }, - ], - }, - { - title: "Some Account", - login: "someUserName", - password: "w4k4k1wergf$^&@#*%2", - login_url: "https://example.com", - }, - ], -}; diff --git a/jslib/common/spec/importers/testData/mykiCsv/UserAccount.csv.ts b/jslib/common/spec/importers/testData/mykiCsv/UserAccount.csv.ts deleted file mode 100644 index 5ccf0971..00000000 --- a/jslib/common/spec/importers/testData/mykiCsv/UserAccount.csv.ts +++ /dev/null @@ -1,3 +0,0 @@ -/* eslint-disable */ -export const userAccountData = `nickname,url,username,password,additionalInfo,twofaSecret,status,tags -PasswordNickname,www.google.com,user.name@email.com,abc123,This is the additional information text.,someTOTPSeed,active,someTag`; diff --git a/jslib/common/spec/importers/testData/mykiCsv/UserCreditCard.csv.ts b/jslib/common/spec/importers/testData/mykiCsv/UserCreditCard.csv.ts deleted file mode 100644 index 0b127627..00000000 --- a/jslib/common/spec/importers/testData/mykiCsv/UserCreditCard.csv.ts +++ /dev/null @@ -1,3 +0,0 @@ -/* eslint-disable */ -export const userCreditCardData = `nickname,status,tags,cardNumber,cardName,exp_month,exp_year,cvv,additionalInfo -Visa test card,active,someTag,4111111111111111,Joe User,04,24,222,This is the additional information field`; diff --git a/jslib/common/spec/importers/testData/mykiCsv/UserIdCard.csv.ts b/jslib/common/spec/importers/testData/mykiCsv/UserIdCard.csv.ts deleted file mode 100644 index 8f3fa600..00000000 --- a/jslib/common/spec/importers/testData/mykiCsv/UserIdCard.csv.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* eslint-disable */ -export const userIdCardData = `nickname,status,tags,idType,idNumber,idName,idIssuanceDate,idExpirationDate,idCountry,additionalInfo -Joe User's nickname,active,someTag,Driver's License,123456,Joe M User,02/02/2022,02/02/2024,United States,Additional information -Passport ID card,active,someTag,Passport,1234567,Joe M User,03/07/2022,03/07/2028,United States,Additional information field -Social Security ID card,active,someTag,Social Security,123455678,Joe M User,03/07/2022,03/07/2028,United States,Additional information field text -ID card type ID card,active,someTag,ID Card,1234566,Joe M User,03/07/2022,03/07/2028,United States,Additional Information field text -Tax number ID card,active,someTag,Tax Number,12345678,Joe M User,03/07/2022,03/07/2028,United States,Additinoal information text field -Bank account ID card,active,someTag,Bank Account,12344556677,Joe M User,03/07/2022,03/07/2028,United States,Additional text information here -Insurance card ID card,active,someTag,Insurance Card,123456677,Joe M User,03/07/2022,03/07/2022,United States,Additional information text goes here -Health card Id card,active,someTag,Health Card,1234670,Joe M User,03/07/2022,03/07/2028,United States,More info -Membership ID card,active,someTag,Membership,12345709,Joe M User,03/07/2022,03/07/2028,United States,Add'l info -Database ID card,active,someTag,Database,12345089u,Joe M User,03/07/2022,03/07/2028,United States,Addin't info -Outdoor license ID card,active,someTag,Outdoor License,123890090,Joe M User,03/07/2022,03/07/2028,United States,Additional info -Reward program Id card,active,someTag,Reward Program,12345890b,Joe M User,03/07/2022,03/07/2028,United States,1234890 -Software license ID card,active,someTag,Software License,1234567c,Joe M User,03/07/2022,03/07/2028,United States,"It seems like the fields don't change, which makes it pretty useless that they have so many ID card types." -Tour visa ID card,active,someTag,Tour Visa,123456lkhj,Joe M User,03/07/2022,03/07/2028,United States,Additional Informaion text`; diff --git a/jslib/common/spec/importers/testData/mykiCsv/UserIdentity.csv.ts b/jslib/common/spec/importers/testData/mykiCsv/UserIdentity.csv.ts deleted file mode 100644 index 13afb16d..00000000 --- a/jslib/common/spec/importers/testData/mykiCsv/UserIdentity.csv.ts +++ /dev/null @@ -1,3 +0,0 @@ -/* eslint-disable */ -export const userIdentityData = `nickname,status,tags,firstName,middleName,lastName,email,firstAddressLine,secondAddressLine,title,gender,number,city,country,zipCode,additionalInfo -Joe User's nickname,active,someTag,Joe,M,User,joe.user@email.com,1 Example House,Suite 300,Mr,Male,2223334444,Portland,United States,04101,Additional information field`; diff --git a/jslib/common/spec/importers/testData/mykiCsv/UserNote.csv.ts b/jslib/common/spec/importers/testData/mykiCsv/UserNote.csv.ts deleted file mode 100644 index 8094c92f..00000000 --- a/jslib/common/spec/importers/testData/mykiCsv/UserNote.csv.ts +++ /dev/null @@ -1,3 +0,0 @@ -/* eslint-disable */ -export const userNoteData = `nickname,status,content -The title of a secure note,active,"The content of a secure note. Lorem ipsum, etc."`; diff --git a/jslib/common/spec/importers/testData/mykiCsv/UserTwofa.csv.ts b/jslib/common/spec/importers/testData/mykiCsv/UserTwofa.csv.ts deleted file mode 100644 index 68cfd44f..00000000 --- a/jslib/common/spec/importers/testData/mykiCsv/UserTwofa.csv.ts +++ /dev/null @@ -1,3 +0,0 @@ -/* eslint-disable */ -export const userTwoFaData = `nickname,status,tags,authToken,additionalInfo -2FA nickname,active,someTag,someTOTPSeed,"Additional information field content. "`; diff --git a/jslib/common/spec/importers/testData/nordpassCsv/nordpass.card.csv.ts b/jslib/common/spec/importers/testData/nordpassCsv/nordpass.card.csv.ts deleted file mode 100644 index 8d79d2b1..00000000 --- a/jslib/common/spec/importers/testData/nordpassCsv/nordpass.card.csv.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const data = `name,url,username,password,note,cardholdername,cardnumber,cvc,expirydate,zipcode,folder,full_name,phone_number,email,address1,address2,city,country,state -SomeVisa,,,,,SomeHolder,4024007103939509,123,01 / 22,12345,,,,,,,,,`; diff --git a/jslib/common/spec/importers/testData/nordpassCsv/nordpass.identity.csv.ts b/jslib/common/spec/importers/testData/nordpassCsv/nordpass.identity.csv.ts deleted file mode 100644 index 4dde389c..00000000 --- a/jslib/common/spec/importers/testData/nordpassCsv/nordpass.identity.csv.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const data = `name,url,username,password,note,cardholdername,cardnumber,cvc,expirydate,zipcode,folder,full_name,phone_number,email,address1,address2,city,country,state -SomeTitle,,,,SomeNoteToMyIdentity,,,,,123456,,#fullName,123456789,hello@bitwarden.com,Test street 123,additional addressinfo,Cologne,Germany,North-Rhine-Westphalia`; diff --git a/jslib/common/spec/importers/testData/nordpassCsv/nordpass.login.csv.ts b/jslib/common/spec/importers/testData/nordpassCsv/nordpass.login.csv.ts deleted file mode 100644 index e2af76b0..00000000 --- a/jslib/common/spec/importers/testData/nordpassCsv/nordpass.login.csv.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const data = `name,url,username,password,note,cardholdername,cardnumber,cvc,expirydate,zipcode,folder,full_name,phone_number,email,address1,address2,city,country,state -SomeVaultItemName,https://example.com,hello@bitwarden.com,someStrongPassword,Some note for the VaultItem,,,,,,SomeFolderForVaultItem,,,,,,,,`; diff --git a/jslib/common/spec/importers/testData/nordpassCsv/nordpass.secureNote.csv.ts b/jslib/common/spec/importers/testData/nordpassCsv/nordpass.secureNote.csv.ts deleted file mode 100644 index 0e4dcb2e..00000000 --- a/jslib/common/spec/importers/testData/nordpassCsv/nordpass.secureNote.csv.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const data = `name,url,username,password,note,cardholdername,cardnumber,cvc,expirydate,zipcode,folder,full_name,phone_number,email,address1,address2,city,country,state -notesFolder,,,,,,,,,,,,,,,,,, -MySuperSecureNoteTitle,,,,MySuperSecureNote,,,,,,notesFolder,,,,,,,,`; diff --git a/jslib/common/spec/importers/testData/onePassword1Pux/APICredentials.ts b/jslib/common/spec/importers/testData/onePassword1Pux/APICredentials.ts deleted file mode 100644 index fb44e7c5..00000000 --- a/jslib/common/spec/importers/testData/onePassword1Pux/APICredentials.ts +++ /dev/null @@ -1,169 +0,0 @@ -import { ExportData } from "@/jslib/common/src/importers/onepasswordImporters/types/onepassword1PuxImporterTypes"; - -export const APICredentialsData: ExportData = { - accounts: [ - { - attrs: { - accountName: "1Password Customer", - name: "1Password Customer", - avatar: "", - email: "username123123123@gmail.com", - uuid: "TRIZ3XV4JJFRXJ3BARILLTUA6E", - domain: "https://my.1password.com/", - }, - vaults: [ - { - attrs: { - uuid: "pqcgbqjxr4tng2hsqt5ffrgwju", - desc: "Just test entries", - avatar: "ke7i5rxnjrh3tj6uesstcosspu.png", - name: "T's Test Vault", - type: "U", - }, - items: [ - { - uuid: "6nqnjdqyk5mwvqbdgbdr47oabe", - favIndex: 0, - createdAt: 1619465969, - updatedAt: 1619466052, - trashed: false, - categoryUuid: "112", - details: { - loginFields: [], - notesPlain: "My API Credential", - sections: [ - { - title: "", - fields: [ - { - title: "username", - id: "username", - value: { - string: "apiuser@nullvalue.test", - }, - indexAtSource: 0, - guarded: true, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "no", - capitalization: "none", - }, - }, - { - title: "credential", - id: "credential", - value: { - concealed: "apiapiapiapiapiapiappy", - }, - indexAtSource: 1, - guarded: true, - multiline: false, - dontGenerate: true, - inputTraits: { - keyboard: "default", - correction: "no", - capitalization: "default", - }, - }, - { - title: "type", - id: "type", - value: { - menu: "jwt", - }, - indexAtSource: 2, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "filename", - id: "filename", - value: { - string: "filename.jwt", - }, - indexAtSource: 3, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "valid from", - id: "validFrom", - value: { - date: 1301918460, - }, - indexAtSource: 4, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "expires", - id: "expires", - value: { - date: 1932811260, - }, - indexAtSource: 5, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "hostname", - id: "hostname", - value: { - string: "not.your.everyday.hostname", - }, - indexAtSource: 6, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "uRL", - correction: "default", - capitalization: "default", - }, - }, - ], - }, - ], - passwordHistory: [], - }, - overview: { - subtitle: "", - title: "API Credential", - url: "", - ps: 0, - pbe: 0.0, - pgrng: false, - }, - }, - ], - }, - ], - }, - ], -}; diff --git a/jslib/common/spec/importers/testData/onePassword1Pux/BankAccount.ts b/jslib/common/spec/importers/testData/onePassword1Pux/BankAccount.ts deleted file mode 100644 index 8278e2e6..00000000 --- a/jslib/common/spec/importers/testData/onePassword1Pux/BankAccount.ts +++ /dev/null @@ -1,224 +0,0 @@ -import { ExportData } from "@/jslib/common/src/importers/onepasswordImporters/types/onepassword1PuxImporterTypes"; - -export const BankAccountData: ExportData = { - accounts: [ - { - attrs: { - accountName: "1Password Customer", - name: "1Password Customer", - avatar: "", - email: "username123123123@gmail.com", - uuid: "TRIZ3XV4JJFRXJ3BARILLTUA6E", - domain: "https://my.1password.com/", - }, - vaults: [ - { - attrs: { - uuid: "pqcgbqjxr4tng2hsqt5ffrgwju", - desc: "Just test entries", - avatar: "ke7i5rxnjrh3tj6uesstcosspu.png", - name: "T's Test Vault", - type: "U", - }, - items: [ - { - uuid: "u2l4sjbencvsowwjuj3dfpt73q", - favIndex: 0, - createdAt: 1619466056, - updatedAt: 1619466187, - trashed: false, - categoryUuid: "101", - details: { - loginFields: [], - notesPlain: "My Bank Account", - sections: [ - { - title: "", - fields: [ - { - title: "bank name", - id: "bankName", - value: { - string: "Super Credit Union", - }, - indexAtSource: 0, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "words", - }, - }, - { - title: "name on account", - id: "owner", - value: { - string: "Cool Guy", - }, - indexAtSource: 1, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "words", - }, - }, - { - title: "type", - id: "accountType", - value: { - menu: "checking", - }, - indexAtSource: 2, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "routing number", - id: "routingNo", - value: { - string: "111000999", - }, - indexAtSource: 3, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numbersAndPunctuation", - correction: "default", - capitalization: "default", - }, - }, - { - title: "account number", - id: "accountNo", - value: { - string: "192837465918273645", - }, - indexAtSource: 4, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numbersAndPunctuation", - correction: "default", - capitalization: "default", - }, - }, - { - title: "SWIFT", - id: "swift", - value: { - string: "123456", - }, - indexAtSource: 5, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numbersAndPunctuation", - correction: "default", - capitalization: "default", - }, - }, - { - title: "IBAN", - id: "iban", - value: { - string: "DE12 123456", - }, - indexAtSource: 6, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numbersAndPunctuation", - correction: "default", - capitalization: "default", - }, - }, - { - title: "PIN", - id: "telephonePin", - value: { - concealed: "5555", - }, - indexAtSource: 7, - guarded: false, - multiline: false, - dontGenerate: true, - inputTraits: { - keyboard: "numberPad", - correction: "default", - capitalization: "default", - }, - }, - ], - }, - { - title: "Branch Information", - name: "branchInfo", - fields: [ - { - title: "phone", - id: "branchPhone", - value: { - phone: "9399399933", - }, - indexAtSource: 0, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "namePhonePad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "address", - id: "branchAddress", - value: { - string: "1 Fifth Avenue", - }, - indexAtSource: 1, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "sentences", - }, - }, - ], - }, - ], - passwordHistory: [], - }, - overview: { - subtitle: "Super Credit Union", - tags: ["Finance"], - title: "Bank Account", - url: "", - ps: 0, - pbe: 0.0, - pgrng: false, - }, - }, - ], - }, - ], - }, - ], -}; diff --git a/jslib/common/spec/importers/testData/onePassword1Pux/CreditCard.ts b/jslib/common/spec/importers/testData/onePassword1Pux/CreditCard.ts deleted file mode 100644 index 8b24d1b9..00000000 --- a/jslib/common/spec/importers/testData/onePassword1Pux/CreditCard.ts +++ /dev/null @@ -1,343 +0,0 @@ -import { ExportData } from "@/jslib/common/src/importers/onepasswordImporters/types/onepassword1PuxImporterTypes"; - -export const CreditCardData: ExportData = { - accounts: [ - { - attrs: { - accountName: "1Password Customer", - name: "1Password Customer", - avatar: "", - email: "username123123123@gmail.com", - uuid: "TRIZ3XV4JJFRXJ3BARILLTUA6E", - domain: "https://my.1password.com/", - }, - vaults: [ - { - attrs: { - uuid: "pqcgbqjxr4tng2hsqt5ffrgwju", - desc: "Just test entries", - avatar: "ke7i5rxnjrh3tj6uesstcosspu.png", - name: "T's Test Vault", - type: "U", - }, - items: [ - { - uuid: "vpxi2esuujz7nrbojp34rd5aja", - favIndex: 0, - createdAt: 1619465282, - updatedAt: 1619465447, - trashed: false, - categoryUuid: "002", - details: { - loginFields: [], - notesPlain: "My parents' credit card. ", - sections: [ - { - title: "", - fields: [ - { - title: "cardholder name", - id: "cardholder", - value: { - string: "Fred Engels", - }, - indexAtSource: 0, - guarded: true, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "words", - }, - }, - { - title: "type", - id: "type", - value: { - creditCardType: "discover", - }, - indexAtSource: 1, - guarded: true, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "number", - id: "ccnum", - value: { - creditCardNumber: "6011111111111117", - }, - indexAtSource: 2, - guarded: true, - clipboardFilter: "0123456789", - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numberPad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "verification number", - id: "cvv", - value: { - concealed: "1312", - }, - indexAtSource: 3, - guarded: true, - multiline: false, - dontGenerate: true, - inputTraits: { - keyboard: "numberPad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "expiry date", - id: "expiry", - value: { - monthYear: 209912, - }, - indexAtSource: 4, - guarded: true, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "valid from", - id: "validFrom", - value: { - monthYear: 200101, - }, - indexAtSource: 5, - guarded: true, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "", - id: "txbzvwzpck7ejhfres3733rbpm", - value: { - string: "card", - }, - indexAtSource: 6, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - ], - }, - { - title: "Contact Information", - name: "contactInfo", - fields: [ - { - title: "issuing bank", - id: "bank", - value: { - string: "Some bank", - }, - indexAtSource: 0, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "words", - }, - }, - { - title: "phone (local)", - id: "phoneLocal", - value: { - phone: "123456", - }, - indexAtSource: 1, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "namePhonePad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "phone (toll free)", - id: "phoneTollFree", - value: { - phone: "0800123456", - }, - indexAtSource: 2, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "namePhonePad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "phone (intl)", - id: "phoneIntl", - value: { - phone: "+49123456", - }, - indexAtSource: 3, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "namePhonePad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "website", - id: "website", - value: { - url: "somebank.com", - }, - indexAtSource: 4, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - ], - }, - { - title: "Additional Details", - name: "details", - fields: [ - { - title: "PIN", - id: "pin", - value: { - concealed: "1234", - }, - indexAtSource: 0, - guarded: false, - multiline: false, - dontGenerate: true, - inputTraits: { - keyboard: "numberPad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "credit limit", - id: "creditLimit", - value: { - string: "$1312", - }, - indexAtSource: 1, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numbersAndPunctuation", - correction: "default", - capitalization: "default", - }, - }, - { - title: "cash withdrawal limit", - id: "cashLimit", - value: { - string: "$500", - }, - indexAtSource: 2, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numbersAndPunctuation", - correction: "default", - capitalization: "default", - }, - }, - { - title: "interest rate", - id: "interest", - value: { - string: "1%", - }, - indexAtSource: 3, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numbersAndPunctuation", - correction: "default", - capitalization: "default", - }, - }, - { - title: "issue number", - id: "issuenumber", - value: { - string: "123456", - }, - indexAtSource: 4, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "no", - capitalization: "default", - }, - }, - ], - }, - ], - passwordHistory: [], - }, - overview: { - subtitle: "1234 **** 6789", - tags: ["Finance"], - title: "Parent's Credit Card", - url: "", - ps: 0, - pbe: 0.0, - pgrng: false, - }, - }, - ], - }, - ], - }, - ], -}; diff --git a/jslib/common/spec/importers/testData/onePassword1Pux/Database.ts b/jslib/common/spec/importers/testData/onePassword1Pux/Database.ts deleted file mode 100644 index 8e80874c..00000000 --- a/jslib/common/spec/importers/testData/onePassword1Pux/Database.ts +++ /dev/null @@ -1,201 +0,0 @@ -import { ExportData } from "@/jslib/common/src/importers/onepasswordImporters/types/onepassword1PuxImporterTypes"; - -export const DatabaseData: ExportData = { - accounts: [ - { - attrs: { - accountName: "1Password Customer", - name: "1Password Customer", - avatar: "", - email: "username123123123@gmail.com", - uuid: "TRIZ3XV4JJFRXJ3BARILLTUA6E", - domain: "https://my.1password.com/", - }, - vaults: [ - { - attrs: { - uuid: "pqcgbqjxr4tng2hsqt5ffrgwju", - desc: "Just test entries", - avatar: "ke7i5rxnjrh3tj6uesstcosspu.png", - name: "T's Test Vault", - type: "U", - }, - items: [ - { - uuid: "ospvepl3ex2y6hjwwqwyvtf2sy", - favIndex: 0, - createdAt: 1619466193, - updatedAt: 1619466276, - trashed: false, - categoryUuid: "102", - details: { - loginFields: [], - notesPlain: "My Database", - sections: [ - { - title: "", - fields: [ - { - title: "type", - id: "database_type", - value: { - menu: "postgresql", - }, - indexAtSource: 0, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "server", - id: "hostname", - value: { - string: "my.secret.db.server", - }, - indexAtSource: 1, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "uRL", - correction: "default", - capitalization: "default", - }, - }, - { - title: "port", - id: "port", - value: { - string: "1337", - }, - indexAtSource: 2, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numberPad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "database", - id: "database", - value: { - string: "user_database", - }, - indexAtSource: 3, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "no", - capitalization: "none", - }, - }, - { - title: "username", - id: "username", - value: { - string: "cooldbuser", - }, - indexAtSource: 4, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "no", - capitalization: "none", - }, - }, - { - title: "password", - id: "password", - value: { - concealed: "^+kTjhLaN7wVPAhGU)*J", - }, - indexAtSource: 5, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "SID", - id: "sid", - value: { - string: "ASDIUFU-283234", - }, - indexAtSource: 6, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "alias", - id: "alias", - value: { - string: "cdbu", - }, - indexAtSource: 7, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "connection options", - id: "options", - value: { - string: "ssh", - }, - indexAtSource: 8, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - ], - }, - ], - passwordHistory: [], - }, - overview: { - subtitle: "my.secret.db.server", - title: "Database", - url: "", - ps: 0, - pbe: 0.0, - pgrng: false, - }, - }, - ], - }, - ], - }, - ], -}; diff --git a/jslib/common/spec/importers/testData/onePassword1Pux/DriversLicense.ts b/jslib/common/spec/importers/testData/onePassword1Pux/DriversLicense.ts deleted file mode 100644 index e35aed1e..00000000 --- a/jslib/common/spec/importers/testData/onePassword1Pux/DriversLicense.ts +++ /dev/null @@ -1,233 +0,0 @@ -import { ExportData } from "@/jslib/common/src/importers/onepasswordImporters/types/onepassword1PuxImporterTypes"; - -export const DriversLicenseData: ExportData = { - accounts: [ - { - attrs: { - accountName: "1Password Customer", - name: "1Password Customer", - avatar: "", - email: "username123123123@gmail.com", - uuid: "TRIZ3XV4JJFRXJ3BARILLTUA6E", - domain: "https://my.1password.com/", - }, - vaults: [ - { - attrs: { - uuid: "pqcgbqjxr4tng2hsqt5ffrgwju", - desc: "Just test entries", - avatar: "ke7i5rxnjrh3tj6uesstcosspu.png", - name: "T's Test Vault", - type: "U", - }, - items: [ - { - uuid: "nntuge2g7s2wrlokyfhea354ay", - favIndex: 0, - createdAt: 1619466279, - updatedAt: 1619466425, - trashed: false, - categoryUuid: "103", - details: { - loginFields: [], - notesPlain: "My Driver's License", - sections: [ - { - title: "", - fields: [ - { - title: "full name", - id: "fullname", - value: { - string: "Michael Scarn", - }, - indexAtSource: 0, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "words", - }, - }, - { - title: "address", - id: "address", - value: { - string: "2120 Mifflin Rd.", - }, - indexAtSource: 1, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "sentences", - }, - }, - { - title: "date of birth", - id: "birthdate", - value: { - date: 252504060, - }, - indexAtSource: 2, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "sex", - id: "sex", - value: { - gender: "male", - }, - indexAtSource: 3, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "height", - id: "height", - value: { - string: "5'11\"", - }, - indexAtSource: 4, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "number", - id: "number", - value: { - string: "12345678901", - }, - indexAtSource: 5, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "license class", - id: "class", - value: { - string: "C", - }, - indexAtSource: 6, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "conditions / restrictions", - id: "conditions", - value: { - string: "B", - }, - indexAtSource: 7, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "state", - id: "state", - value: { - string: "Pennsylvania", - }, - indexAtSource: 8, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "country", - id: "country", - value: { - string: "United States", - }, - indexAtSource: 9, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "expiry date", - id: "expiry_date", - value: { - monthYear: 203012, - }, - indexAtSource: 10, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - ], - }, - ], - passwordHistory: [], - }, - overview: { - subtitle: "12345678901", - title: "Michael Scarn", - url: "", - ps: 0, - pbe: 0.0, - pgrng: false, - }, - }, - ], - }, - ], - }, - ], -}; diff --git a/jslib/common/spec/importers/testData/onePassword1Pux/EmailAccount.ts b/jslib/common/spec/importers/testData/onePassword1Pux/EmailAccount.ts deleted file mode 100644 index e345891d..00000000 --- a/jslib/common/spec/importers/testData/onePassword1Pux/EmailAccount.ts +++ /dev/null @@ -1,341 +0,0 @@ -import { ExportData } from "@/jslib/common/src/importers/onepasswordImporters/types/onepassword1PuxImporterTypes"; - -export const EmailAccountData: ExportData = { - accounts: [ - { - attrs: { - accountName: "1Password Customer", - name: "1Password Customer", - avatar: "", - email: "username123123123@gmail.com", - uuid: "TRIZ3XV4JJFRXJ3BARILLTUA6E", - domain: "https://my.1password.com/", - }, - vaults: [ - { - attrs: { - uuid: "pqcgbqjxr4tng2hsqt5ffrgwju", - desc: "Just test entries", - avatar: "ke7i5rxnjrh3tj6uesstcosspu.png", - name: "T's Test Vault", - type: "U", - }, - items: [ - { - uuid: "p3hohdgwpt4u2ra2fc3tvzomsm", - favIndex: 0, - createdAt: 1619466428, - updatedAt: 1619466585, - trashed: false, - categoryUuid: "111", - details: { - loginFields: [], - notesPlain: "My Email Config", - sections: [ - { - title: "", - fields: [ - { - title: "type", - id: "pop_type", - value: { - menu: "either", - }, - indexAtSource: 0, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "username", - id: "pop_username", - value: { - string: "someuser@nullvalue.test", - }, - indexAtSource: 1, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "no", - capitalization: "none", - }, - }, - { - title: "server", - id: "pop_server", - value: { - string: "mailserver.nullvalue.test", - }, - indexAtSource: 2, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "uRL", - correction: "default", - capitalization: "default", - }, - }, - { - title: "port number", - id: "pop_port", - value: { - string: "587", - }, - indexAtSource: 3, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numberPad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "password", - id: "pop_password", - value: { - concealed: "u1jsf - - - - - - - - - - - - This is a sample note. - 3 - - - - 5555123456789000 - John Smith - 01/23 - 555 - 1111 - 555-0153 - 1 - - - john555@gmail.com - early91*Fail* - https://www.facebook.com - 3 - - - john555@gmail.com - plain79{Area{ - https://www.google.com - 3 - thisisanotp - thisshouldbehidden - - - 555111111 - John Smith - 05/05/1980 - 01/01/2018 - 01/01/2028 - 3 - This is a note attached to a card - - - john555@gmail.com - https://twitter.com - 3 - shouldbepassword - - - john555 - Save63\apple\ - 3 - - -`; diff --git a/jslib/common/spec/misc/logInStrategies/apiLogIn.strategy.spec.ts b/jslib/common/spec/misc/logInStrategies/apiLogIn.strategy.spec.ts deleted file mode 100644 index 37b19f84..00000000 --- a/jslib/common/spec/misc/logInStrategies/apiLogIn.strategy.spec.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute"; - -import { ApiService } from "@/jslib/common/src/abstractions/api.service"; -import { AppIdService } from "@/jslib/common/src/abstractions/appId.service"; -import { CryptoService } from "@/jslib/common/src/abstractions/crypto.service"; -import { EnvironmentService } from "@/jslib/common/src/abstractions/environment.service"; -import { KeyConnectorService } from "@/jslib/common/src/abstractions/keyConnector.service"; -import { LogService } from "@/jslib/common/src/abstractions/log.service"; -import { MessagingService } from "@/jslib/common/src/abstractions/messaging.service"; -import { PlatformUtilsService } from "@/jslib/common/src/abstractions/platformUtils.service"; -import { StateService } from "@/jslib/common/src/abstractions/state.service"; -import { TokenService } from "@/jslib/common/src/abstractions/token.service"; -import { TwoFactorService } from "@/jslib/common/src/abstractions/twoFactor.service"; -import { ApiLogInStrategy } from "@/jslib/common/src/misc/logInStrategies/apiLogin.strategy"; -import { Utils } from "@/jslib/common/src/misc/utils"; -import { ApiLogInCredentials } from "@/jslib/common/src/models/domain/logInCredentials"; - -import { identityTokenResponseFactory } from "./logIn.strategy.spec"; - -describe("ApiLogInStrategy", () => { - let cryptoService: SubstituteOf; - let apiService: SubstituteOf; - let tokenService: SubstituteOf; - let appIdService: SubstituteOf; - let platformUtilsService: SubstituteOf; - let messagingService: SubstituteOf; - let logService: SubstituteOf; - let environmentService: SubstituteOf; - let keyConnectorService: SubstituteOf; - let stateService: SubstituteOf; - let twoFactorService: SubstituteOf; - - let apiLogInStrategy: ApiLogInStrategy; - let credentials: ApiLogInCredentials; - - const deviceId = Utils.newGuid(); - const keyConnectorUrl = "KEY_CONNECTOR_URL"; - const apiClientId = "API_CLIENT_ID"; - const apiClientSecret = "API_CLIENT_SECRET"; - - beforeEach(async () => { - cryptoService = Substitute.for(); - apiService = Substitute.for(); - tokenService = Substitute.for(); - appIdService = Substitute.for(); - platformUtilsService = Substitute.for(); - messagingService = Substitute.for(); - logService = Substitute.for(); - environmentService = Substitute.for(); - stateService = Substitute.for(); - keyConnectorService = Substitute.for(); - twoFactorService = Substitute.for(); - - appIdService.getAppId().resolves(deviceId); - tokenService.getTwoFactorToken().resolves(null); - - apiLogInStrategy = new ApiLogInStrategy( - cryptoService, - apiService, - tokenService, - appIdService, - platformUtilsService, - messagingService, - logService, - stateService, - twoFactorService, - environmentService, - keyConnectorService - ); - - credentials = new ApiLogInCredentials(apiClientId, apiClientSecret); - }); - - it("sends api key credentials to the server", async () => { - apiService.postIdentityToken(Arg.any()).resolves(identityTokenResponseFactory()); - await apiLogInStrategy.logIn(credentials); - - apiService.received(1).postIdentityToken( - Arg.is((actual) => { - const apiTokenRequest = actual as any; - return ( - apiTokenRequest.clientId === apiClientId && - apiTokenRequest.clientSecret === apiClientSecret && - apiTokenRequest.device.identifier === deviceId && - apiTokenRequest.twoFactor.provider == null && - apiTokenRequest.twoFactor.token == null && - apiTokenRequest.captchaResponse == null - ); - }) - ); - }); - - it("sets the local environment after a successful login", async () => { - apiService.postIdentityToken(Arg.any()).resolves(identityTokenResponseFactory()); - - await apiLogInStrategy.logIn(credentials); - - stateService.received(1).setApiKeyClientId(apiClientId); - stateService.received(1).setApiKeyClientSecret(apiClientSecret); - stateService.received(1).addAccount(Arg.any()); - }); - - it("gets and sets the Key Connector key from environmentUrl", async () => { - const tokenResponse = identityTokenResponseFactory(); - tokenResponse.apiUseKeyConnector = true; - - apiService.postIdentityToken(Arg.any()).resolves(tokenResponse); - environmentService.getKeyConnectorUrl().returns(keyConnectorUrl); - - await apiLogInStrategy.logIn(credentials); - - keyConnectorService.received(1).getAndSetKey(keyConnectorUrl); - }); -}); diff --git a/jslib/common/spec/misc/logInStrategies/logIn.strategy.spec.ts b/jslib/common/spec/misc/logInStrategies/logIn.strategy.spec.ts deleted file mode 100644 index 9cffb31b..00000000 --- a/jslib/common/spec/misc/logInStrategies/logIn.strategy.spec.ts +++ /dev/null @@ -1,288 +0,0 @@ -import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute"; - -import { ApiService } from "@/jslib/common/src/abstractions/api.service"; -import { AppIdService } from "@/jslib/common/src/abstractions/appId.service"; -import { AuthService } from "@/jslib/common/src/abstractions/auth.service"; -import { CryptoService } from "@/jslib/common/src/abstractions/crypto.service"; -import { LogService } from "@/jslib/common/src/abstractions/log.service"; -import { MessagingService } from "@/jslib/common/src/abstractions/messaging.service"; -import { PlatformUtilsService } from "@/jslib/common/src/abstractions/platformUtils.service"; -import { StateService } from "@/jslib/common/src/abstractions/state.service"; -import { TokenService } from "@/jslib/common/src/abstractions/token.service"; -import { TwoFactorService } from "@/jslib/common/src/abstractions/twoFactor.service"; -import { TwoFactorProviderType } from "@/jslib/common/src/enums/twoFactorProviderType"; -import { PasswordLogInStrategy } from "@/jslib/common/src/misc/logInStrategies/passwordLogin.strategy"; -import { Utils } from "@/jslib/common/src/misc/utils"; -import { Account, AccountProfile, AccountTokens } from "@/jslib/common/src/models/domain/account"; -import { AuthResult } from "@/jslib/common/src/models/domain/authResult"; -import { EncString } from "@/jslib/common/src/models/domain/encString"; -import { PasswordLogInCredentials } from "@/jslib/common/src/models/domain/logInCredentials"; -import { PasswordTokenRequest } from "@/jslib/common/src/models/request/identityToken/passwordTokenRequest"; -import { TokenRequestTwoFactor } from "@/jslib/common/src/models/request/identityToken/tokenRequestTwoFactor"; -import { IdentityCaptchaResponse } from "@/jslib/common/src/models/response/identityCaptchaResponse"; -import { IdentityTokenResponse } from "@/jslib/common/src/models/response/identityTokenResponse"; -import { IdentityTwoFactorResponse } from "@/jslib/common/src/models/response/identityTwoFactorResponse"; - -const email = "hello@world.com"; -const masterPassword = "password"; - -const deviceId = Utils.newGuid(); -const accessToken = "ACCESS_TOKEN"; -const refreshToken = "REFRESH_TOKEN"; -const encKey = "ENC_KEY"; -const privateKey = "PRIVATE_KEY"; -const captchaSiteKey = "CAPTCHA_SITE_KEY"; -const kdf = 0; -const kdfIterations = 10000; -const userId = Utils.newGuid(); -const masterPasswordHash = "MASTER_PASSWORD_HASH"; - -const decodedToken = { - sub: userId, - email: email, - premium: false, -}; - -const twoFactorProviderType = TwoFactorProviderType.Authenticator; -const twoFactorToken = "TWO_FACTOR_TOKEN"; -const twoFactorRemember = true; - -export function identityTokenResponseFactory() { - return new IdentityTokenResponse({ - ForcePasswordReset: false, - Kdf: kdf, - KdfIterations: kdfIterations, - Key: encKey, - PrivateKey: privateKey, - ResetMasterPassword: false, - access_token: accessToken, - expires_in: 3600, - refresh_token: refreshToken, - scope: "api offline_access", - token_type: "Bearer", - }); -} - -describe("LogInStrategy", () => { - let cryptoService: SubstituteOf; - let apiService: SubstituteOf; - let tokenService: SubstituteOf; - let appIdService: SubstituteOf; - let platformUtilsService: SubstituteOf; - let messagingService: SubstituteOf; - let logService: SubstituteOf; - let stateService: SubstituteOf; - let twoFactorService: SubstituteOf; - let authService: SubstituteOf; - - let passwordLogInStrategy: PasswordLogInStrategy; - let credentials: PasswordLogInCredentials; - - beforeEach(async () => { - cryptoService = Substitute.for(); - apiService = Substitute.for(); - tokenService = Substitute.for(); - appIdService = Substitute.for(); - platformUtilsService = Substitute.for(); - messagingService = Substitute.for(); - logService = Substitute.for(); - stateService = Substitute.for(); - twoFactorService = Substitute.for(); - authService = Substitute.for(); - - appIdService.getAppId().resolves(deviceId); - - // The base class is abstract so we test it via PasswordLogInStrategy - passwordLogInStrategy = new PasswordLogInStrategy( - cryptoService, - apiService, - tokenService, - appIdService, - platformUtilsService, - messagingService, - logService, - stateService, - twoFactorService, - authService - ); - credentials = new PasswordLogInCredentials(email, masterPassword); - }); - - describe("base class", () => { - it("sets the local environment after a successful login", async () => { - apiService.postIdentityToken(Arg.any()).resolves(identityTokenResponseFactory()); - tokenService.decodeToken(accessToken).resolves(decodedToken); - - await passwordLogInStrategy.logIn(credentials); - - stateService.received(1).addAccount( - new Account({ - profile: { - ...new AccountProfile(), - ...{ - userId: userId, - email: email, - hasPremiumPersonally: false, - kdfIterations: kdfIterations, - kdfType: kdf, - }, - }, - tokens: { - ...new AccountTokens(), - ...{ - accessToken: accessToken, - refreshToken: refreshToken, - }, - }, - }) - ); - cryptoService.received(1).setEncKey(encKey); - cryptoService.received(1).setEncPrivateKey(privateKey); - - stateService.received(1).setBiometricLocked(false); - messagingService.received(1).send("loggedIn"); - }); - - it("builds AuthResult", async () => { - const tokenResponse = identityTokenResponseFactory(); - tokenResponse.forcePasswordReset = true; - tokenResponse.resetMasterPassword = true; - - apiService.postIdentityToken(Arg.any()).resolves(tokenResponse); - - const result = await passwordLogInStrategy.logIn(credentials); - - const expected = new AuthResult(); - expected.forcePasswordReset = true; - expected.resetMasterPassword = true; - expected.twoFactorProviders = null; - expected.captchaSiteKey = ""; - expect(result).toEqual(expected); - }); - - it("rejects login if CAPTCHA is required", async () => { - // Sample CAPTCHA response - const tokenResponse = new IdentityCaptchaResponse({ - error: "invalid_grant", - error_description: "Captcha required.", - HCaptcha_SiteKey: captchaSiteKey, - }); - - apiService.postIdentityToken(Arg.any()).resolves(tokenResponse); - - const result = await passwordLogInStrategy.logIn(credentials); - - stateService.didNotReceive().addAccount(Arg.any()); - messagingService.didNotReceive().send(Arg.any()); - - const expected = new AuthResult(); - expected.captchaSiteKey = captchaSiteKey; - expect(result).toEqual(expected); - }); - - it("makes a new public and private key for an old account", async () => { - const tokenResponse = identityTokenResponseFactory(); - tokenResponse.privateKey = null; - cryptoService.makeKeyPair(Arg.any()).resolves(["PUBLIC_KEY", new EncString("PRIVATE_KEY")]); - - apiService.postIdentityToken(Arg.any()).resolves(tokenResponse); - - await passwordLogInStrategy.logIn(credentials); - - apiService.received(1).postAccountKeys(Arg.any()); - }); - }); - - describe("Two-factor authentication", () => { - it("rejects login if 2FA is required", async () => { - // Sample response where TOTP 2FA required - const tokenResponse = new IdentityTwoFactorResponse({ - TwoFactorProviders: ["0"], - TwoFactorProviders2: { 0: null }, - error: "invalid_grant", - error_description: "Two factor required.", - }); - - apiService.postIdentityToken(Arg.any()).resolves(tokenResponse); - - const result = await passwordLogInStrategy.logIn(credentials); - - stateService.didNotReceive().addAccount(Arg.any()); - messagingService.didNotReceive().send(Arg.any()); - - const expected = new AuthResult(); - expected.twoFactorProviders = new Map(); - expected.twoFactorProviders.set(0, null); - expect(result).toEqual(expected); - }); - - it("sends stored 2FA token to server", async () => { - tokenService.getTwoFactorToken().resolves(twoFactorToken); - apiService.postIdentityToken(Arg.any()).resolves(identityTokenResponseFactory()); - - await passwordLogInStrategy.logIn(credentials); - - apiService.received(1).postIdentityToken( - Arg.is((actual) => { - const passwordTokenRequest = actual as any; - return ( - passwordTokenRequest.twoFactor.provider === TwoFactorProviderType.Remember && - passwordTokenRequest.twoFactor.token === twoFactorToken && - passwordTokenRequest.twoFactor.remember === false - ); - }) - ); - }); - - it("sends 2FA token provided by user to server (single step)", async () => { - // This occurs if the user enters the 2FA code as an argument in the CLI - apiService.postIdentityToken(Arg.any()).resolves(identityTokenResponseFactory()); - credentials.twoFactor = new TokenRequestTwoFactor( - twoFactorProviderType, - twoFactorToken, - twoFactorRemember - ); - - await passwordLogInStrategy.logIn(credentials); - - apiService.received(1).postIdentityToken( - Arg.is((actual) => { - const passwordTokenRequest = actual as any; - return ( - passwordTokenRequest.twoFactor.provider === twoFactorProviderType && - passwordTokenRequest.twoFactor.token === twoFactorToken && - passwordTokenRequest.twoFactor.remember === twoFactorRemember - ); - }) - ); - }); - - it("sends 2FA token provided by user to server (two-step)", async () => { - // Simulate a partially completed login - passwordLogInStrategy.tokenRequest = new PasswordTokenRequest( - email, - masterPasswordHash, - null, - null - ); - - apiService.postIdentityToken(Arg.any()).resolves(identityTokenResponseFactory()); - - await passwordLogInStrategy.logInTwoFactor( - new TokenRequestTwoFactor(twoFactorProviderType, twoFactorToken, twoFactorRemember), - null - ); - - apiService.received(1).postIdentityToken( - Arg.is((actual) => { - const passwordTokenRequest = actual as any; - return ( - passwordTokenRequest.twoFactor.provider === twoFactorProviderType && - passwordTokenRequest.twoFactor.token === twoFactorToken && - passwordTokenRequest.twoFactor.remember === twoFactorRemember - ); - }) - ); - }); - }); -}); diff --git a/jslib/common/spec/misc/logInStrategies/passwordLogIn.strategy.spec.ts b/jslib/common/spec/misc/logInStrategies/passwordLogIn.strategy.spec.ts deleted file mode 100644 index 9e95f7f2..00000000 --- a/jslib/common/spec/misc/logInStrategies/passwordLogIn.strategy.spec.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute"; - -import { ApiService } from "@/jslib/common/src/abstractions/api.service"; -import { AppIdService } from "@/jslib/common/src/abstractions/appId.service"; -import { AuthService } from "@/jslib/common/src/abstractions/auth.service"; -import { CryptoService } from "@/jslib/common/src/abstractions/crypto.service"; -import { LogService } from "@/jslib/common/src/abstractions/log.service"; -import { MessagingService } from "@/jslib/common/src/abstractions/messaging.service"; -import { PlatformUtilsService } from "@/jslib/common/src/abstractions/platformUtils.service"; -import { StateService } from "@/jslib/common/src/abstractions/state.service"; -import { TokenService } from "@/jslib/common/src/abstractions/token.service"; -import { TwoFactorService } from "@/jslib/common/src/abstractions/twoFactor.service"; -import { HashPurpose } from "@/jslib/common/src/enums/hashPurpose"; -import { PasswordLogInStrategy } from "@/jslib/common/src/misc/logInStrategies/passwordLogin.strategy"; -import { Utils } from "@/jslib/common/src/misc/utils"; -import { PasswordLogInCredentials } from "@/jslib/common/src/models/domain/logInCredentials"; -import { SymmetricCryptoKey } from "@/jslib/common/src/models/domain/symmetricCryptoKey"; - -import { identityTokenResponseFactory } from "./logIn.strategy.spec"; - -const email = "hello@world.com"; -const masterPassword = "password"; -const hashedPassword = "HASHED_PASSWORD"; -const localHashedPassword = "LOCAL_HASHED_PASSWORD"; -const preloginKey = new SymmetricCryptoKey( - Utils.fromB64ToArray( - "N2KWjlLpfi5uHjv+YcfUKIpZ1l+W+6HRensmIqD+BFYBf6N/dvFpJfWwYnVBdgFCK2tJTAIMLhqzIQQEUmGFgg==" - ) -); -const deviceId = Utils.newGuid(); - -describe("PasswordLogInStrategy", () => { - let cryptoService: SubstituteOf; - let apiService: SubstituteOf; - let tokenService: SubstituteOf; - let appIdService: SubstituteOf; - let platformUtilsService: SubstituteOf; - let messagingService: SubstituteOf; - let logService: SubstituteOf; - let stateService: SubstituteOf; - let twoFactorService: SubstituteOf; - let authService: SubstituteOf; - - let passwordLogInStrategy: PasswordLogInStrategy; - let credentials: PasswordLogInCredentials; - - beforeEach(async () => { - cryptoService = Substitute.for(); - apiService = Substitute.for(); - tokenService = Substitute.for(); - appIdService = Substitute.for(); - platformUtilsService = Substitute.for(); - messagingService = Substitute.for(); - logService = Substitute.for(); - stateService = Substitute.for(); - twoFactorService = Substitute.for(); - authService = Substitute.for(); - - appIdService.getAppId().resolves(deviceId); - tokenService.getTwoFactorToken().resolves(null); - - authService.makePreloginKey(Arg.any(), Arg.any()).resolves(preloginKey); - - cryptoService.hashPassword(masterPassword, Arg.any()).resolves(hashedPassword); - cryptoService - .hashPassword(masterPassword, Arg.any(), HashPurpose.LocalAuthorization) - .resolves(localHashedPassword); - - passwordLogInStrategy = new PasswordLogInStrategy( - cryptoService, - apiService, - tokenService, - appIdService, - platformUtilsService, - messagingService, - logService, - stateService, - twoFactorService, - authService - ); - credentials = new PasswordLogInCredentials(email, masterPassword); - - apiService.postIdentityToken(Arg.any()).resolves(identityTokenResponseFactory()); - }); - - it("sends master password credentials to the server", async () => { - await passwordLogInStrategy.logIn(credentials); - - apiService.received(1).postIdentityToken( - Arg.is((actual) => { - const passwordTokenRequest = actual as any; // Need to access private fields - return ( - passwordTokenRequest.email === email && - passwordTokenRequest.masterPasswordHash === hashedPassword && - passwordTokenRequest.device.identifier === deviceId && - passwordTokenRequest.twoFactor.provider == null && - passwordTokenRequest.twoFactor.token == null && - passwordTokenRequest.captchaResponse == null - ); - }) - ); - }); - - it("sets the local environment after a successful login", async () => { - await passwordLogInStrategy.logIn(credentials); - - cryptoService.received(1).setKey(preloginKey); - cryptoService.received(1).setKeyHash(localHashedPassword); - }); -}); diff --git a/jslib/common/spec/misc/logInStrategies/ssoLogIn.strategy.spec.ts b/jslib/common/spec/misc/logInStrategies/ssoLogIn.strategy.spec.ts deleted file mode 100644 index 25fc4ba0..00000000 --- a/jslib/common/spec/misc/logInStrategies/ssoLogIn.strategy.spec.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute"; - -import { ApiService } from "@/jslib/common/src/abstractions/api.service"; -import { AppIdService } from "@/jslib/common/src/abstractions/appId.service"; -import { CryptoService } from "@/jslib/common/src/abstractions/crypto.service"; -import { KeyConnectorService } from "@/jslib/common/src/abstractions/keyConnector.service"; -import { LogService } from "@/jslib/common/src/abstractions/log.service"; -import { MessagingService } from "@/jslib/common/src/abstractions/messaging.service"; -import { PlatformUtilsService } from "@/jslib/common/src/abstractions/platformUtils.service"; -import { StateService } from "@/jslib/common/src/abstractions/state.service"; -import { TokenService } from "@/jslib/common/src/abstractions/token.service"; -import { TwoFactorService } from "@/jslib/common/src/abstractions/twoFactor.service"; -import { SsoLogInStrategy } from "@/jslib/common/src/misc/logInStrategies/ssoLogin.strategy"; -import { Utils } from "@/jslib/common/src/misc/utils"; -import { SsoLogInCredentials } from "@/jslib/common/src/models/domain/logInCredentials"; - -import { identityTokenResponseFactory } from "./logIn.strategy.spec"; - -describe("SsoLogInStrategy", () => { - let cryptoService: SubstituteOf; - let apiService: SubstituteOf; - let tokenService: SubstituteOf; - let appIdService: SubstituteOf; - let platformUtilsService: SubstituteOf; - let messagingService: SubstituteOf; - let logService: SubstituteOf; - let keyConnectorService: SubstituteOf; - let stateService: SubstituteOf; - let twoFactorService: SubstituteOf; - - let ssoLogInStrategy: SsoLogInStrategy; - let credentials: SsoLogInCredentials; - - const deviceId = Utils.newGuid(); - const encKey = "ENC_KEY"; - const privateKey = "PRIVATE_KEY"; - const keyConnectorUrl = "KEY_CONNECTOR_URL"; - - const ssoCode = "SSO_CODE"; - const ssoCodeVerifier = "SSO_CODE_VERIFIER"; - const ssoRedirectUrl = "SSO_REDIRECT_URL"; - const ssoOrgId = "SSO_ORG_ID"; - - beforeEach(async () => { - cryptoService = Substitute.for(); - apiService = Substitute.for(); - tokenService = Substitute.for(); - appIdService = Substitute.for(); - platformUtilsService = Substitute.for(); - messagingService = Substitute.for(); - logService = Substitute.for(); - stateService = Substitute.for(); - keyConnectorService = Substitute.for(); - twoFactorService = Substitute.for(); - - tokenService.getTwoFactorToken().resolves(null); - appIdService.getAppId().resolves(deviceId); - - ssoLogInStrategy = new SsoLogInStrategy( - cryptoService, - apiService, - tokenService, - appIdService, - platformUtilsService, - messagingService, - logService, - stateService, - twoFactorService, - keyConnectorService - ); - credentials = new SsoLogInCredentials(ssoCode, ssoCodeVerifier, ssoRedirectUrl, ssoOrgId); - }); - - it("sends SSO information to server", async () => { - apiService.postIdentityToken(Arg.any()).resolves(identityTokenResponseFactory()); - - await ssoLogInStrategy.logIn(credentials); - - apiService.received(1).postIdentityToken( - Arg.is((actual) => { - const ssoTokenRequest = actual as any; - return ( - ssoTokenRequest.code === ssoCode && - ssoTokenRequest.codeVerifier === ssoCodeVerifier && - ssoTokenRequest.redirectUri === ssoRedirectUrl && - ssoTokenRequest.device.identifier === deviceId && - ssoTokenRequest.twoFactor.provider == null && - ssoTokenRequest.twoFactor.token == null - ); - }) - ); - }); - - it("does not set keys for new SSO user flow", async () => { - const tokenResponse = identityTokenResponseFactory(); - tokenResponse.key = null; - apiService.postIdentityToken(Arg.any()).resolves(tokenResponse); - - await ssoLogInStrategy.logIn(credentials); - - cryptoService.didNotReceive().setEncPrivateKey(privateKey); - cryptoService.didNotReceive().setEncKey(encKey); - }); - - it("gets and sets KeyConnector key for enrolled user", async () => { - const tokenResponse = identityTokenResponseFactory(); - tokenResponse.keyConnectorUrl = keyConnectorUrl; - - apiService.postIdentityToken(Arg.any()).resolves(tokenResponse); - - await ssoLogInStrategy.logIn(credentials); - - keyConnectorService.received(1).getAndSetKey(keyConnectorUrl); - }); - - it("converts new SSO user to Key Connector on first login", async () => { - const tokenResponse = identityTokenResponseFactory(); - tokenResponse.keyConnectorUrl = keyConnectorUrl; - tokenResponse.key = null; - - apiService.postIdentityToken(Arg.any()).resolves(tokenResponse); - - await ssoLogInStrategy.logIn(credentials); - - keyConnectorService.received(1).convertNewSsoUserToKeyConnector(tokenResponse, ssoOrgId); - }); -}); diff --git a/jslib/common/spec/misc/sequentialize.spec.ts b/jslib/common/spec/misc/sequentialize.spec.ts deleted file mode 100644 index 7a1be5f7..00000000 --- a/jslib/common/spec/misc/sequentialize.spec.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { sequentialize } from "@/jslib/common/src/misc/sequentialize"; - -describe("sequentialize decorator", () => { - it("should call the function once", async () => { - const foo = new Foo(); - const promises = []; - for (let i = 0; i < 10; i++) { - promises.push(foo.bar(1)); - } - await Promise.all(promises); - - expect(foo.calls).toBe(1); - }); - - it("should call the function once for each instance of the object", async () => { - const foo = new Foo(); - const foo2 = new Foo(); - const promises = []; - for (let i = 0; i < 10; i++) { - promises.push(foo.bar(1)); - promises.push(foo2.bar(1)); - } - await Promise.all(promises); - - expect(foo.calls).toBe(1); - expect(foo2.calls).toBe(1); - }); - - it("should call the function once with key function", async () => { - const foo = new Foo(); - const promises = []; - for (let i = 0; i < 10; i++) { - promises.push(foo.baz(1)); - } - await Promise.all(promises); - - expect(foo.calls).toBe(1); - }); - - it("should call the function again when already resolved", async () => { - const foo = new Foo(); - await foo.bar(1); - expect(foo.calls).toBe(1); - await foo.bar(1); - expect(foo.calls).toBe(2); - }); - - it("should call the function again when already resolved with a key function", async () => { - const foo = new Foo(); - await foo.baz(1); - expect(foo.calls).toBe(1); - await foo.baz(1); - expect(foo.calls).toBe(2); - }); - - it("should call the function for each argument", async () => { - const foo = new Foo(); - await Promise.all([foo.bar(1), foo.bar(1), foo.bar(2), foo.bar(2), foo.bar(3), foo.bar(3)]); - expect(foo.calls).toBe(3); - }); - - it("should call the function for each argument with key function", async () => { - const foo = new Foo(); - await Promise.all([foo.baz(1), foo.baz(1), foo.baz(2), foo.baz(2), foo.baz(3), foo.baz(3)]); - expect(foo.calls).toBe(3); - }); - - it("should return correct result for each call", async () => { - const foo = new Foo(); - const allRes: number[] = []; - - await Promise.all([ - foo.bar(1).then((res) => allRes.push(res)), - foo.bar(1).then((res) => allRes.push(res)), - foo.bar(2).then((res) => allRes.push(res)), - foo.bar(2).then((res) => allRes.push(res)), - foo.bar(3).then((res) => allRes.push(res)), - foo.bar(3).then((res) => allRes.push(res)), - ]); - expect(foo.calls).toBe(3); - expect(allRes.length).toBe(6); - allRes.sort(); - expect(allRes).toEqual([2, 2, 4, 4, 6, 6]); - }); - - it("should return correct result for each call with key function", async () => { - const foo = new Foo(); - const allRes: number[] = []; - - await Promise.all([ - foo.baz(1).then((res) => allRes.push(res)), - foo.baz(1).then((res) => allRes.push(res)), - foo.baz(2).then((res) => allRes.push(res)), - foo.baz(2).then((res) => allRes.push(res)), - foo.baz(3).then((res) => allRes.push(res)), - foo.baz(3).then((res) => allRes.push(res)), - ]); - expect(foo.calls).toBe(3); - expect(allRes.length).toBe(6); - allRes.sort(); - expect(allRes).toEqual([3, 3, 6, 6, 9, 9]); - }); -}); - -class Foo { - calls = 0; - - @sequentialize((args) => "bar" + args[0]) - bar(a: number): Promise { - this.calls++; - return new Promise((res) => { - setTimeout(() => { - res(a * 2); - }, Math.random() * 100); - }); - } - - @sequentialize((args) => "baz" + args[0]) - baz(a: number): Promise { - this.calls++; - return new Promise((res) => { - setTimeout(() => { - res(a * 3); - }, Math.random() * 100); - }); - } -} diff --git a/jslib/common/spec/misc/throttle.spec.ts b/jslib/common/spec/misc/throttle.spec.ts deleted file mode 100644 index f9f3bd2c..00000000 --- a/jslib/common/spec/misc/throttle.spec.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { sequentialize } from "@/jslib/common/src/misc/sequentialize"; -import { throttle } from "@/jslib/common/src/misc/throttle"; - -describe("throttle decorator", () => { - it("should call the function once at a time", async () => { - const foo = new Foo(); - const promises = []; - for (let i = 0; i < 10; i++) { - promises.push(foo.bar(1)); - } - await Promise.all(promises); - - expect(foo.calls).toBe(10); - }); - - it("should call the function once at a time for each object", async () => { - const foo = new Foo(); - const foo2 = new Foo(); - const promises = []; - for (let i = 0; i < 10; i++) { - promises.push(foo.bar(1)); - promises.push(foo2.bar(1)); - } - await Promise.all(promises); - - expect(foo.calls).toBe(10); - expect(foo2.calls).toBe(10); - }); - - it("should call the function limit at a time", async () => { - const foo = new Foo(); - const promises = []; - for (let i = 0; i < 10; i++) { - promises.push(foo.baz(1)); - } - await Promise.all(promises); - - expect(foo.calls).toBe(10); - }); - - it("should call the function limit at a time for each object", async () => { - const foo = new Foo(); - const foo2 = new Foo(); - const promises = []; - for (let i = 0; i < 10; i++) { - promises.push(foo.baz(1)); - promises.push(foo2.baz(1)); - } - await Promise.all(promises); - - expect(foo.calls).toBe(10); - expect(foo2.calls).toBe(10); - }); - - it("should work together with sequentialize", async () => { - const foo = new Foo(); - const promises = []; - for (let i = 0; i < 10; i++) { - promises.push(foo.qux(Math.floor(i / 2) * 2)); - } - await Promise.all(promises); - - expect(foo.calls).toBe(5); - }); -}); - -class Foo { - calls = 0; - inflight = 0; - - @throttle(1, () => "bar") - bar(a: number) { - this.calls++; - this.inflight++; - return new Promise((res) => { - setTimeout(() => { - expect(this.inflight).toBe(1); - this.inflight--; - res(a * 2); - }, Math.random() * 10); - }); - } - - @throttle(5, () => "baz") - baz(a: number) { - this.calls++; - this.inflight++; - return new Promise((res) => { - setTimeout(() => { - expect(this.inflight).toBeLessThanOrEqual(5); - this.inflight--; - res(a * 3); - }, Math.random() * 10); - }); - } - - @sequentialize((args) => "qux" + args[0]) - @throttle(1, () => "qux") - qux(a: number) { - this.calls++; - this.inflight++; - return new Promise((res) => { - setTimeout(() => { - expect(this.inflight).toBe(1); - this.inflight--; - res(a * 3); - }, Math.random() * 10); - }); - } -} diff --git a/jslib/common/spec/misc/utils.spec.ts b/jslib/common/spec/misc/utils.spec.ts deleted file mode 100644 index cada0117..00000000 --- a/jslib/common/spec/misc/utils.spec.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { Utils } from "@/jslib/common/src/misc/utils"; - -describe("Utils Service", () => { - describe("getDomain", () => { - it("should fail for invalid urls", () => { - expect(Utils.getDomain(null)).toBeNull(); - expect(Utils.getDomain(undefined)).toBeNull(); - expect(Utils.getDomain(" ")).toBeNull(); - expect(Utils.getDomain('https://bit!:"_&ward.com')).toBeNull(); - expect(Utils.getDomain("bitwarden")).toBeNull(); - }); - - it("should fail for data urls", () => { - expect(Utils.getDomain("data:image/jpeg;base64,AAA")).toBeNull(); - }); - - it("should handle urls without protocol", () => { - expect(Utils.getDomain("bitwarden.com")).toBe("bitwarden.com"); - expect(Utils.getDomain("wrong://bitwarden.com")).toBe("bitwarden.com"); - }); - - it("should handle valid urls", () => { - expect(Utils.getDomain("https://bitwarden")).toBe("bitwarden"); - expect(Utils.getDomain("https://bitwarden.com")).toBe("bitwarden.com"); - expect(Utils.getDomain("http://bitwarden.com")).toBe("bitwarden.com"); - expect(Utils.getDomain("http://vault.bitwarden.com")).toBe("bitwarden.com"); - expect( - Utils.getDomain("https://user:password@bitwarden.com:8080/password/sites?and&query#hash") - ).toBe("bitwarden.com"); - expect(Utils.getDomain("https://bitwarden.unknown")).toBe("bitwarden.unknown"); - }); - - it("should support localhost and IP", () => { - expect(Utils.getDomain("https://localhost")).toBe("localhost"); - expect(Utils.getDomain("https://192.168.1.1")).toBe("192.168.1.1"); - }); - - it("should reject invalid hostnames", () => { - expect(Utils.getDomain("https://mywebsite.com$.mywebsite.com")).toBeNull(); - expect(Utils.getDomain("https://mywebsite.com!.mywebsite.com")).toBeNull(); - }); - }); - - describe("getHostname", () => { - it("should fail for invalid urls", () => { - expect(Utils.getHostname(null)).toBeNull(); - expect(Utils.getHostname(undefined)).toBeNull(); - expect(Utils.getHostname(" ")).toBeNull(); - expect(Utils.getHostname('https://bit!:"_&ward.com')).toBeNull(); - expect(Utils.getHostname("bitwarden")).toBeNull(); - }); - - it("should handle valid urls", () => { - expect(Utils.getHostname("bitwarden.com")).toBe("bitwarden.com"); - expect(Utils.getHostname("https://bitwarden.com")).toBe("bitwarden.com"); - expect(Utils.getHostname("http://bitwarden.com")).toBe("bitwarden.com"); - expect(Utils.getHostname("http://vault.bitwarden.com")).toBe("vault.bitwarden.com"); - }); - - it("should support localhost and IP", () => { - expect(Utils.getHostname("https://localhost")).toBe("localhost"); - expect(Utils.getHostname("https://192.168.1.1")).toBe("192.168.1.1"); - }); - }); - - describe("newGuid", () => { - it("should create a valid guid", () => { - const validGuid = - /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; - expect(Utils.newGuid()).toMatch(validGuid); - }); - }); -}); diff --git a/jslib/common/spec/services/cipher.service.spec.ts b/jslib/common/spec/services/cipher.service.spec.ts deleted file mode 100644 index f36612f2..00000000 --- a/jslib/common/spec/services/cipher.service.spec.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute"; - -import { ApiService } from "@/jslib/common/src/abstractions/api.service"; -import { CryptoService } from "@/jslib/common/src/abstractions/crypto.service"; -import { FileUploadService } from "@/jslib/common/src/abstractions/fileUpload.service"; -import { I18nService } from "@/jslib/common/src/abstractions/i18n.service"; -import { LogService } from "@/jslib/common/src/abstractions/log.service"; -import { SearchService } from "@/jslib/common/src/abstractions/search.service"; -import { SettingsService } from "@/jslib/common/src/abstractions/settings.service"; -import { StateService } from "@/jslib/common/src/abstractions/state.service"; -import { Utils } from "@/jslib/common/src/misc/utils"; -import { Cipher } from "@/jslib/common/src/models/domain/cipher"; -import { EncArrayBuffer } from "@/jslib/common/src/models/domain/encArrayBuffer"; -import { EncString } from "@/jslib/common/src/models/domain/encString"; -import { SymmetricCryptoKey } from "@/jslib/common/src/models/domain/symmetricCryptoKey"; -import { CipherService } from "@/jslib/common/src/services/cipher.service"; - -const ENCRYPTED_TEXT = "This data has been encrypted"; -const ENCRYPTED_BYTES = new EncArrayBuffer(Utils.fromUtf8ToArray(ENCRYPTED_TEXT).buffer); - -describe("Cipher Service", () => { - let cryptoService: SubstituteOf; - let stateService: SubstituteOf; - let settingsService: SubstituteOf; - let apiService: SubstituteOf; - let fileUploadService: SubstituteOf; - let i18nService: SubstituteOf; - let searchService: SubstituteOf; - let logService: SubstituteOf; - - let cipherService: CipherService; - - beforeEach(() => { - cryptoService = Substitute.for(); - stateService = Substitute.for(); - settingsService = Substitute.for(); - apiService = Substitute.for(); - fileUploadService = Substitute.for(); - i18nService = Substitute.for(); - searchService = Substitute.for(); - logService = Substitute.for(); - - cryptoService.encryptToBytes(Arg.any(), Arg.any()).resolves(ENCRYPTED_BYTES); - cryptoService.encrypt(Arg.any(), Arg.any()).resolves(new EncString(ENCRYPTED_TEXT)); - - cipherService = new CipherService( - cryptoService, - settingsService, - apiService, - fileUploadService, - i18nService, - () => searchService, - logService, - stateService - ); - }); - - it("attachments upload encrypted file contents", async () => { - const fileName = "filename"; - const fileData = new Uint8Array(10).buffer; - cryptoService.getOrgKey(Arg.any()).resolves(new SymmetricCryptoKey(new Uint8Array(32).buffer)); - - await cipherService.saveAttachmentRawWithServer(new Cipher(), fileName, fileData); - - fileUploadService - .received(1) - .uploadCipherAttachment(Arg.any(), Arg.any(), new EncString(ENCRYPTED_TEXT), ENCRYPTED_BYTES); - }); -}); diff --git a/jslib/common/spec/services/consoleLog.service.spec.ts b/jslib/common/spec/services/consoleLog.service.spec.ts deleted file mode 100644 index 59c08882..00000000 --- a/jslib/common/spec/services/consoleLog.service.spec.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ConsoleLogService } from "@/jslib/common/src/services/consoleLog.service"; - -const originalConsole = console; -let caughtMessage: any; - -declare let console: any; - -export function interceptConsole(interceptions: any): object { - console = { - log: function () { - // eslint-disable-next-line - interceptions.log = arguments; - }, - warn: function () { - // eslint-disable-next-line - interceptions.warn = arguments; - }, - error: function () { - // eslint-disable-next-line - interceptions.error = arguments; - }, - }; - return interceptions; -} - -export function restoreConsole() { - console = originalConsole; -} - -describe("ConsoleLogService", () => { - let logService: ConsoleLogService; - beforeEach(() => { - caughtMessage = {}; - interceptConsole(caughtMessage); - logService = new ConsoleLogService(true); - }); - - afterAll(() => { - restoreConsole(); - }); - - it("filters messages below the set threshold", () => { - logService = new ConsoleLogService(true, () => true); - logService.debug("debug"); - logService.info("info"); - logService.warning("warning"); - logService.error("error"); - - expect(caughtMessage).toEqual({}); - }); - it("only writes debug messages in dev mode", () => { - logService = new ConsoleLogService(false); - - logService.debug("debug message"); - expect(caughtMessage.log).toBeUndefined(); - }); - - it("writes debug/info messages to console.log", () => { - logService.debug("this is a debug message"); - expect(caughtMessage).toMatchObject({ - log: { "0": "this is a debug message" }, - }); - - logService.info("this is an info message"); - expect(caughtMessage).toMatchObject({ - log: { "0": "this is an info message" }, - }); - }); - it("writes warning messages to console.warn", () => { - logService.warning("this is a warning message"); - expect(caughtMessage).toMatchObject({ - warn: { 0: "this is a warning message" }, - }); - }); - it("writes error messages to console.error", () => { - logService.error("this is an error message"); - expect(caughtMessage).toMatchObject({ - error: { 0: "this is an error message" }, - }); - }); - - it("times with output to info", async () => { - logService.time(); - await new Promise((r) => setTimeout(r, 250)); - const duration = logService.timeEnd(); - expect(duration[0]).toBe(0); - expect(duration[1]).toBeGreaterThan(0); - expect(duration[1]).toBeLessThan(500 * 10e6); - - expect(caughtMessage).toEqual(expect.arrayContaining([])); - expect(caughtMessage.log.length).toBe(1); - expect(caughtMessage.log[0]).toEqual(expect.stringMatching(/^default: \d+\.?\d*ms$/)); - }); - - it("filters time output", async () => { - logService = new ConsoleLogService(true, () => true); - logService.time(); - logService.timeEnd(); - - expect(caughtMessage).toEqual({}); - }); -}); diff --git a/jslib/common/spec/services/export.service.spec.ts b/jslib/common/spec/services/export.service.spec.ts deleted file mode 100644 index 7361e292..00000000 --- a/jslib/common/spec/services/export.service.spec.ts +++ /dev/null @@ -1,209 +0,0 @@ -import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute"; - -import { ApiService } from "@/jslib/common/src/abstractions/api.service"; -import { CipherService } from "@/jslib/common/src/abstractions/cipher.service"; -import { CryptoService } from "@/jslib/common/src/abstractions/crypto.service"; -import { CryptoFunctionService } from "@/jslib/common/src/abstractions/cryptoFunction.service"; -import { FolderService } from "@/jslib/common/src/abstractions/folder.service"; -import { CipherType } from "@/jslib/common/src/enums/cipherType"; -import { KdfType } from "@/jslib/common/src/enums/kdfType"; -import { Utils } from "@/jslib/common/src/misc/utils"; -import { Cipher } from "@/jslib/common/src/models/domain/cipher"; -import { EncString } from "@/jslib/common/src/models/domain/encString"; -import { Login } from "@/jslib/common/src/models/domain/login"; -import { CipherWithIds as CipherExport } from "@/jslib/common/src/models/export/cipherWithIds"; -import { CipherView } from "@/jslib/common/src/models/view/cipherView"; -import { LoginView } from "@/jslib/common/src/models/view/loginView"; -import { ExportService } from "@/jslib/common/src/services/export.service"; - -import { BuildTestObject, GetUniqueString } from "../utils"; - -const UserCipherViews = [ - generateCipherView(false), - generateCipherView(false), - generateCipherView(true), -]; - -const UserCipherDomains = [ - generateCipherDomain(false), - generateCipherDomain(false), - generateCipherDomain(true), -]; - -function generateCipherView(deleted: boolean) { - return BuildTestObject( - { - id: GetUniqueString("id"), - notes: GetUniqueString("notes"), - type: CipherType.Login, - login: BuildTestObject( - { - username: GetUniqueString("username"), - password: GetUniqueString("password"), - }, - LoginView - ), - collectionIds: null, - deletedDate: deleted ? new Date() : null, - }, - CipherView - ); -} - -function generateCipherDomain(deleted: boolean) { - return BuildTestObject( - { - id: GetUniqueString("id"), - notes: new EncString(GetUniqueString("notes")), - type: CipherType.Login, - login: BuildTestObject( - { - username: new EncString(GetUniqueString("username")), - password: new EncString(GetUniqueString("password")), - }, - Login - ), - collectionIds: null, - deletedDate: deleted ? new Date() : null, - }, - Cipher - ); -} - -function expectEqualCiphers(ciphers: CipherView[] | Cipher[], jsonResult: string) { - const actual = JSON.stringify(JSON.parse(jsonResult).items); - const items: CipherExport[] = []; - ciphers.forEach((c: CipherView | Cipher) => { - const item = new CipherExport(); - item.build(c); - items.push(item); - }); - - expect(actual).toEqual(JSON.stringify(items)); -} - -describe("ExportService", () => { - let exportService: ExportService; - let apiService: SubstituteOf; - let cryptoFunctionService: SubstituteOf; - let cipherService: SubstituteOf; - let folderService: SubstituteOf; - let cryptoService: SubstituteOf; - - beforeEach(() => { - apiService = Substitute.for(); - cryptoFunctionService = Substitute.for(); - cipherService = Substitute.for(); - folderService = Substitute.for(); - cryptoService = Substitute.for(); - - folderService.getAllDecrypted().resolves([]); - folderService.getAll().resolves([]); - - exportService = new ExportService( - folderService, - cipherService, - apiService, - cryptoService, - cryptoFunctionService - ); - }); - - it("exports unecrypted user ciphers", async () => { - cipherService.getAllDecrypted().resolves(UserCipherViews.slice(0, 1)); - - const actual = await exportService.getExport("json"); - - expectEqualCiphers(UserCipherViews.slice(0, 1), actual); - }); - - it("exports encrypted json user ciphers", async () => { - cipherService.getAll().resolves(UserCipherDomains.slice(0, 1)); - - const actual = await exportService.getExport("encrypted_json"); - - expectEqualCiphers(UserCipherDomains.slice(0, 1), actual); - }); - - it("does not unecrypted export trashed user items", async () => { - cipherService.getAllDecrypted().resolves(UserCipherViews); - - const actual = await exportService.getExport("json"); - - expectEqualCiphers(UserCipherViews.slice(0, 2), actual); - }); - - it("does not encrypted export trashed user items", async () => { - cipherService.getAll().resolves(UserCipherDomains); - - const actual = await exportService.getExport("encrypted_json"); - - expectEqualCiphers(UserCipherDomains.slice(0, 2), actual); - }); - - describe("password protected export", () => { - let exportString: string; - let exportObject: any; - let mac: SubstituteOf; - let data: SubstituteOf; - const password = "password"; - const salt = "salt"; - - describe("export json object", () => { - beforeEach(async () => { - mac = Substitute.for(); - data = Substitute.for(); - - mac.encryptedString.returns("mac"); - data.encryptedString.returns("encData"); - - jest.spyOn(Utils, "fromBufferToB64").mockReturnValue(salt); - cipherService.getAllDecrypted().resolves(UserCipherViews.slice(0, 1)); - - exportString = await exportService.getPasswordProtectedExport(password); - exportObject = JSON.parse(exportString); - }); - - it("specifies it is encrypted", () => { - expect(exportObject.encrypted).toBe(true); - }); - - it("specifies it's password protected", () => { - expect(exportObject.passwordProtected).toBe(true); - }); - - it("specifies salt", () => { - expect(exportObject.salt).toEqual("salt"); - }); - - it("specifies kdfIterations", () => { - expect(exportObject.kdfIterations).toEqual(100000); - }); - - it("has kdfType", () => { - expect(exportObject.kdfType).toEqual(KdfType.PBKDF2_SHA256); - }); - - it("has a mac property", async () => { - cryptoService.encrypt(Arg.any(), Arg.any()).resolves(mac); - exportString = await exportService.getPasswordProtectedExport(password); - exportObject = JSON.parse(exportString); - - expect(exportObject.encKeyValidation_DO_NOT_EDIT).toEqual(mac.encryptedString); - }); - - it("has data property", async () => { - cryptoService.encrypt(Arg.any(), Arg.any()).resolves(data); - exportString = await exportService.getPasswordProtectedExport(password); - exportObject = JSON.parse(exportString); - - expect(exportObject.data).toEqual(data.encryptedString); - }); - - it("encrypts the data property", async () => { - const unencrypted = await exportService.getExport(); - expect(exportObject.data).not.toEqual(unencrypted); - }); - }); - }); -}); diff --git a/jslib/common/spec/services/import.service.spec.ts b/jslib/common/spec/services/import.service.spec.ts deleted file mode 100644 index 9625667a..00000000 --- a/jslib/common/spec/services/import.service.spec.ts +++ /dev/null @@ -1,72 +0,0 @@ -import Substitute, { SubstituteOf } from "@fluffy-spoon/substitute"; - -import { ApiService } from "@/jslib/common/src/abstractions/api.service"; -import { CipherService } from "@/jslib/common/src/abstractions/cipher.service"; -import { CollectionService } from "@/jslib/common/src/abstractions/collection.service"; -import { CryptoService } from "@/jslib/common/src/abstractions/crypto.service"; -import { FolderService } from "@/jslib/common/src/abstractions/folder.service"; -import { I18nService } from "@/jslib/common/src/abstractions/i18n.service"; -import { PlatformUtilsService } from "@/jslib/common/src/abstractions/platformUtils.service"; -import { BitwardenPasswordProtectedImporter } from "@/jslib/common/src/importers/bitwardenPasswordProtectedImporter"; -import { Importer } from "@/jslib/common/src/importers/importer"; -import { Utils } from "@/jslib/common/src/misc/utils"; -import { ImportService } from "@/jslib/common/src/services/import.service"; - -describe("ImportService", () => { - let importService: ImportService; - let cipherService: SubstituteOf; - let folderService: SubstituteOf; - let apiService: SubstituteOf; - let i18nService: SubstituteOf; - let collectionService: SubstituteOf; - let platformUtilsService: SubstituteOf; - let cryptoService: SubstituteOf; - - beforeEach(() => { - cipherService = Substitute.for(); - folderService = Substitute.for(); - apiService = Substitute.for(); - i18nService = Substitute.for(); - collectionService = Substitute.for(); - platformUtilsService = Substitute.for(); - cryptoService = Substitute.for(); - - importService = new ImportService( - cipherService, - folderService, - apiService, - i18nService, - collectionService, - platformUtilsService, - cryptoService - ); - }); - - describe("getImporterInstance", () => { - describe("Get bitPasswordProtected importer", () => { - let importer: Importer; - const organizationId = Utils.newGuid(); - const password = Utils.newGuid(); - - beforeEach(() => { - importer = importService.getImporter( - "bitwardenpasswordprotected", - organizationId, - password - ); - }); - - it("returns an instance of BitwardenPasswordProtectedImporter", () => { - expect(importer).toBeInstanceOf(BitwardenPasswordProtectedImporter); - }); - - it("has the appropriate organization Id", () => { - expect(importer.organizationId).toEqual(organizationId); - }); - - it("has the appropriate password", () => { - expect(Object.entries(importer)).toEqual(expect.arrayContaining([["password", password]])); - }); - }); - }); -}); diff --git a/jslib/common/spec/services/stateMigration.service.ts b/jslib/common/spec/services/stateMigration.service.ts deleted file mode 100644 index 32b65bd7..00000000 --- a/jslib/common/spec/services/stateMigration.service.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute"; - -import { StorageService } from "@/jslib/common/src/abstractions/storage.service"; -import { StateVersion } from "@/jslib/common/src/enums/stateVersion"; -import { StateFactory } from "@/jslib/common/src/factories/stateFactory"; -import { Account } from "@/jslib/common/src/models/domain/account"; -import { GlobalState } from "@/jslib/common/src/models/domain/globalState"; -import { StateMigrationService } from "@/jslib/common/src/services/stateMigration.service"; - -const userId = "USER_ID"; - -describe("State Migration Service", () => { - let storageService: SubstituteOf; - let secureStorageService: SubstituteOf; - let stateFactory: SubstituteOf; - - let stateMigrationService: StateMigrationService; - - beforeEach(() => { - storageService = Substitute.for(); - secureStorageService = Substitute.for(); - stateFactory = Substitute.for(); - - stateMigrationService = new StateMigrationService( - storageService, - secureStorageService, - stateFactory - ); - }); - - describe("StateVersion 3 to 4 migration", async () => { - beforeEach(() => { - const globalVersion3: Partial = { - stateVersion: StateVersion.Three, - }; - - storageService.get("global", Arg.any()).resolves(globalVersion3); - storageService.get("authenticatedAccounts", Arg.any()).resolves([userId]); - }); - - it("clears everBeenUnlocked", async () => { - const accountVersion3: Account = { - profile: { - apiKeyClientId: null, - convertAccountToKeyConnector: null, - email: "EMAIL", - emailVerified: true, - everBeenUnlocked: true, - hasPremiumPersonally: false, - kdfIterations: 100000, - kdfType: 0, - keyHash: "KEY_HASH", - lastSync: "LAST_SYNC", - userId: userId, - usesKeyConnector: false, - forcePasswordReset: false, - }, - }; - - const expectedAccountVersion4: Account = { - profile: { - ...accountVersion3.profile, - }, - }; - delete expectedAccountVersion4.profile.everBeenUnlocked; - - storageService.get(userId, Arg.any()).resolves(accountVersion3); - - await stateMigrationService.migrate(); - - storageService.received(1).save(userId, expectedAccountVersion4, Arg.any()); - }); - - it("updates StateVersion number", async () => { - await stateMigrationService.migrate(); - - storageService.received(1).save( - "global", - Arg.is((globals: GlobalState) => globals.stateVersion === StateVersion.Four), - Arg.any() - ); - }); - }); -}); diff --git a/jslib/common/spec/test.ts b/jslib/common/spec/test.ts deleted file mode 100644 index 9d9906aa..00000000 --- a/jslib/common/spec/test.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { webcrypto } from "crypto"; - -Object.defineProperty(window, "crypto", { - value: webcrypto, -}); diff --git a/jslib/common/spec/utils.ts b/jslib/common/spec/utils.ts deleted file mode 100644 index c4a5fb6f..00000000 --- a/jslib/common/spec/utils.ts +++ /dev/null @@ -1,37 +0,0 @@ -import Substitute, { Arg } from "@fluffy-spoon/substitute"; - -import { EncString } from "@/jslib/common/src/models/domain/encString"; - -function newGuid() { - return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => { - const r = (Math.random() * 16) | 0; - const v = c === "x" ? r : (r & 0x3) | 0x8; - return v.toString(16); - }); -} - -export function GetUniqueString(prefix = "") { - return prefix + "_" + newGuid(); -} - -export function BuildTestObject( - def: Partial> | T, - constructor?: new () => T -): T { - return Object.assign(constructor === null ? {} : new constructor(), def) as T; -} - -export function mockEnc(s: string): EncString { - const mock = Substitute.for(); - mock.decrypt(Arg.any(), Arg.any()).resolves(s); - - return mock; -} - -export function makeStaticByteArray(length: number) { - const arr = new Uint8Array(length); - for (let i = 0; i < length; i++) { - arr[i] = i; - } - return arr; -} diff --git a/jslib/common/spec/web/services/webCryptoFunction.service.spec.ts b/jslib/common/spec/web/services/webCryptoFunction.service.spec.ts deleted file mode 100644 index f4940397..00000000 --- a/jslib/common/spec/web/services/webCryptoFunction.service.spec.ts +++ /dev/null @@ -1,558 +0,0 @@ -import Substitute from "@fluffy-spoon/substitute"; - -import { PlatformUtilsService } from "@/jslib/common/src/abstractions/platformUtils.service"; -import { Utils } from "@/jslib/common/src/misc/utils"; -import { SymmetricCryptoKey } from "@/jslib/common/src/models/domain/symmetricCryptoKey"; -import { WebCryptoFunctionService } from "@/jslib/common/src/services/webCryptoFunction.service"; - -const RsaPublicKey = - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl0Vawl/toXzkEvB82FEtqHP" + - "4xlU2ab/v0crqIfXfIoWF/XXdHGIdrZeilnRXPPJT1B9dTsasttEZNnua/0Rek/cjNDHtzT52irfoZYS7X6HNIfOi54Q+egP" + - "RQ1H7iNHVZz3K8Db9GCSKPeC8MbW6gVCzb15esCe1gGzg6wkMuWYDFYPoh/oBqcIqrGah7firqB1nDedzEjw32heP2DAffVN" + - "084iTDjiWrJNUxBJ2pDD5Z9dT3MzQ2s09ew1yMWK2z37rT3YerC7OgEDmo3WYo3xL3qYJznu3EO2nmrYjiRa40wKSjxsTlUc" + - "xDF+F0uMW8oR9EMUHgepdepfAtLsSAQIDAQAB"; -const RsaPrivateKey = - "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXRVrCX+2hfOQS8Hz" + - "YUS2oc/jGVTZpv+/Ryuoh9d8ihYX9dd0cYh2tl6KWdFc88lPUH11Oxqy20Rk2e5r/RF6T9yM0Me3NPnaKt+hlhLtfoc0h86L" + - "nhD56A9FDUfuI0dVnPcrwNv0YJIo94LwxtbqBULNvXl6wJ7WAbODrCQy5ZgMVg+iH+gGpwiqsZqHt+KuoHWcN53MSPDfaF4/" + - "YMB99U3TziJMOOJask1TEEnakMPln11PczNDazT17DXIxYrbPfutPdh6sLs6AQOajdZijfEvepgnOe7cQ7aeatiOJFrjTApK" + - "PGxOVRzEMX4XS4xbyhH0QxQeB6l16l8C0uxIBAgMBAAECggEASaWfeVDA3cVzOPFSpvJm20OTE+R6uGOU+7vh36TX/POq92q" + - "Buwbd0h0oMD32FxsXywd2IxtBDUSiFM9699qufTVuM0Q3tZw6lHDTOVG08+tPdr8qSbMtw7PGFxN79fHLBxejjO4IrM9lapj" + - "WpxEF+11x7r+wM+0xRZQ8sNFYG46aPfIaty4BGbL0I2DQ2y8I57iBCAy69eht59NLMm27fRWGJIWCuBIjlpfzET1j2HLXUIh" + - "5bTBNzqaN039WH49HczGE3mQKVEJZc/efk3HaVd0a1Sjzyn0QY+N1jtZN3jTRbuDWA1AknkX1LX/0tUhuS3/7C3ejHxjw4Dk" + - "1ZLo5/QKBgQDIWvqFn0+IKRSu6Ua2hDsufIHHUNLelbfLUMmFthxabcUn4zlvIscJO00Tq/ezopSRRvbGiqnxjv/mYxucvOU" + - "BeZtlus0Q9RTACBtw9TGoNTmQbEunJ2FOSlqbQxkBBAjgGEppRPt30iGj/VjAhCATq2MYOa/X4dVR51BqQAFIEwKBgQDBSIf" + - "TFKC/hDk6FKZlgwvupWYJyU9RkyfstPErZFmzoKhPkQ3YORo2oeAYmVUbS9I2iIYpYpYQJHX8jMuCbCz4ONxTCuSIXYQYUcU" + - "q4PglCKp31xBAE6TN8SvhfME9/MvuDssnQinAHuF0GDAhF646T3LLS1not6Vszv7brwSoGwKBgQC88v/8cGfi80ssQZeMnVv" + - "q1UTXIeQcQnoY5lGHJl3K8mbS3TnXE6c9j417Fdz+rj8KWzBzwWXQB5pSPflWcdZO886Xu/mVGmy9RWgLuVFhXwCwsVEPjNX" + - "5ramRb0/vY0yzenUCninBsIxFSbIfrPtLUYCc4hpxr+sr2Mg/y6jpvQKBgBezMRRs3xkcuXepuI2R+BCXL1/b02IJTUf1F+1" + - "eLLGd7YV0H+J3fgNc7gGWK51hOrF9JBZHBGeOUPlaukmPwiPdtQZpu4QNE3l37VlIpKTF30E6mb+BqR+nht3rUjarnMXgAoE" + - "Z18y6/KIjpSMpqC92Nnk/EBM9EYe6Cf4eA9ApAoGAeqEUg46UTlJySkBKURGpIs3v1kkf5I0X8DnOhwb+HPxNaiEdmO7ckm8" + - "+tPVgppLcG0+tMdLjigFQiDUQk2y3WjyxP5ZvXu7U96jaJRI8PFMoE06WeVYcdIzrID2HvqH+w0UQJFrLJ/0Mn4stFAEzXKZ" + - "BokBGnjFnTnKcs7nv/O8="; - -const Sha1Mac = "4d4c223f95dc577b665ec4ccbcb680b80a397038"; -const Sha256Mac = "6be3caa84922e12aaaaa2f16c40d44433bb081ef323db584eb616333ab4e874f"; -const Sha512Mac = - "21910e341fa12106ca35758a2285374509326c9fbe0bd64e7b99c898f841dc948c58ce66d3504d8883c" + - "5ea7817a0b7c5d4d9b00364ccd214669131fc17fe4aca"; - -describe("WebCrypto Function Service", () => { - describe("pbkdf2", () => { - const regular256Key = "pj9prw/OHPleXI6bRdmlaD+saJS4awrMiQsQiDjeu2I="; - const utf8256Key = "yqvoFXgMRmHR3QPYr5pyR4uVuoHkltv9aHUP63p8n7I="; - const unicode256Key = "ZdeOata6xoRpB4DLp8zHhXz5kLmkWtX5pd+TdRH8w8w="; - - const regular512Key = - "liTi/Ke8LPU1Qv+Vl7NGEVt/XMbsBVJ2kQxtVG/Z1/JFHFKQW3ZkI81qVlwTiCpb+cFXzs+57" + - "eyhhx5wfKo5Cg=="; - const utf8512Key = - "df0KdvIBeCzD/kyXptwQohaqUa4e7IyFUyhFQjXCANu5T+scq55hCcE4dG4T/MhAk2exw8j7ixRN" + - "zXANiVZpnw=="; - const unicode512Key = - "FE+AnUJaxv8jh+zUDtZz4mjjcYk0/PZDZm+SLJe3XtxtnpdqqpblX6JjuMZt/dYYNMOrb2+mD" + - "L3FiQDTROh1lg=="; - - testPbkdf2("sha256", regular256Key, utf8256Key, unicode256Key); - testPbkdf2("sha512", regular512Key, utf8512Key, unicode512Key); - }); - - describe("hkdf", () => { - const regular256Key = "qBUmEYtwTwwGPuw/z6bs/qYXXYNUlocFlyAuuANI8Pw="; - const utf8256Key = "6DfJwW1R3txgiZKkIFTvVAb7qVlG7lKcmJGJoxR2GBU="; - const unicode256Key = "gejGI82xthA+nKtKmIh82kjw+ttHr+ODsUoGdu5sf0A="; - - const regular512Key = "xe5cIG6ZfwGmb1FvsOedM0XKOm21myZkjL/eDeKIqqM="; - const utf8512Key = "XQMVBnxVEhlvjSFDQc77j5GDE9aorvbS0vKnjhRg0LY="; - const unicode512Key = "148GImrTbrjaGAe/iWEpclINM8Ehhko+9lB14+52lqc="; - - testHkdf("sha256", regular256Key, utf8256Key, unicode256Key); - testHkdf("sha512", regular512Key, utf8512Key, unicode512Key); - }); - - describe("hkdfExpand", () => { - const prk16Byte = "criAmKtfzxanbgea5/kelQ=="; - const prk32Byte = "F5h4KdYQnIVH4rKH0P9CZb1GrR4n16/sJrS0PsQEn0Y="; - const prk64Byte = - "ssBK0mRG17VHdtsgt8yo4v25CRNpauH+0r2fwY/E9rLyaFBAOMbIeTry+" + - "gUJ28p8y+hFh3EI9pcrEWaNvFYonQ=="; - - testHkdfExpand("sha256", prk32Byte, 32, "BnIqJlfnHm0e/2iB/15cbHyR19ARPIcWRp4oNS22CD8="); - testHkdfExpand( - "sha256", - prk32Byte, - 64, - "BnIqJlfnHm0e/2iB/15cbHyR19ARPIcWRp4oNS22CD9BV+" + - "/queOZenPNkDhmlVyL2WZ3OSU5+7ISNF5NhNfvZA==" - ); - testHkdfExpand("sha512", prk64Byte, 32, "uLWbMWodSBms5uGJ5WTRTesyW+MD7nlpCZvagvIRXlk="); - testHkdfExpand( - "sha512", - prk64Byte, - 64, - "uLWbMWodSBms5uGJ5WTRTesyW+MD7nlpCZvagvIRXlkY5Pv0sB+" + - "MqvaopmkC6sD/j89zDwTV9Ib2fpucUydO8w==" - ); - - it("should fail with prk too small", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const f = cryptoFunctionService.hkdfExpand( - Utils.fromB64ToArray(prk16Byte), - "info", - 32, - "sha256" - ); - await expect(f).rejects.toEqual(new Error("prk is too small.")); - }); - - it("should fail with outputByteSize is too large", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const f = cryptoFunctionService.hkdfExpand( - Utils.fromB64ToArray(prk32Byte), - "info", - 8161, - "sha256" - ); - await expect(f).rejects.toEqual(new Error("outputByteSize is too large.")); - }); - }); - - describe("hash", () => { - const regular1Hash = "2a241604fb921fad12bf877282457268e1dccb70"; - const utf81Hash = "85672798dc5831e96d6c48655d3d39365a9c88b6"; - const unicode1Hash = "39c975935054a3efc805a9709b60763a823a6ad4"; - - const regular256Hash = "2b8e96031d352a8655d733d7a930b5ffbea69dc25cf65c7bca7dd946278908b2"; - const utf8256Hash = "25fe8440f5b01ed113b0a0e38e721b126d2f3f77a67518c4a04fcde4e33eeb9d"; - const unicode256Hash = "adc1c0c2afd6e92cefdf703f9b6eb2c38e0d6d1a040c83f8505c561fea58852e"; - - const regular512Hash = - "c15cf11d43bde333647e3f559ec4193bb2edeaa0e8b902772f514cdf3f785a3f49a6e02a4b87b3" + - "b47523271ad45b7e0aebb5cdcc1bc54815d256eb5dcb80da9d"; - const utf8512Hash = - "035c31a877a291af09ed2d3a1a293e69c3e079ea2cecc00211f35e6bce10474ca3ad6e30b59e26118" + - "37463f20969c5bc95282965a051a88f8cdf2e166549fcdd"; - const unicode512Hash = - "2b16a5561af8ad6fe414cc103fc8036492e1fc6d9aabe1b655497054f760fe0e34c5d100ac773d" + - "9f3030438284f22dbfa20cb2e9b019f2c98dfe38ce1ef41bae"; - - const regularMd5 = "5eceffa53a5fd58c44134211e2c5f522"; - const utf8Md5 = "3abc9433c09551b939c80aa0aa3174e1"; - const unicodeMd5 = "85ae134072c8d81257933f7045ba17ca"; - - testHash("sha1", regular1Hash, utf81Hash, unicode1Hash); - testHash("sha256", regular256Hash, utf8256Hash, unicode256Hash); - testHash("sha512", regular512Hash, utf8512Hash, unicode512Hash); - testHash("md5", regularMd5, utf8Md5, unicodeMd5); - }); - - describe("hmac", () => { - testHmac("sha1", Sha1Mac); - testHmac("sha256", Sha256Mac); - testHmac("sha512", Sha512Mac); - }); - - describe("compare", () => { - it("should successfully compare two of the same values", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const a = new Uint8Array(2); - a[0] = 1; - a[1] = 2; - const equal = await cryptoFunctionService.compare(a.buffer, a.buffer); - expect(equal).toBe(true); - }); - - it("should successfully compare two different values of the same length", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const a = new Uint8Array(2); - a[0] = 1; - a[1] = 2; - const b = new Uint8Array(2); - b[0] = 3; - b[1] = 4; - const equal = await cryptoFunctionService.compare(a.buffer, b.buffer); - expect(equal).toBe(false); - }); - - it("should successfully compare two different values of different lengths", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const a = new Uint8Array(2); - a[0] = 1; - a[1] = 2; - const b = new Uint8Array(2); - b[0] = 3; - const equal = await cryptoFunctionService.compare(a.buffer, b.buffer); - expect(equal).toBe(false); - }); - }); - - describe("hmacFast", () => { - testHmacFast("sha1", Sha1Mac); - testHmacFast("sha256", Sha256Mac); - testHmacFast("sha512", Sha512Mac); - }); - - describe("compareFast", () => { - it("should successfully compare two of the same values", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const a = new Uint8Array(2); - a[0] = 1; - a[1] = 2; - const aByteString = Utils.fromBufferToByteString(a.buffer); - const equal = await cryptoFunctionService.compareFast(aByteString, aByteString); - expect(equal).toBe(true); - }); - - it("should successfully compare two different values of the same length", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const a = new Uint8Array(2); - a[0] = 1; - a[1] = 2; - const aByteString = Utils.fromBufferToByteString(a.buffer); - const b = new Uint8Array(2); - b[0] = 3; - b[1] = 4; - const bByteString = Utils.fromBufferToByteString(b.buffer); - const equal = await cryptoFunctionService.compareFast(aByteString, bByteString); - expect(equal).toBe(false); - }); - - it("should successfully compare two different values of different lengths", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const a = new Uint8Array(2); - a[0] = 1; - a[1] = 2; - const aByteString = Utils.fromBufferToByteString(a.buffer); - const b = new Uint8Array(2); - b[0] = 3; - const bByteString = Utils.fromBufferToByteString(b.buffer); - const equal = await cryptoFunctionService.compareFast(aByteString, bByteString); - expect(equal).toBe(false); - }); - }); - - describe("aesEncrypt", () => { - it("should successfully encrypt data", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const iv = makeStaticByteArray(16); - const key = makeStaticByteArray(32); - const data = Utils.fromUtf8ToArray("EncryptMe!"); - const encValue = await cryptoFunctionService.aesEncrypt(data.buffer, iv.buffer, key.buffer); - expect(Utils.fromBufferToB64(encValue)).toBe("ByUF8vhyX4ddU9gcooznwA=="); - }); - - it("should successfully encrypt and then decrypt data fast", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const iv = makeStaticByteArray(16); - const key = makeStaticByteArray(32); - const value = "EncryptMe!"; - const data = Utils.fromUtf8ToArray(value); - const encValue = await cryptoFunctionService.aesEncrypt(data.buffer, iv.buffer, key.buffer); - const encData = Utils.fromBufferToB64(encValue); - const b64Iv = Utils.fromBufferToB64(iv.buffer); - const symKey = new SymmetricCryptoKey(key.buffer); - const params = cryptoFunctionService.aesDecryptFastParameters(encData, b64Iv, null, symKey); - const decValue = await cryptoFunctionService.aesDecryptFast(params); - expect(decValue).toBe(value); - }); - - it("should successfully encrypt and then decrypt data", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const iv = makeStaticByteArray(16); - const key = makeStaticByteArray(32); - const value = "EncryptMe!"; - const data = Utils.fromUtf8ToArray(value); - const encValue = await cryptoFunctionService.aesEncrypt(data.buffer, iv.buffer, key.buffer); - const decValue = await cryptoFunctionService.aesDecrypt(encValue, iv.buffer, key.buffer); - expect(Utils.fromBufferToUtf8(decValue)).toBe(value); - }); - }); - - describe("aesDecryptFast", () => { - it("should successfully decrypt data", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const iv = Utils.fromBufferToB64(makeStaticByteArray(16).buffer); - const symKey = new SymmetricCryptoKey(makeStaticByteArray(32).buffer); - const data = "ByUF8vhyX4ddU9gcooznwA=="; - const params = cryptoFunctionService.aesDecryptFastParameters(data, iv, null, symKey); - const decValue = await cryptoFunctionService.aesDecryptFast(params); - expect(decValue).toBe("EncryptMe!"); - }); - }); - - describe("aesDecrypt", () => { - it("should successfully decrypt data", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const iv = makeStaticByteArray(16); - const key = makeStaticByteArray(32); - const data = Utils.fromB64ToArray("ByUF8vhyX4ddU9gcooznwA=="); - const decValue = await cryptoFunctionService.aesDecrypt(data.buffer, iv.buffer, key.buffer); - expect(Utils.fromBufferToUtf8(decValue)).toBe("EncryptMe!"); - }); - }); - - describe("rsaEncrypt", () => { - it("should successfully encrypt and then decrypt data", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const pubKey = Utils.fromB64ToArray(RsaPublicKey); - const privKey = Utils.fromB64ToArray(RsaPrivateKey); - const value = "EncryptMe!"; - const data = Utils.fromUtf8ToArray(value); - const encValue = await cryptoFunctionService.rsaEncrypt(data.buffer, pubKey.buffer, "sha1"); - const decValue = await cryptoFunctionService.rsaDecrypt(encValue, privKey.buffer, "sha1"); - expect(Utils.fromBufferToUtf8(decValue)).toBe(value); - }); - }); - - describe("rsaDecrypt", () => { - it("should successfully decrypt data", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const privKey = Utils.fromB64ToArray(RsaPrivateKey); - const data = Utils.fromB64ToArray( - "A1/p8BQzN9UrbdYxUY2Va5+kPLyfZXF9JsZrjeEXcaclsnHurdxVAJcnbEqYMP3UXV" + - "4YAS/mpf+Rxe6/X0WS1boQdA0MAHSgx95hIlAraZYpiMLLiJRKeo2u8YivCdTM9V5vuAEJwf9Tof/qFsFci3sApdbATkorCT" + - "zFOIEPF2S1zgperEP23M01mr4dWVdYN18B32YF67xdJHMbFhp5dkQwv9CmscoWq7OE5HIfOb+JAh7BEZb+CmKhM3yWJvoR/D" + - "/5jcercUtK2o+XrzNrL4UQ7yLZcFz6Bfwb/j6ICYvqd/YJwXNE6dwlL57OfwJyCdw2rRYf0/qI00t9u8Iitw==" - ); - const decValue = await cryptoFunctionService.rsaDecrypt(data.buffer, privKey.buffer, "sha1"); - expect(Utils.fromBufferToUtf8(decValue)).toBe("EncryptMe!"); - }); - }); - - describe("rsaExtractPublicKey", () => { - it("should successfully extract key", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const privKey = Utils.fromB64ToArray(RsaPrivateKey); - const publicKey = await cryptoFunctionService.rsaExtractPublicKey(privKey.buffer); - expect(Utils.fromBufferToB64(publicKey)).toBe(RsaPublicKey); - }); - }); - - describe("rsaGenerateKeyPair", () => { - testRsaGenerateKeyPair(1024); - testRsaGenerateKeyPair(2048); - - // Generating 4096 bit keys can be slow. Commenting it out to save CI. - // testRsaGenerateKeyPair(4096); - }); - - describe("randomBytes", () => { - it("should make a value of the correct length", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const randomData = await cryptoFunctionService.randomBytes(16); - expect(randomData.byteLength).toBe(16); - }); - - it("should not make the same value twice", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const randomData = await cryptoFunctionService.randomBytes(16); - const randomData2 = await cryptoFunctionService.randomBytes(16); - expect( - randomData.byteLength === randomData2.byteLength && randomData !== randomData2 - ).toBeTruthy(); - }); - }); -}); - -function testPbkdf2( - algorithm: "sha256" | "sha512", - regularKey: string, - utf8Key: string, - unicodeKey: string -) { - const regularEmail = "user@example.com"; - const utf8Email = "üser@example.com"; - - const regularPassword = "password"; - const utf8Password = "pǻssword"; - const unicodePassword = "😀password🙏"; - - it("should create valid " + algorithm + " key from regular input", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const key = await cryptoFunctionService.pbkdf2(regularPassword, regularEmail, algorithm, 5000); - expect(Utils.fromBufferToB64(key)).toBe(regularKey); - }); - - it("should create valid " + algorithm + " key from utf8 input", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const key = await cryptoFunctionService.pbkdf2(utf8Password, utf8Email, algorithm, 5000); - expect(Utils.fromBufferToB64(key)).toBe(utf8Key); - }); - - it("should create valid " + algorithm + " key from unicode input", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const key = await cryptoFunctionService.pbkdf2(unicodePassword, regularEmail, algorithm, 5000); - expect(Utils.fromBufferToB64(key)).toBe(unicodeKey); - }); - - it("should create valid " + algorithm + " key from array buffer input", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const key = await cryptoFunctionService.pbkdf2( - Utils.fromUtf8ToArray(regularPassword).buffer, - Utils.fromUtf8ToArray(regularEmail).buffer, - algorithm, - 5000 - ); - expect(Utils.fromBufferToB64(key)).toBe(regularKey); - }); -} - -function testHkdf( - algorithm: "sha256" | "sha512", - regularKey: string, - utf8Key: string, - unicodeKey: string -) { - const ikm = Utils.fromB64ToArray("criAmKtfzxanbgea5/kelQ=="); - - const regularSalt = "salt"; - const utf8Salt = "üser_salt"; - const unicodeSalt = "😀salt🙏"; - - const regularInfo = "info"; - const utf8Info = "üser_info"; - const unicodeInfo = "😀info🙏"; - - it("should create valid " + algorithm + " key from regular input", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const key = await cryptoFunctionService.hkdf(ikm, regularSalt, regularInfo, 32, algorithm); - expect(Utils.fromBufferToB64(key)).toBe(regularKey); - }); - - it("should create valid " + algorithm + " key from utf8 input", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const key = await cryptoFunctionService.hkdf(ikm, utf8Salt, utf8Info, 32, algorithm); - expect(Utils.fromBufferToB64(key)).toBe(utf8Key); - }); - - it("should create valid " + algorithm + " key from unicode input", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const key = await cryptoFunctionService.hkdf(ikm, unicodeSalt, unicodeInfo, 32, algorithm); - expect(Utils.fromBufferToB64(key)).toBe(unicodeKey); - }); - - it("should create valid " + algorithm + " key from array buffer input", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const key = await cryptoFunctionService.hkdf( - ikm, - Utils.fromUtf8ToArray(regularSalt).buffer, - Utils.fromUtf8ToArray(regularInfo).buffer, - 32, - algorithm - ); - expect(Utils.fromBufferToB64(key)).toBe(regularKey); - }); -} - -function testHkdfExpand( - algorithm: "sha256" | "sha512", - b64prk: string, - outputByteSize: number, - b64ExpectedOkm: string -) { - const info = "info"; - - it("should create valid " + algorithm + " " + outputByteSize + " byte okm", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const okm = await cryptoFunctionService.hkdfExpand( - Utils.fromB64ToArray(b64prk), - info, - outputByteSize, - algorithm - ); - expect(Utils.fromBufferToB64(okm)).toBe(b64ExpectedOkm); - }); -} - -function testHash( - algorithm: "sha1" | "sha256" | "sha512" | "md5", - regularHash: string, - utf8Hash: string, - unicodeHash: string -) { - const regularValue = "HashMe!!"; - const utf8Value = "HǻshMe!!"; - const unicodeValue = "😀HashMe!!!🙏"; - - it("should create valid " + algorithm + " hash from regular input", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const hash = await cryptoFunctionService.hash(regularValue, algorithm); - expect(Utils.fromBufferToHex(hash)).toBe(regularHash); - }); - - it("should create valid " + algorithm + " hash from utf8 input", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const hash = await cryptoFunctionService.hash(utf8Value, algorithm); - expect(Utils.fromBufferToHex(hash)).toBe(utf8Hash); - }); - - it("should create valid " + algorithm + " hash from unicode input", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const hash = await cryptoFunctionService.hash(unicodeValue, algorithm); - expect(Utils.fromBufferToHex(hash)).toBe(unicodeHash); - }); - - it("should create valid " + algorithm + " hash from array buffer input", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const hash = await cryptoFunctionService.hash( - Utils.fromUtf8ToArray(regularValue).buffer, - algorithm - ); - expect(Utils.fromBufferToHex(hash)).toBe(regularHash); - }); -} - -function testHmac(algorithm: "sha1" | "sha256" | "sha512", mac: string) { - it("should create valid " + algorithm + " hmac", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const computedMac = await cryptoFunctionService.hmac( - Utils.fromUtf8ToArray("SignMe!!").buffer, - Utils.fromUtf8ToArray("secretkey").buffer, - algorithm - ); - expect(Utils.fromBufferToHex(computedMac)).toBe(mac); - }); -} - -function testHmacFast(algorithm: "sha1" | "sha256" | "sha512", mac: string) { - it("should create valid " + algorithm + " hmac", async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const keyByteString = Utils.fromBufferToByteString(Utils.fromUtf8ToArray("secretkey").buffer); - const dataByteString = Utils.fromBufferToByteString(Utils.fromUtf8ToArray("SignMe!!").buffer); - const computedMac = await cryptoFunctionService.hmacFast( - dataByteString, - keyByteString, - algorithm - ); - expect(Utils.fromBufferToHex(Utils.fromByteStringToArray(computedMac).buffer)).toBe(mac); - }); -} - -function testRsaGenerateKeyPair(length: 1024 | 2048 | 4096) { - it( - "should successfully generate a " + length + " bit key pair", - async () => { - const cryptoFunctionService = getWebCryptoFunctionService(); - const keyPair = await cryptoFunctionService.rsaGenerateKeyPair(length); - expect(keyPair[0] == null || keyPair[1] == null).toBe(false); - const publicKey = await cryptoFunctionService.rsaExtractPublicKey(keyPair[1]); - expect(Utils.fromBufferToB64(keyPair[0])).toBe(Utils.fromBufferToB64(publicKey)); - }, - 30000 - ); -} - -function getWebCryptoFunctionService() { - const platformUtilsMock = Substitute.for(); - platformUtilsMock.isEdge().mimicks(() => navigator.userAgent.indexOf(" Edg/") !== -1); - - return new WebCryptoFunctionService(window); -} - -function makeStaticByteArray(length: number) { - const arr = new Uint8Array(length); - for (let i = 0; i < length; i++) { - arr[i] = i; - } - return arr; -} diff --git a/jslib/electron/jest.config.js b/jslib/electron/jest.config.js deleted file mode 100644 index 8d59aeaf..00000000 --- a/jslib/electron/jest.config.js +++ /dev/null @@ -1,16 +0,0 @@ -const { pathsToModuleNameMapper } = require("ts-jest/utils"); - -const { compilerOptions } = require("./tsconfig"); - -module.exports = { - preset: "ts-jest", - testEnvironment: "jsdom", - testMatch: ["**/+(*.)+(spec).+(ts)"], - setupFilesAfterEnv: ["/spec/test.ts"], - collectCoverage: true, - coverageReporters: ["html", "lcov"], - coverageDirectory: "coverage", - moduleNameMapper: pathsToModuleNameMapper(compilerOptions?.paths || {}, { - prefix: "/", - }), -}; diff --git a/jslib/electron/spec/services/electronLog.service.spec.ts b/jslib/electron/spec/services/electronLog.service.spec.ts deleted file mode 100644 index 925c7d82..00000000 --- a/jslib/electron/spec/services/electronLog.service.spec.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { ElectronLogService } from "@/jslib/electron/src/services/electronLog.service"; - -describe("ElectronLogService", () => { - it("sets dev based on electron method", () => { - process.env.ELECTRON_IS_DEV = "1"; - const logService = new ElectronLogService(); - expect(logService).toEqual(expect.objectContaining({ isDev: true }) as any); - }); -}); diff --git a/jslib/electron/spec/test.ts b/jslib/electron/spec/test.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/jslib/electron/spec/utils.spec.ts b/jslib/electron/spec/utils.spec.ts deleted file mode 100644 index f24d961e..00000000 --- a/jslib/electron/spec/utils.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { cleanUserAgent } from "@/jslib/electron/src/utils"; - -const expectedUserAgent = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${process.versions.chrome} Safari/537.36`; - -describe("cleanUserAgent", () => { - it("cleans mac agent", () => { - const initialMacAgent = `Mozilla/5.0 (Macintosh; Intel Mac OS X 11_6_0) AppleWebKit/537.36 (KHTML, like Gecko) Bitwarden/${process.version} Chrome/${process.versions.chrome} Electron/${process.versions.electron} Safari/537.36`; - expect(cleanUserAgent(initialMacAgent)).toEqual(expectedUserAgent); - }); - - it("cleans windows agent", () => { - const initialWindowsAgent = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Bitwarden/${process.version} Chrome/${process.versions.chrome} Electron/${process.versions.electron} Safari/537.36`; - expect(cleanUserAgent(initialWindowsAgent)).toEqual(expectedUserAgent); - }); - - it("cleans linux agent", () => { - const initialWindowsAgent = `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Bitwarden/${process.version} Chrome/${process.versions.chrome} Electron/${process.versions.electron} Safari/537.36`; - expect(cleanUserAgent(initialWindowsAgent)).toEqual(expectedUserAgent); - }); - - it("does not change version numbers", () => { - const expected = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36`; - const initialAgent = `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Bitwarden/1.28.3 Chrome/87.0.4280.141 Electron/11.4.5 Safari/537.36`; - - expect(cleanUserAgent(initialAgent)).toEqual(expected); - }); -}); diff --git a/jslib/jest.config.js b/jslib/jest.config.js deleted file mode 100644 index fabe9db7..00000000 --- a/jslib/jest.config.js +++ /dev/null @@ -1,18 +0,0 @@ -const { pathsToModuleNameMapper } = require("ts-jest/utils"); - -const { compilerOptions } = require("./tsconfig"); - -module.exports = { - collectCoverage: true, - coverageReporters: ["html", "lcov"], - coverageDirectory: "coverage", - moduleNameMapper: pathsToModuleNameMapper(compilerOptions?.paths || {}, { - prefix: "/", - }), - projects: [ - "/angular/jest.config.js", - "/common/jest.config.js", - "/electron/jest.config.js", - "/node/jest.config.js", - ], -}; diff --git a/jslib/node/jest.config.js b/jslib/node/jest.config.js deleted file mode 100644 index f1bfb7a9..00000000 --- a/jslib/node/jest.config.js +++ /dev/null @@ -1,15 +0,0 @@ -const { pathsToModuleNameMapper } = require("ts-jest/utils"); - -const { compilerOptions } = require("./tsconfig"); - -module.exports = { - preset: "ts-jest", - testMatch: ["**/+(*.)+(spec).+(ts)"], - setupFilesAfterEnv: ["/spec/test.ts"], - collectCoverage: true, - coverageReporters: ["html", "lcov"], - coverageDirectory: "coverage", - moduleNameMapper: pathsToModuleNameMapper(compilerOptions?.paths || {}, { - prefix: "/", - }), -}; diff --git a/jslib/node/spec/cli/consoleLog.service.spec.ts b/jslib/node/spec/cli/consoleLog.service.spec.ts deleted file mode 100644 index d5970cdf..00000000 --- a/jslib/node/spec/cli/consoleLog.service.spec.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { - interceptConsole, - restoreConsole, -} from "@/jslib/common/spec/services/consoleLog.service.spec"; - -import { ConsoleLogService } from "@/jslib/node/src/cli/services/consoleLog.service"; - -let caughtMessage: any = {}; - -describe("CLI Console log service", () => { - let logService: ConsoleLogService; - beforeEach(() => { - caughtMessage = {}; - interceptConsole(caughtMessage); - logService = new ConsoleLogService(true); - }); - - afterAll(() => { - restoreConsole(); - }); - - it("should redirect all console to error if BW_RESPONSE env is true", () => { - process.env.BW_RESPONSE = "true"; - - logService.debug("this is a debug message"); - expect(caughtMessage).toMatchObject({ - error: { 0: "this is a debug message" }, - }); - }); - - it("should not redirect console to error if BW_RESPONSE != true", () => { - process.env.BW_RESPONSE = "false"; - - logService.debug("debug"); - logService.info("info"); - logService.warning("warning"); - logService.error("error"); - - expect(caughtMessage).toMatchObject({ - log: { 0: "info" }, - warn: { 0: "warning" }, - error: { 0: "error" }, - }); - }); -}); diff --git a/jslib/node/spec/services/nodeCryptoFunction.service.spec.ts b/jslib/node/spec/services/nodeCryptoFunction.service.spec.ts deleted file mode 100644 index b2b7f1b8..00000000 --- a/jslib/node/spec/services/nodeCryptoFunction.service.spec.ts +++ /dev/null @@ -1,518 +0,0 @@ -import { Utils } from "@/jslib/common/src/misc/utils"; -import { SymmetricCryptoKey } from "@/jslib/common/src/models/domain/symmetricCryptoKey"; -import { NodeCryptoFunctionService } from "@/jslib/node/src/services/nodeCryptoFunction.service"; - -const RsaPublicKey = - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl0Vawl/toXzkEvB82FEtqHP" + - "4xlU2ab/v0crqIfXfIoWF/XXdHGIdrZeilnRXPPJT1B9dTsasttEZNnua/0Rek/cjNDHtzT52irfoZYS7X6HNIfOi54Q+egP" + - "RQ1H7iNHVZz3K8Db9GCSKPeC8MbW6gVCzb15esCe1gGzg6wkMuWYDFYPoh/oBqcIqrGah7firqB1nDedzEjw32heP2DAffVN" + - "084iTDjiWrJNUxBJ2pDD5Z9dT3MzQ2s09ew1yMWK2z37rT3YerC7OgEDmo3WYo3xL3qYJznu3EO2nmrYjiRa40wKSjxsTlUc" + - "xDF+F0uMW8oR9EMUHgepdepfAtLsSAQIDAQAB"; -const RsaPrivateKey = - "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXRVrCX+2hfOQS8Hz" + - "YUS2oc/jGVTZpv+/Ryuoh9d8ihYX9dd0cYh2tl6KWdFc88lPUH11Oxqy20Rk2e5r/RF6T9yM0Me3NPnaKt+hlhLtfoc0h86L" + - "nhD56A9FDUfuI0dVnPcrwNv0YJIo94LwxtbqBULNvXl6wJ7WAbODrCQy5ZgMVg+iH+gGpwiqsZqHt+KuoHWcN53MSPDfaF4/" + - "YMB99U3TziJMOOJask1TEEnakMPln11PczNDazT17DXIxYrbPfutPdh6sLs6AQOajdZijfEvepgnOe7cQ7aeatiOJFrjTApK" + - "PGxOVRzEMX4XS4xbyhH0QxQeB6l16l8C0uxIBAgMBAAECggEASaWfeVDA3cVzOPFSpvJm20OTE+R6uGOU+7vh36TX/POq92q" + - "Buwbd0h0oMD32FxsXywd2IxtBDUSiFM9699qufTVuM0Q3tZw6lHDTOVG08+tPdr8qSbMtw7PGFxN79fHLBxejjO4IrM9lapj" + - "WpxEF+11x7r+wM+0xRZQ8sNFYG46aPfIaty4BGbL0I2DQ2y8I57iBCAy69eht59NLMm27fRWGJIWCuBIjlpfzET1j2HLXUIh" + - "5bTBNzqaN039WH49HczGE3mQKVEJZc/efk3HaVd0a1Sjzyn0QY+N1jtZN3jTRbuDWA1AknkX1LX/0tUhuS3/7C3ejHxjw4Dk" + - "1ZLo5/QKBgQDIWvqFn0+IKRSu6Ua2hDsufIHHUNLelbfLUMmFthxabcUn4zlvIscJO00Tq/ezopSRRvbGiqnxjv/mYxucvOU" + - "BeZtlus0Q9RTACBtw9TGoNTmQbEunJ2FOSlqbQxkBBAjgGEppRPt30iGj/VjAhCATq2MYOa/X4dVR51BqQAFIEwKBgQDBSIf" + - "TFKC/hDk6FKZlgwvupWYJyU9RkyfstPErZFmzoKhPkQ3YORo2oeAYmVUbS9I2iIYpYpYQJHX8jMuCbCz4ONxTCuSIXYQYUcU" + - "q4PglCKp31xBAE6TN8SvhfME9/MvuDssnQinAHuF0GDAhF646T3LLS1not6Vszv7brwSoGwKBgQC88v/8cGfi80ssQZeMnVv" + - "q1UTXIeQcQnoY5lGHJl3K8mbS3TnXE6c9j417Fdz+rj8KWzBzwWXQB5pSPflWcdZO886Xu/mVGmy9RWgLuVFhXwCwsVEPjNX" + - "5ramRb0/vY0yzenUCninBsIxFSbIfrPtLUYCc4hpxr+sr2Mg/y6jpvQKBgBezMRRs3xkcuXepuI2R+BCXL1/b02IJTUf1F+1" + - "eLLGd7YV0H+J3fgNc7gGWK51hOrF9JBZHBGeOUPlaukmPwiPdtQZpu4QNE3l37VlIpKTF30E6mb+BqR+nht3rUjarnMXgAoE" + - "Z18y6/KIjpSMpqC92Nnk/EBM9EYe6Cf4eA9ApAoGAeqEUg46UTlJySkBKURGpIs3v1kkf5I0X8DnOhwb+HPxNaiEdmO7ckm8" + - "+tPVgppLcG0+tMdLjigFQiDUQk2y3WjyxP5ZvXu7U96jaJRI8PFMoE06WeVYcdIzrID2HvqH+w0UQJFrLJ/0Mn4stFAEzXKZ" + - "BokBGnjFnTnKcs7nv/O8="; - -const Sha1Mac = "4d4c223f95dc577b665ec4ccbcb680b80a397038"; -const Sha256Mac = "6be3caa84922e12aaaaa2f16c40d44433bb081ef323db584eb616333ab4e874f"; -const Sha512Mac = - "21910e341fa12106ca35758a2285374509326c9fbe0bd64e7b99c898f841dc948c58ce66d3504d8883c" + - "5ea7817a0b7c5d4d9b00364ccd214669131fc17fe4aca"; - -describe("NodeCrypto Function Service", () => { - describe("pbkdf2", () => { - const regular256Key = "pj9prw/OHPleXI6bRdmlaD+saJS4awrMiQsQiDjeu2I="; - const utf8256Key = "yqvoFXgMRmHR3QPYr5pyR4uVuoHkltv9aHUP63p8n7I="; - const unicode256Key = "ZdeOata6xoRpB4DLp8zHhXz5kLmkWtX5pd+TdRH8w8w="; - - const regular512Key = - "liTi/Ke8LPU1Qv+Vl7NGEVt/XMbsBVJ2kQxtVG/Z1/JFHFKQW3ZkI81qVlwTiCpb+cFXzs+57" + - "eyhhx5wfKo5Cg=="; - const utf8512Key = - "df0KdvIBeCzD/kyXptwQohaqUa4e7IyFUyhFQjXCANu5T+scq55hCcE4dG4T/MhAk2exw8j7ixRN" + - "zXANiVZpnw=="; - const unicode512Key = - "FE+AnUJaxv8jh+zUDtZz4mjjcYk0/PZDZm+SLJe3XtxtnpdqqpblX6JjuMZt/dYYNMOrb2+mD" + - "L3FiQDTROh1lg=="; - - testPbkdf2("sha256", regular256Key, utf8256Key, unicode256Key); - testPbkdf2("sha512", regular512Key, utf8512Key, unicode512Key); - }); - - describe("hkdf", () => { - const regular256Key = "qBUmEYtwTwwGPuw/z6bs/qYXXYNUlocFlyAuuANI8Pw="; - const utf8256Key = "6DfJwW1R3txgiZKkIFTvVAb7qVlG7lKcmJGJoxR2GBU="; - const unicode256Key = "gejGI82xthA+nKtKmIh82kjw+ttHr+ODsUoGdu5sf0A="; - - const regular512Key = "xe5cIG6ZfwGmb1FvsOedM0XKOm21myZkjL/eDeKIqqM="; - const utf8512Key = "XQMVBnxVEhlvjSFDQc77j5GDE9aorvbS0vKnjhRg0LY="; - const unicode512Key = "148GImrTbrjaGAe/iWEpclINM8Ehhko+9lB14+52lqc="; - - testHkdf("sha256", regular256Key, utf8256Key, unicode256Key); - testHkdf("sha512", regular512Key, utf8512Key, unicode512Key); - }); - - describe("hkdfExpand", () => { - const prk16Byte = "criAmKtfzxanbgea5/kelQ=="; - const prk32Byte = "F5h4KdYQnIVH4rKH0P9CZb1GrR4n16/sJrS0PsQEn0Y="; - const prk64Byte = - "ssBK0mRG17VHdtsgt8yo4v25CRNpauH+0r2fwY/E9rLyaFBAOMbIeTry+" + - "gUJ28p8y+hFh3EI9pcrEWaNvFYonQ=="; - - testHkdfExpand("sha256", prk32Byte, 32, "BnIqJlfnHm0e/2iB/15cbHyR19ARPIcWRp4oNS22CD8="); - testHkdfExpand( - "sha256", - prk32Byte, - 64, - "BnIqJlfnHm0e/2iB/15cbHyR19ARPIcWRp4oNS22CD9BV+" + - "/queOZenPNkDhmlVyL2WZ3OSU5+7ISNF5NhNfvZA==" - ); - testHkdfExpand("sha512", prk64Byte, 32, "uLWbMWodSBms5uGJ5WTRTesyW+MD7nlpCZvagvIRXlk="); - testHkdfExpand( - "sha512", - prk64Byte, - 64, - "uLWbMWodSBms5uGJ5WTRTesyW+MD7nlpCZvagvIRXlkY5Pv0sB+" + - "MqvaopmkC6sD/j89zDwTV9Ib2fpucUydO8w==" - ); - - it("should fail with prk too small", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const f = cryptoFunctionService.hkdfExpand( - Utils.fromB64ToArray(prk16Byte), - "info", - 32, - "sha256" - ); - await expect(f).rejects.toEqual(new Error("prk is too small.")); - }); - - it("should fail with outputByteSize is too large", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const f = cryptoFunctionService.hkdfExpand( - Utils.fromB64ToArray(prk32Byte), - "info", - 8161, - "sha256" - ); - await expect(f).rejects.toEqual(new Error("outputByteSize is too large.")); - }); - }); - - describe("hash", () => { - const regular1Hash = "2a241604fb921fad12bf877282457268e1dccb70"; - const utf81Hash = "85672798dc5831e96d6c48655d3d39365a9c88b6"; - const unicode1Hash = "39c975935054a3efc805a9709b60763a823a6ad4"; - - const regular256Hash = "2b8e96031d352a8655d733d7a930b5ffbea69dc25cf65c7bca7dd946278908b2"; - const utf8256Hash = "25fe8440f5b01ed113b0a0e38e721b126d2f3f77a67518c4a04fcde4e33eeb9d"; - const unicode256Hash = "adc1c0c2afd6e92cefdf703f9b6eb2c38e0d6d1a040c83f8505c561fea58852e"; - - const regular512Hash = - "c15cf11d43bde333647e3f559ec4193bb2edeaa0e8b902772f514cdf3f785a3f49a6e02a4b87b3" + - "b47523271ad45b7e0aebb5cdcc1bc54815d256eb5dcb80da9d"; - const utf8512Hash = - "035c31a877a291af09ed2d3a1a293e69c3e079ea2cecc00211f35e6bce10474ca3ad6e30b59e26118" + - "37463f20969c5bc95282965a051a88f8cdf2e166549fcdd"; - const unicode512Hash = - "2b16a5561af8ad6fe414cc103fc8036492e1fc6d9aabe1b655497054f760fe0e34c5d100ac773d" + - "9f3030438284f22dbfa20cb2e9b019f2c98dfe38ce1ef41bae"; - - const regularMd5 = "5eceffa53a5fd58c44134211e2c5f522"; - const utf8Md5 = "3abc9433c09551b939c80aa0aa3174e1"; - const unicodeMd5 = "85ae134072c8d81257933f7045ba17ca"; - - testHash("sha1", regular1Hash, utf81Hash, unicode1Hash); - testHash("sha256", regular256Hash, utf8256Hash, unicode256Hash); - testHash("sha512", regular512Hash, utf8512Hash, unicode512Hash); - testHash("md5", regularMd5, utf8Md5, unicodeMd5); - }); - - describe("hmac", () => { - testHmac("sha1", Sha1Mac); - testHmac("sha256", Sha256Mac); - testHmac("sha512", Sha512Mac); - }); - - describe("compare", () => { - testCompare(false); - }); - - describe("hmacFast", () => { - testHmac("sha1", Sha1Mac, true); - testHmac("sha256", Sha256Mac, true); - testHmac("sha512", Sha512Mac, true); - }); - - describe("compareFast", () => { - testCompare(true); - }); - - describe("aesEncrypt", () => { - it("should successfully encrypt data", async () => { - const nodeCryptoFunctionService = new NodeCryptoFunctionService(); - const iv = makeStaticByteArray(16); - const key = makeStaticByteArray(32); - const data = Utils.fromUtf8ToArray("EncryptMe!"); - const encValue = await nodeCryptoFunctionService.aesEncrypt( - data.buffer, - iv.buffer, - key.buffer - ); - expect(Utils.fromBufferToB64(encValue)).toBe("ByUF8vhyX4ddU9gcooznwA=="); - }); - - it("should successfully encrypt and then decrypt data", async () => { - const nodeCryptoFunctionService = new NodeCryptoFunctionService(); - const iv = makeStaticByteArray(16); - const key = makeStaticByteArray(32); - const value = "EncryptMe!"; - const data = Utils.fromUtf8ToArray(value); - const encValue = await nodeCryptoFunctionService.aesEncrypt( - data.buffer, - iv.buffer, - key.buffer - ); - const decValue = await nodeCryptoFunctionService.aesDecrypt(encValue, iv.buffer, key.buffer); - expect(Utils.fromBufferToUtf8(decValue)).toBe(value); - }); - }); - - describe("aesDecryptFast", () => { - it("should successfully decrypt data", async () => { - const nodeCryptoFunctionService = new NodeCryptoFunctionService(); - const iv = Utils.fromBufferToB64(makeStaticByteArray(16).buffer); - const symKey = new SymmetricCryptoKey(makeStaticByteArray(32).buffer); - const data = "ByUF8vhyX4ddU9gcooznwA=="; - const params = nodeCryptoFunctionService.aesDecryptFastParameters(data, iv, null, symKey); - const decValue = await nodeCryptoFunctionService.aesDecryptFast(params); - expect(decValue).toBe("EncryptMe!"); - }); - }); - - describe("aesDecrypt", () => { - it("should successfully decrypt data", async () => { - const nodeCryptoFunctionService = new NodeCryptoFunctionService(); - const iv = makeStaticByteArray(16); - const key = makeStaticByteArray(32); - const data = Utils.fromB64ToArray("ByUF8vhyX4ddU9gcooznwA=="); - const decValue = await nodeCryptoFunctionService.aesDecrypt( - data.buffer, - iv.buffer, - key.buffer - ); - expect(Utils.fromBufferToUtf8(decValue)).toBe("EncryptMe!"); - }); - }); - - describe("rsaEncrypt", () => { - it("should successfully encrypt and then decrypt data", async () => { - const nodeCryptoFunctionService = new NodeCryptoFunctionService(); - const pubKey = Utils.fromB64ToArray(RsaPublicKey); - const privKey = Utils.fromB64ToArray(RsaPrivateKey); - const value = "EncryptMe!"; - const data = Utils.fromUtf8ToArray(value); - const encValue = await nodeCryptoFunctionService.rsaEncrypt( - data.buffer, - pubKey.buffer, - "sha1" - ); - const decValue = await nodeCryptoFunctionService.rsaDecrypt(encValue, privKey.buffer, "sha1"); - expect(Utils.fromBufferToUtf8(decValue)).toBe(value); - }); - }); - - describe("rsaDecrypt", () => { - it("should successfully decrypt data", async () => { - const nodeCryptoFunctionService = new NodeCryptoFunctionService(); - const privKey = Utils.fromB64ToArray(RsaPrivateKey); - const data = Utils.fromB64ToArray( - "A1/p8BQzN9UrbdYxUY2Va5+kPLyfZXF9JsZrjeEXcaclsnHurdxVAJcnbEqYMP3UXV" + - "4YAS/mpf+Rxe6/X0WS1boQdA0MAHSgx95hIlAraZYpiMLLiJRKeo2u8YivCdTM9V5vuAEJwf9Tof/qFsFci3sApdbATkorCT" + - "zFOIEPF2S1zgperEP23M01mr4dWVdYN18B32YF67xdJHMbFhp5dkQwv9CmscoWq7OE5HIfOb+JAh7BEZb+CmKhM3yWJvoR/D" + - "/5jcercUtK2o+XrzNrL4UQ7yLZcFz6Bfwb/j6ICYvqd/YJwXNE6dwlL57OfwJyCdw2rRYf0/qI00t9u8Iitw==" - ); - const decValue = await nodeCryptoFunctionService.rsaDecrypt( - data.buffer, - privKey.buffer, - "sha1" - ); - expect(Utils.fromBufferToUtf8(decValue)).toBe("EncryptMe!"); - }); - }); - - describe("rsaExtractPublicKey", () => { - it("should successfully extract key", async () => { - const nodeCryptoFunctionService = new NodeCryptoFunctionService(); - const privKey = Utils.fromB64ToArray(RsaPrivateKey); - const publicKey = await nodeCryptoFunctionService.rsaExtractPublicKey(privKey.buffer); - expect(Utils.fromBufferToB64(publicKey)).toBe(RsaPublicKey); - }); - }); - - describe("rsaGenerateKeyPair", () => { - testRsaGenerateKeyPair(1024); - testRsaGenerateKeyPair(2048); - - // Generating 4096 bit keys is really slow with Forge lib. - // Maybe move to something else if we ever want to generate keys of this size. - // testRsaGenerateKeyPair(4096); - }); - - describe("randomBytes", () => { - it("should make a value of the correct length", async () => { - const nodeCryptoFunctionService = new NodeCryptoFunctionService(); - const randomData = await nodeCryptoFunctionService.randomBytes(16); - expect(randomData.byteLength).toBe(16); - }); - - it("should not make the same value twice", async () => { - const nodeCryptoFunctionService = new NodeCryptoFunctionService(); - const randomData = await nodeCryptoFunctionService.randomBytes(16); - const randomData2 = await nodeCryptoFunctionService.randomBytes(16); - expect( - randomData.byteLength === randomData2.byteLength && randomData !== randomData2 - ).toBeTruthy(); - }); - }); -}); - -function testPbkdf2( - algorithm: "sha256" | "sha512", - regularKey: string, - utf8Key: string, - unicodeKey: string -) { - const regularEmail = "user@example.com"; - const utf8Email = "üser@example.com"; - - const regularPassword = "password"; - const utf8Password = "pǻssword"; - const unicodePassword = "😀password🙏"; - - it("should create valid " + algorithm + " key from regular input", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const key = await cryptoFunctionService.pbkdf2(regularPassword, regularEmail, algorithm, 5000); - expect(Utils.fromBufferToB64(key)).toBe(regularKey); - }); - - it("should create valid " + algorithm + " key from utf8 input", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const key = await cryptoFunctionService.pbkdf2(utf8Password, utf8Email, algorithm, 5000); - expect(Utils.fromBufferToB64(key)).toBe(utf8Key); - }); - - it("should create valid " + algorithm + " key from unicode input", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const key = await cryptoFunctionService.pbkdf2(unicodePassword, regularEmail, algorithm, 5000); - expect(Utils.fromBufferToB64(key)).toBe(unicodeKey); - }); - - it("should create valid " + algorithm + " key from array buffer input", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const key = await cryptoFunctionService.pbkdf2( - Utils.fromUtf8ToArray(regularPassword).buffer, - Utils.fromUtf8ToArray(regularEmail).buffer, - algorithm, - 5000 - ); - expect(Utils.fromBufferToB64(key)).toBe(regularKey); - }); -} - -function testHkdf( - algorithm: "sha256" | "sha512", - regularKey: string, - utf8Key: string, - unicodeKey: string -) { - const ikm = Utils.fromB64ToArray("criAmKtfzxanbgea5/kelQ=="); - - const regularSalt = "salt"; - const utf8Salt = "üser_salt"; - const unicodeSalt = "😀salt🙏"; - - const regularInfo = "info"; - const utf8Info = "üser_info"; - const unicodeInfo = "😀info🙏"; - - it("should create valid " + algorithm + " key from regular input", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const key = await cryptoFunctionService.hkdf(ikm, regularSalt, regularInfo, 32, algorithm); - expect(Utils.fromBufferToB64(key)).toBe(regularKey); - }); - - it("should create valid " + algorithm + " key from utf8 input", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const key = await cryptoFunctionService.hkdf(ikm, utf8Salt, utf8Info, 32, algorithm); - expect(Utils.fromBufferToB64(key)).toBe(utf8Key); - }); - - it("should create valid " + algorithm + " key from unicode input", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const key = await cryptoFunctionService.hkdf(ikm, unicodeSalt, unicodeInfo, 32, algorithm); - expect(Utils.fromBufferToB64(key)).toBe(unicodeKey); - }); - - it("should create valid " + algorithm + " key from array buffer input", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const key = await cryptoFunctionService.hkdf( - ikm, - Utils.fromUtf8ToArray(regularSalt).buffer, - Utils.fromUtf8ToArray(regularInfo).buffer, - 32, - algorithm - ); - expect(Utils.fromBufferToB64(key)).toBe(regularKey); - }); -} - -function testHkdfExpand( - algorithm: "sha256" | "sha512", - b64prk: string, - outputByteSize: number, - b64ExpectedOkm: string -) { - const info = "info"; - - it("should create valid " + algorithm + " " + outputByteSize + " byte okm", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const okm = await cryptoFunctionService.hkdfExpand( - Utils.fromB64ToArray(b64prk), - info, - outputByteSize, - algorithm - ); - expect(Utils.fromBufferToB64(okm)).toBe(b64ExpectedOkm); - }); -} - -function testHash( - algorithm: "sha1" | "sha256" | "sha512" | "md5", - regularHash: string, - utf8Hash: string, - unicodeHash: string -) { - const regularValue = "HashMe!!"; - const utf8Value = "HǻshMe!!"; - const unicodeValue = "😀HashMe!!!🙏"; - - it("should create valid " + algorithm + " hash from regular input", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const hash = await cryptoFunctionService.hash(regularValue, algorithm); - expect(Utils.fromBufferToHex(hash)).toBe(regularHash); - }); - - it("should create valid " + algorithm + " hash from utf8 input", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const hash = await cryptoFunctionService.hash(utf8Value, algorithm); - expect(Utils.fromBufferToHex(hash)).toBe(utf8Hash); - }); - - it("should create valid " + algorithm + " hash from unicode input", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const hash = await cryptoFunctionService.hash(unicodeValue, algorithm); - expect(Utils.fromBufferToHex(hash)).toBe(unicodeHash); - }); - - it("should create valid " + algorithm + " hash from array buffer input", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const hash = await cryptoFunctionService.hash( - Utils.fromUtf8ToArray(regularValue).buffer, - algorithm - ); - expect(Utils.fromBufferToHex(hash)).toBe(regularHash); - }); -} - -function testHmac(algorithm: "sha1" | "sha256" | "sha512", mac: string, fast = false) { - it("should create valid " + algorithm + " hmac", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const value = Utils.fromUtf8ToArray("SignMe!!").buffer; - const key = Utils.fromUtf8ToArray("secretkey").buffer; - let computedMac: ArrayBuffer = null; - if (fast) { - computedMac = await cryptoFunctionService.hmacFast(value, key, algorithm); - } else { - computedMac = await cryptoFunctionService.hmac(value, key, algorithm); - } - expect(Utils.fromBufferToHex(computedMac)).toBe(mac); - }); -} - -function testCompare(fast = false) { - it("should successfully compare two of the same values", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const a = new Uint8Array(2); - a[0] = 1; - a[1] = 2; - const equal = fast - ? await cryptoFunctionService.compareFast(a.buffer, a.buffer) - : await cryptoFunctionService.compare(a.buffer, a.buffer); - expect(equal).toBe(true); - }); - - it("should successfully compare two different values of the same length", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const a = new Uint8Array(2); - a[0] = 1; - a[1] = 2; - const b = new Uint8Array(2); - b[0] = 3; - b[1] = 4; - const equal = fast - ? await cryptoFunctionService.compareFast(a.buffer, b.buffer) - : await cryptoFunctionService.compare(a.buffer, b.buffer); - expect(equal).toBe(false); - }); - - it("should successfully compare two different values of different lengths", async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const a = new Uint8Array(2); - a[0] = 1; - a[1] = 2; - const b = new Uint8Array(2); - b[0] = 3; - const equal = fast - ? await cryptoFunctionService.compareFast(a.buffer, b.buffer) - : await cryptoFunctionService.compare(a.buffer, b.buffer); - expect(equal).toBe(false); - }); -} - -function testRsaGenerateKeyPair(length: 1024 | 2048 | 4096) { - it( - "should successfully generate a " + length + " bit key pair", - async () => { - const cryptoFunctionService = new NodeCryptoFunctionService(); - const keyPair = await cryptoFunctionService.rsaGenerateKeyPair(length); - expect(keyPair[0] == null || keyPair[1] == null).toBe(false); - const publicKey = await cryptoFunctionService.rsaExtractPublicKey(keyPair[1]); - expect(Utils.fromBufferToB64(keyPair[0])).toBe(Utils.fromBufferToB64(publicKey)); - }, - 30000 - ); -} - -function makeStaticByteArray(length: number) { - const arr = new Uint8Array(length); - for (let i = 0; i < length; i++) { - arr[i] = i; - } - return arr; -} diff --git a/jslib/node/spec/test.ts b/jslib/node/spec/test.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/package-lock.json b/package-lock.json index f9112fce..8894e27d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,6 +36,7 @@ "googleapis": "73.0.0", "https-proxy-agent": "5.0.1", "inquirer": "8.2.6", + "jsdom": "22.1.0", "keytar": "7.9.0", "ldapjs": "2.3.3", "lowdb": "1.0.0", @@ -94,7 +95,7 @@ "html-webpack-plugin": "5.5.3", "husky": "8.0.3", "jest": "29.6.4", - "jest-environment-jsdom": "^29.7.0", + "jest-junit": "16.0.0", "jest-preset-angular": "13.1.1", "lint-staged": "12.5.0", "mini-css-extract-plugin": "2.7.6", @@ -106,7 +107,7 @@ "rxjs": "7.8.1", "sass": "1.66.1", "sass-loader": "12.6.0", - "ts-jest": "29.1.1", + "ts-jest": "^29.1.1", "ts-loader": "9.4.4", "tsconfig-paths-webpack-plugin": "4.1.0", "typescript": "4.9.5", @@ -1378,9 +1379,9 @@ } }, "node_modules/@babel/helper-compilation-targets/node_modules/browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", "dev": true, "funding": [ { @@ -1397,9 +1398,9 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" }, "bin": { @@ -4010,9 +4011,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz", - "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -5426,9 +5427,9 @@ } }, "node_modules/@types/eslint": { - "version": "8.44.7", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.7.tgz", - "integrity": "sha512-f5ORu2hcBbKei97U73mf+l9t4zTGl74IqZ0GQk4oVea/VS8tQZYkUveSYojk+frraAVYId0V2WC9O4PTNru2FQ==", + "version": "8.44.8", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.8.tgz", + "integrity": "sha512-4K8GavROwhrYl2QXDXm0Rv9epkA8GBFu0EI+XrrnnuCl7u8CWBRusX7fXJfanhZTDWSAL24gDI/UqXyUM0Injw==", "dev": true, "dependencies": { "@types/estree": "*", @@ -6278,8 +6279,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "deprecated": "Use your platform's native atob() and btoa() methods instead", - "dev": true + "deprecated": "Use your platform's native atob() and btoa() methods instead" }, "node_modules/abbrev": { "version": "1.1.1", @@ -6868,8 +6868,7 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/at-least-node": { "version": "1.0.0", @@ -7697,9 +7696,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001565", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz", - "integrity": "sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==", + "version": "1.0.30001566", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", + "integrity": "sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==", "dev": true, "funding": [ { @@ -7817,9 +7816,9 @@ "dev": true }, "node_modules/clean-css": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", - "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", "dev": true, "dependencies": { "source-map": "~0.6.0" @@ -8019,7 +8018,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -8422,12 +8420,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.33.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.3.tgz", - "integrity": "sha512-cNzGqFsh3Ot+529GIXacjTJ7kegdt5fPXxCBVS1G0iaZpuo/tBz399ymceLJveQhFFZ8qThHiP3fzuoQjKN2ow==", + "version": "3.34.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.34.0.tgz", + "integrity": "sha512-4ZIyeNbW/Cn1wkMMDy+mvrRUxrwFNjKwbhCfQpDd+eLgYipDqp8oGFGtLmhh18EDPKA0g3VUBYOxQGGwvWLVpA==", "dev": true, "dependencies": { - "browserslist": "^4.22.1" + "browserslist": "^4.22.2" }, "funding": { "type": "opencollective", @@ -8435,9 +8433,9 @@ } }, "node_modules/core-js-compat/node_modules/browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", "dev": true, "funding": [ { @@ -8454,9 +8452,9 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" }, "bin": { @@ -8643,35 +8641,27 @@ "dev": true }, "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", + "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", "dependencies": { - "cssom": "~0.3.6" + "rrweb-cssom": "^0.6.0" }, "engines": { - "node": ">=8" + "node": ">=14" } }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - }, "node_modules/data-urls": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", - "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", - "dev": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", + "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", "dependencies": { "abab": "^2.0.6", "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0" + "whatwg-url": "^12.0.0" }, "engines": { - "node": ">=12" + "node": ">=14" } }, "node_modules/date-fns": { @@ -8742,8 +8732,7 @@ "node_modules/decimal.js": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" }, "node_modules/decompress-response": { "version": "3.3.0", @@ -8983,7 +8972,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -9287,7 +9275,6 @@ "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", "deprecated": "Use your platform's native DOMException instead", - "dev": true, "dependencies": { "webidl-conversions": "^7.0.0" }, @@ -9862,9 +9849,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.597", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.597.tgz", - "integrity": "sha512-0XOQNqHhg2YgRVRUrS4M4vWjFCFIP2ETXcXe/0KIQBjXE9Cpy+tgzzYfuq6HGai3hWq0YywtG+5XK8fyG08EjA==", + "version": "1.4.604", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.604.tgz", + "integrity": "sha512-JAJ4lyLJYudlgJPYJicimU9R+qZ/3iyeyQS99bfT7PWi7psYWeN84lPswTjpHxQueU34PKxM/IJzQS6poYlovQ==", "dev": true }, "node_modules/electron-updater": { @@ -9951,9 +9938,9 @@ } }, "node_modules/electron/node_modules/@types/node": { - "version": "16.18.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.66.tgz", - "integrity": "sha512-sePmD/imfKvC4re/Wwos1NEcXYm6O96CAG5gQVY53nmDb8ePQ4qPku6uruN7n6TJ0t5FhcoUc2+yvE2/UZVDZw==", + "version": "16.18.67", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.67.tgz", + "integrity": "sha512-gUa0tDO9oxyAYO9V9tqxDJguVMDpqUwH5I5Q9ASYBCso+8CUdJlKPKDYS1YSS9kyZWIduDafZvucGM0zGNKFjg==", "dev": true }, "node_modules/emittery": { @@ -11416,7 +11403,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -12099,7 +12085,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", - "dev": true, "dependencies": { "whatwg-encoding": "^2.0.0" }, @@ -12389,7 +12374,6 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "devOptional": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -12935,8 +12919,7 @@ "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" }, "node_modules/is-promise": { "version": "2.2.2", @@ -13516,6 +13499,138 @@ } } }, + "node_modules/jest-environment-jsdom/node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/jest-environment-jsdom/node_modules/data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-jsdom/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/ws": { + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", + "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/jest-environment-node": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", @@ -13567,6 +13682,33 @@ "fsevents": "^2.3.2" } }, + "node_modules/jest-junit": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-16.0.0.tgz", + "integrity": "sha512-A94mmw6NfJab4Fg/BlvVOUXzXgF0XIH6EmTgJ5NDPp4xoKq0Kr7sErb+4Xs9nZvu58pJojz5RFGpqnZYJTrRfQ==", + "dev": true, + "dependencies": { + "mkdirp": "^1.0.4", + "strip-ansi": "^6.0.1", + "uuid": "^8.3.2", + "xml": "^1.0.1" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/jest-junit/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/jest-leak-detector": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", @@ -13994,27 +14136,23 @@ } }, "node_modules/jsdom": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", - "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", - "dev": true, + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", + "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", "dependencies": { "abab": "^2.0.6", - "acorn": "^8.8.1", - "acorn-globals": "^7.0.0", - "cssom": "^0.5.0", - "cssstyle": "^2.3.0", - "data-urls": "^3.0.2", - "decimal.js": "^10.4.2", + "cssstyle": "^3.0.0", + "data-urls": "^4.0.0", + "decimal.js": "^10.4.3", "domexception": "^4.0.0", - "escodegen": "^2.0.0", "form-data": "^4.0.0", "html-encoding-sniffer": "^3.0.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.1", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.2", - "parse5": "^7.1.1", + "nwsapi": "^2.2.4", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.6.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^4.1.2", @@ -14022,12 +14160,12 @@ "webidl-conversions": "^7.0.0", "whatwg-encoding": "^2.0.0", "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0", - "ws": "^8.11.0", + "whatwg-url": "^12.0.1", + "ws": "^8.13.0", "xml-name-validator": "^4.0.0" }, "engines": { - "node": ">=14" + "node": ">=16" }, "peerDependencies": { "canvas": "^2.5.0" @@ -14042,7 +14180,6 @@ "version": "8.14.2", "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", - "dev": true, "engines": { "node": ">=10.0.0" }, @@ -15108,7 +15245,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -15117,7 +15253,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -15589,9 +15724,9 @@ } }, "node_modules/node-abi": { - "version": "3.51.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.51.0.tgz", - "integrity": "sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA==", + "version": "3.52.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.52.0.tgz", + "integrity": "sha512-JJ98b02z16ILv7859irtXn4oUaFWADtvkzy2c0IAatNVX2Mc9Yoh8z6hZInn3QwvMEYhHuQloYi+TTQy67SIdQ==", "dependencies": { "semver": "^7.3.5" }, @@ -15775,9 +15910,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, "node_modules/nopt": { @@ -16089,8 +16224,7 @@ "node_modules/nwsapi": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", - "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", - "dev": true + "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==" }, "node_modules/object-assign": { "version": "4.1.1", @@ -16119,13 +16253,13 @@ } }, "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, @@ -16508,7 +16642,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "devOptional": true, "dependencies": { "entities": "^4.4.0" }, @@ -16573,7 +16706,6 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "devOptional": true, "engines": { "node": ">=0.12" }, @@ -18157,6 +18289,11 @@ "dev": true, "optional": true }, + "node_modules/rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==" + }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -18332,7 +18469,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", - "dev": true, "dependencies": { "xmlchars": "^2.2.0" }, @@ -19364,8 +19500,7 @@ "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, "node_modules/tapable": { "version": "2.2.1", @@ -19664,9 +19799,9 @@ } }, "node_modules/terser-webpack-plugin/node_modules/terser": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.24.0.tgz", - "integrity": "sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw==", + "version": "5.25.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.25.0.tgz", + "integrity": "sha512-we0I9SIsfvNUMP77zC9HG+MylwYYsGFSBG8qm+13oud2Yh+O104y614FRbyjpxys16jZwot72Fpi827YvGzuqg==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -19880,22 +20015,20 @@ } }, "node_modules/tr46": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", - "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", - "dev": true, + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", "dependencies": { - "punycode": "^2.1.1" + "punycode": "^2.3.0" }, "engines": { - "node": ">=12" + "node": ">=14" } }, "node_modules/tr46/node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, "engines": { "node": ">=6" } @@ -20621,7 +20754,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", - "dev": true, "dependencies": { "xml-name-validator": "^4.0.0" }, @@ -20672,7 +20804,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, "engines": { "node": ">=12" } @@ -21028,7 +21159,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", - "dev": true, "dependencies": { "iconv-lite": "0.6.3" }, @@ -21040,22 +21170,20 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", - "dev": true, "engines": { "node": ">=12" } }, "node_modules/whatwg-url": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", - "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", - "dev": true, + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", + "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", "dependencies": { - "tr46": "^3.0.0", + "tr46": "^4.1.1", "webidl-conversions": "^7.0.0" }, "engines": { - "node": ">=12" + "node": ">=14" } }, "node_modules/which": { @@ -21189,11 +21317,16 @@ } } }, + "node_modules/xml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", + "dev": true + }, "node_modules/xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", - "dev": true, "engines": { "node": ">=12" } @@ -21210,8 +21343,7 @@ "node_modules/xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, "node_modules/y18n": { "version": "5.0.8", diff --git a/package.json b/package.json index fc2fd6d3..0d93e5aa 100644 --- a/package.json +++ b/package.json @@ -63,10 +63,7 @@ "publish:mac": "npm run build:dist && npm run clean:dist && electron-builder --mac -p always", "publish:win": "npm run build:dist && npm run clean:dist && electron-builder --win --x64 --ia32 -p always -c.win.certificateSubjectName=\"8bit Solutions LLC\"", "prettier": "prettier --write .", - "prepare": "husky install", - "test:jslib": "jest", - "test:jslib:watch": "jest --watch", - "test:jslib:watch:all": "jest --watchAll" + "prepare": "husky install" }, "devDependencies": { "@angular-devkit/build-angular": "15.2.9", @@ -76,7 +73,6 @@ "@microsoft/microsoft-graph-types": "2.38.0", "@ngtools/webpack": "15.2.9", "@types/inquirer": "8.2.6", - "@types/jest": "29.5.4", "@types/ldapjs": "2.2.5", "@types/lowdb": "1.0.11", "@types/lunr": "2.3.4", @@ -111,9 +107,6 @@ "html-loader": "3.1.2", "html-webpack-plugin": "5.5.3", "husky": "8.0.3", - "jest": "29.6.4", - "jest-environment-jsdom": "^29.7.0", - "jest-preset-angular": "13.1.1", "lint-staged": "12.5.0", "mini-css-extract-plugin": "2.7.6", "node-forge": "1.3.1", @@ -124,7 +117,6 @@ "rxjs": "7.8.1", "sass": "1.66.1", "sass-loader": "12.6.0", - "ts-jest": "29.1.1", "ts-loader": "9.4.4", "tsconfig-paths-webpack-plugin": "4.1.0", "typescript": "4.9.5",