mirror of
https://github.com/bitwarden/browser
synced 2025-12-18 01:03:35 +00:00
[EC-582] Add domain object serialization (#3623)
This commit is contained in:
@@ -8,7 +8,7 @@ import { EncString } from "@bitwarden/common/models/domain/encString";
|
|||||||
import { SymmetricCryptoKey } from "@bitwarden/common/models/domain/symmetricCryptoKey";
|
import { SymmetricCryptoKey } from "@bitwarden/common/models/domain/symmetricCryptoKey";
|
||||||
import { ContainerService } from "@bitwarden/common/services/container.service";
|
import { ContainerService } from "@bitwarden/common/services/container.service";
|
||||||
|
|
||||||
import { makeStaticByteArray, mockEnc } from "../../utils";
|
import { makeStaticByteArray, mockEnc, mockFromJson } from "../../utils";
|
||||||
|
|
||||||
describe("Attachment", () => {
|
describe("Attachment", () => {
|
||||||
let data: AttachmentData;
|
let data: AttachmentData;
|
||||||
@@ -131,4 +131,25 @@ describe("Attachment", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("fromJSON", () => {
|
||||||
|
it("initializes nested objects", () => {
|
||||||
|
jest.spyOn(EncString, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
|
||||||
|
const actual = Attachment.fromJSON({
|
||||||
|
key: "myKey",
|
||||||
|
fileName: "myFileName",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(actual).toEqual({
|
||||||
|
key: "myKey_fromJSON",
|
||||||
|
fileName: "myFileName_fromJSON",
|
||||||
|
});
|
||||||
|
expect(actual).toBeInstanceOf(Attachment);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns null if object is null", () => {
|
||||||
|
expect(Attachment.fromJSON(null)).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { CardData } from "@bitwarden/common/models/data/cardData";
|
import { CardData } from "@bitwarden/common/models/data/cardData";
|
||||||
import { Card } from "@bitwarden/common/models/domain/card";
|
import { Card } from "@bitwarden/common/models/domain/card";
|
||||||
|
import { EncString } from "@bitwarden/common/models/domain/encString";
|
||||||
|
|
||||||
import { mockEnc } from "../../utils";
|
import { mockEnc, mockFromJson } from "../../utils";
|
||||||
|
|
||||||
describe("Card", () => {
|
describe("Card", () => {
|
||||||
let data: CardData;
|
let data: CardData;
|
||||||
@@ -70,4 +71,33 @@ describe("Card", () => {
|
|||||||
expYear: "expYear",
|
expYear: "expYear",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("fromJSON", () => {
|
||||||
|
it("initializes nested objects", () => {
|
||||||
|
jest.spyOn(EncString, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
|
||||||
|
const actual = Card.fromJSON({
|
||||||
|
cardholderName: "mockCardHolder",
|
||||||
|
brand: "mockBrand",
|
||||||
|
number: "mockNumber",
|
||||||
|
expMonth: "mockExpMonth",
|
||||||
|
expYear: "mockExpYear",
|
||||||
|
code: "mockCode",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(actual).toEqual({
|
||||||
|
cardholderName: "mockCardHolder_fromJSON",
|
||||||
|
brand: "mockBrand_fromJSON",
|
||||||
|
number: "mockNumber_fromJSON",
|
||||||
|
expMonth: "mockExpMonth_fromJSON",
|
||||||
|
expYear: "mockExpYear_fromJSON",
|
||||||
|
code: "mockCode_fromJSON",
|
||||||
|
});
|
||||||
|
expect(actual).toBeInstanceOf(Card);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns null if object is null", () => {
|
||||||
|
expect(Card.fromJSON(null)).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Substitute, Arg } from "@fluffy-spoon/substitute";
|
import { Substitute, Arg } from "@fluffy-spoon/substitute";
|
||||||
|
import { Jsonify } from "type-fest";
|
||||||
|
|
||||||
import { CipherRepromptType } from "@bitwarden/common/enums/cipherRepromptType";
|
import { CipherRepromptType } from "@bitwarden/common/enums/cipherRepromptType";
|
||||||
import { CipherType } from "@bitwarden/common/enums/cipherType";
|
import { CipherType } from "@bitwarden/common/enums/cipherType";
|
||||||
@@ -6,16 +7,20 @@ import { FieldType } from "@bitwarden/common/enums/fieldType";
|
|||||||
import { SecureNoteType } from "@bitwarden/common/enums/secureNoteType";
|
import { SecureNoteType } from "@bitwarden/common/enums/secureNoteType";
|
||||||
import { UriMatchType } from "@bitwarden/common/enums/uriMatchType";
|
import { UriMatchType } from "@bitwarden/common/enums/uriMatchType";
|
||||||
import { CipherData } from "@bitwarden/common/models/data/cipherData";
|
import { CipherData } from "@bitwarden/common/models/data/cipherData";
|
||||||
|
import { Attachment } from "@bitwarden/common/models/domain/attachment";
|
||||||
import { Card } from "@bitwarden/common/models/domain/card";
|
import { Card } from "@bitwarden/common/models/domain/card";
|
||||||
import { Cipher } from "@bitwarden/common/models/domain/cipher";
|
import { Cipher } from "@bitwarden/common/models/domain/cipher";
|
||||||
|
import { EncString } from "@bitwarden/common/models/domain/encString";
|
||||||
|
import { Field } from "@bitwarden/common/models/domain/field";
|
||||||
import { Identity } from "@bitwarden/common/models/domain/identity";
|
import { Identity } from "@bitwarden/common/models/domain/identity";
|
||||||
import { Login } from "@bitwarden/common/models/domain/login";
|
import { Login } from "@bitwarden/common/models/domain/login";
|
||||||
|
import { Password } from "@bitwarden/common/models/domain/password";
|
||||||
import { SecureNote } from "@bitwarden/common/models/domain/secureNote";
|
import { SecureNote } from "@bitwarden/common/models/domain/secureNote";
|
||||||
import { CardView } from "@bitwarden/common/models/view/cardView";
|
import { CardView } from "@bitwarden/common/models/view/cardView";
|
||||||
import { IdentityView } from "@bitwarden/common/models/view/identityView";
|
import { IdentityView } from "@bitwarden/common/models/view/identityView";
|
||||||
import { LoginView } from "@bitwarden/common/models/view/loginView";
|
import { LoginView } from "@bitwarden/common/models/view/loginView";
|
||||||
|
|
||||||
import { mockEnc } from "../../utils";
|
import { mockEnc, mockFromJson } from "../../utils";
|
||||||
|
|
||||||
describe("Cipher DTO", () => {
|
describe("Cipher DTO", () => {
|
||||||
it("Convert from empty CipherData", () => {
|
it("Convert from empty CipherData", () => {
|
||||||
@@ -587,4 +592,63 @@ describe("Cipher DTO", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("fromJSON", () => {
|
||||||
|
it("initializes nested objects", () => {
|
||||||
|
jest.spyOn(Attachment, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
jest.spyOn(Field, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
jest.spyOn(Password, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
jest.spyOn(EncString, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
|
||||||
|
const revisionDate = new Date("2022-08-04T01:06:40.441Z");
|
||||||
|
const deletedDate = new Date("2022-09-04T01:06:40.441Z");
|
||||||
|
const actual = Cipher.fromJSON({
|
||||||
|
name: "myName",
|
||||||
|
notes: "myNotes",
|
||||||
|
revisionDate: revisionDate.toISOString(),
|
||||||
|
attachments: ["attachment1", "attachment2"] as any,
|
||||||
|
fields: ["field1", "field2"] as any,
|
||||||
|
passwordHistory: ["ph1", "ph2"] as any,
|
||||||
|
deletedDate: deletedDate.toISOString(),
|
||||||
|
} as Jsonify<Cipher>);
|
||||||
|
|
||||||
|
expect(actual).toMatchObject({
|
||||||
|
name: "myName_fromJSON",
|
||||||
|
notes: "myNotes_fromJSON",
|
||||||
|
revisionDate: revisionDate,
|
||||||
|
attachments: ["attachment1_fromJSON", "attachment2_fromJSON"],
|
||||||
|
fields: ["field1_fromJSON", "field2_fromJSON"],
|
||||||
|
passwordHistory: ["ph1_fromJSON", "ph2_fromJSON"],
|
||||||
|
deletedDate: deletedDate,
|
||||||
|
});
|
||||||
|
expect(actual).toBeInstanceOf(Cipher);
|
||||||
|
});
|
||||||
|
|
||||||
|
test.each([
|
||||||
|
// Test description, CipherType, expected output
|
||||||
|
["LoginView", CipherType.Login, { login: "myLogin_fromJSON" }],
|
||||||
|
["CardView", CipherType.Card, { card: "myCard_fromJSON" }],
|
||||||
|
["IdentityView", CipherType.Identity, { identity: "myIdentity_fromJSON" }],
|
||||||
|
["Secure Note", CipherType.SecureNote, { secureNote: "mySecureNote_fromJSON" }],
|
||||||
|
])("initializes %s", (description: string, cipherType: CipherType, expected: any) => {
|
||||||
|
jest.spyOn(Login, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
jest.spyOn(Identity, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
jest.spyOn(Card, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
jest.spyOn(SecureNote, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
|
||||||
|
const actual = Cipher.fromJSON({
|
||||||
|
login: "myLogin",
|
||||||
|
card: "myCard",
|
||||||
|
identity: "myIdentity",
|
||||||
|
secureNote: "mySecureNote",
|
||||||
|
type: cipherType,
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
expect(actual).toMatchObject(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns null if object is null", () => {
|
||||||
|
expect(Cipher.fromJSON(null)).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -226,5 +226,9 @@ describe("EncString", () => {
|
|||||||
|
|
||||||
expect(encString.toJSON()).toBe(encString.encryptedString);
|
expect(encString.toJSON()).toBe(encString.encryptedString);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("returns null if object is null", () => {
|
||||||
|
expect(EncString.fromJSON(null)).toBeNull();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { FieldType } from "@bitwarden/common/enums/fieldType";
|
import { FieldType } from "@bitwarden/common/enums/fieldType";
|
||||||
import { FieldData } from "@bitwarden/common/models/data/fieldData";
|
import { FieldData } from "@bitwarden/common/models/data/fieldData";
|
||||||
|
import { EncString } from "@bitwarden/common/models/domain/encString";
|
||||||
import { Field } from "@bitwarden/common/models/domain/field";
|
import { Field } from "@bitwarden/common/models/domain/field";
|
||||||
|
|
||||||
import { mockEnc } from "../../utils";
|
import { mockEnc, mockFromJson } from "../../utils";
|
||||||
|
|
||||||
describe("Field", () => {
|
describe("Field", () => {
|
||||||
let data: FieldData;
|
let data: FieldData;
|
||||||
@@ -61,4 +62,25 @@ describe("Field", () => {
|
|||||||
showValue: false,
|
showValue: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("fromJSON", () => {
|
||||||
|
it("initializes nested objects", () => {
|
||||||
|
jest.spyOn(EncString, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
|
||||||
|
const actual = Field.fromJSON({
|
||||||
|
name: "myName",
|
||||||
|
value: "myValue",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(actual).toEqual({
|
||||||
|
name: "myName_fromJSON",
|
||||||
|
value: "myValue_fromJSON",
|
||||||
|
});
|
||||||
|
expect(actual).toBeInstanceOf(Field);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns null if object is null", () => {
|
||||||
|
expect(Field.fromJSON(null)).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { FolderData } from "@bitwarden/common/models/data/folderData";
|
|||||||
import { EncString } from "@bitwarden/common/models/domain/encString";
|
import { EncString } from "@bitwarden/common/models/domain/encString";
|
||||||
import { Folder } from "@bitwarden/common/models/domain/folder";
|
import { Folder } from "@bitwarden/common/models/domain/folder";
|
||||||
|
|
||||||
import { mockEnc } from "../../utils";
|
import { mockEnc, mockFromJson } from "../../utils";
|
||||||
|
|
||||||
describe("Folder", () => {
|
describe("Folder", () => {
|
||||||
let data: FolderData;
|
let data: FolderData;
|
||||||
@@ -42,7 +42,6 @@ describe("Folder", () => {
|
|||||||
|
|
||||||
describe("fromJSON", () => {
|
describe("fromJSON", () => {
|
||||||
jest.mock("@bitwarden/common/models/domain/encString");
|
jest.mock("@bitwarden/common/models/domain/encString");
|
||||||
const mockFromJson = (stub: any) => (stub + "_fromJSON") as any;
|
|
||||||
jest.spyOn(EncString, "fromJSON").mockImplementation(mockFromJson);
|
jest.spyOn(EncString, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
|
||||||
it("initializes nested objects", () => {
|
it("initializes nested objects", () => {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { IdentityData } from "@bitwarden/common/models/data/identityData";
|
import { IdentityData } from "@bitwarden/common/models/data/identityData";
|
||||||
|
import { EncString } from "@bitwarden/common/models/domain/encString";
|
||||||
import { Identity } from "@bitwarden/common/models/domain/identity";
|
import { Identity } from "@bitwarden/common/models/domain/identity";
|
||||||
|
|
||||||
import { mockEnc } from "../../utils";
|
import { mockEnc, mockFromJson } from "../../utils";
|
||||||
|
|
||||||
describe("Identity", () => {
|
describe("Identity", () => {
|
||||||
let data: IdentityData;
|
let data: IdentityData;
|
||||||
@@ -131,4 +132,57 @@ describe("Identity", () => {
|
|||||||
username: "mockUsername",
|
username: "mockUsername",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("fromJSON", () => {
|
||||||
|
it("initializes nested objects", () => {
|
||||||
|
jest.spyOn(EncString, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
|
||||||
|
const actual = Identity.fromJSON({
|
||||||
|
firstName: "mockFirstName",
|
||||||
|
lastName: "mockLastName",
|
||||||
|
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",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(actual).toEqual({
|
||||||
|
firstName: "mockFirstName_fromJSON",
|
||||||
|
lastName: "mockLastName_fromJSON",
|
||||||
|
address1: "mockAddress1_fromJSON",
|
||||||
|
address2: "mockAddress2_fromJSON",
|
||||||
|
address3: "mockAddress3_fromJSON",
|
||||||
|
city: "mockCity_fromJSON",
|
||||||
|
company: "mockCompany_fromJSON",
|
||||||
|
country: "mockCountry_fromJSON",
|
||||||
|
email: "mockEmail_fromJSON",
|
||||||
|
licenseNumber: "mockLicenseNumber_fromJSON",
|
||||||
|
middleName: "mockMiddleName_fromJSON",
|
||||||
|
passportNumber: "mockPassportNumber_fromJSON",
|
||||||
|
phone: "mockPhone_fromJSON",
|
||||||
|
postalCode: "mockPostalCode_fromJSON",
|
||||||
|
ssn: "mockSsn_fromJSON",
|
||||||
|
state: "mockState_fromJSON",
|
||||||
|
title: "mockTitle_fromJSON",
|
||||||
|
username: "mockUsername_fromJSON",
|
||||||
|
});
|
||||||
|
expect(actual).toBeInstanceOf(Identity);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns null if object is null", () => {
|
||||||
|
expect(Identity.fromJSON(null)).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,11 +2,12 @@ import { Substitute, Arg } from "@fluffy-spoon/substitute";
|
|||||||
|
|
||||||
import { UriMatchType } from "@bitwarden/common/enums/uriMatchType";
|
import { UriMatchType } from "@bitwarden/common/enums/uriMatchType";
|
||||||
import { LoginData } from "@bitwarden/common/models/data/loginData";
|
import { LoginData } from "@bitwarden/common/models/data/loginData";
|
||||||
|
import { EncString } from "@bitwarden/common/models/domain/encString";
|
||||||
import { Login } from "@bitwarden/common/models/domain/login";
|
import { Login } from "@bitwarden/common/models/domain/login";
|
||||||
import { LoginUri } from "@bitwarden/common/models/domain/loginUri";
|
import { LoginUri } from "@bitwarden/common/models/domain/loginUri";
|
||||||
import { LoginUriView } from "@bitwarden/common/models/view/loginUriView";
|
import { LoginUriView } from "@bitwarden/common/models/view/loginUriView";
|
||||||
|
|
||||||
import { mockEnc } from "../../utils";
|
import { mockEnc, mockFromJson } from "../../utils";
|
||||||
|
|
||||||
describe("Login DTO", () => {
|
describe("Login DTO", () => {
|
||||||
it("Convert from empty LoginData", () => {
|
it("Convert from empty LoginData", () => {
|
||||||
@@ -98,4 +99,33 @@ describe("Login DTO", () => {
|
|||||||
|
|
||||||
expect(loginData).toEqual(data);
|
expect(loginData).toEqual(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("fromJSON", () => {
|
||||||
|
it("initializes nested objects", () => {
|
||||||
|
jest.spyOn(EncString, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
jest.spyOn(LoginUri, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
const passwordRevisionDate = new Date("2022-01-31T12:00:00.000Z");
|
||||||
|
|
||||||
|
const actual = Login.fromJSON({
|
||||||
|
uris: ["loginUri1", "loginUri2"] as any,
|
||||||
|
username: "myUsername",
|
||||||
|
password: "myPassword",
|
||||||
|
passwordRevisionDate: passwordRevisionDate.toISOString(),
|
||||||
|
totp: "myTotp",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(actual).toEqual({
|
||||||
|
uris: ["loginUri1_fromJSON", "loginUri2_fromJSON"] as any,
|
||||||
|
username: "myUsername_fromJSON",
|
||||||
|
password: "myPassword_fromJSON",
|
||||||
|
passwordRevisionDate: passwordRevisionDate,
|
||||||
|
totp: "myTotp_fromJSON",
|
||||||
|
});
|
||||||
|
expect(actual).toBeInstanceOf(Login);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns null if object is null", () => {
|
||||||
|
expect(Login.fromJSON(null)).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
|
import { Jsonify } from "type-fest";
|
||||||
|
|
||||||
import { UriMatchType } from "@bitwarden/common/enums/uriMatchType";
|
import { UriMatchType } from "@bitwarden/common/enums/uriMatchType";
|
||||||
import { LoginUriData } from "@bitwarden/common/models/data/loginUriData";
|
import { LoginUriData } from "@bitwarden/common/models/data/loginUriData";
|
||||||
|
import { EncString } from "@bitwarden/common/models/domain/encString";
|
||||||
import { LoginUri } from "@bitwarden/common/models/domain/loginUri";
|
import { LoginUri } from "@bitwarden/common/models/domain/loginUri";
|
||||||
|
|
||||||
import { mockEnc } from "../../utils";
|
import { mockEnc, mockFromJson } from "../../utils";
|
||||||
|
|
||||||
describe("LoginUri", () => {
|
describe("LoginUri", () => {
|
||||||
let data: LoginUriData;
|
let data: LoginUriData;
|
||||||
@@ -54,4 +57,23 @@ describe("LoginUri", () => {
|
|||||||
match: 3,
|
match: 3,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("fromJSON", () => {
|
||||||
|
it("initializes nested objects", () => {
|
||||||
|
jest.spyOn(EncString, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
|
||||||
|
const actual = LoginUri.fromJSON({
|
||||||
|
uri: "myUri",
|
||||||
|
} as Jsonify<LoginUri>);
|
||||||
|
|
||||||
|
expect(actual).toEqual({
|
||||||
|
uri: "myUri_fromJSON",
|
||||||
|
});
|
||||||
|
expect(actual).toBeInstanceOf(LoginUri);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns null if object is null", () => {
|
||||||
|
expect(LoginUri.fromJSON(null)).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { PasswordHistoryData } from "@bitwarden/common/models/data/passwordHistoryData";
|
import { PasswordHistoryData } from "@bitwarden/common/models/data/passwordHistoryData";
|
||||||
|
import { EncString } from "@bitwarden/common/models/domain/encString";
|
||||||
import { Password } from "@bitwarden/common/models/domain/password";
|
import { Password } from "@bitwarden/common/models/domain/password";
|
||||||
|
|
||||||
import { mockEnc } from "../../utils";
|
import { mockEnc, mockFromJson } from "../../utils";
|
||||||
|
|
||||||
describe("Password", () => {
|
describe("Password", () => {
|
||||||
let data: PasswordHistoryData;
|
let data: PasswordHistoryData;
|
||||||
@@ -48,4 +49,26 @@ describe("Password", () => {
|
|||||||
lastUsedDate: new Date("2022-01-31T12:00:00.000Z"),
|
lastUsedDate: new Date("2022-01-31T12:00:00.000Z"),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("fromJSON", () => {
|
||||||
|
it("initializes nested objects", () => {
|
||||||
|
jest.spyOn(EncString, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
const lastUsedDate = new Date("2022-01-31T12:00:00.000Z");
|
||||||
|
|
||||||
|
const actual = Password.fromJSON({
|
||||||
|
password: "myPassword",
|
||||||
|
lastUsedDate: lastUsedDate.toISOString(),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(actual).toEqual({
|
||||||
|
password: "myPassword_fromJSON",
|
||||||
|
lastUsedDate: lastUsedDate,
|
||||||
|
});
|
||||||
|
expect(actual).toBeInstanceOf(Password);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns null if object is null", () => {
|
||||||
|
expect(Password.fromJSON(null)).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -43,4 +43,10 @@ describe("SecureNote", () => {
|
|||||||
type: 0,
|
type: 0,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("fromJSON", () => {
|
||||||
|
it("returns null if object is null", () => {
|
||||||
|
expect(SecureNote.fromJSON(null)).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { SymmetricCryptoKey } from "@bitwarden/common/models/domain/symmetricCryptoKey";
|
import { SymmetricCryptoKey } from "@bitwarden/common/models/domain/symmetricCryptoKey";
|
||||||
import { AttachmentView } from "@bitwarden/common/models/view/attachmentView";
|
import { AttachmentView } from "@bitwarden/common/models/view/attachmentView";
|
||||||
|
|
||||||
|
import { mockFromJson } from "../../utils";
|
||||||
|
|
||||||
jest.mock("@bitwarden/common/models/domain/symmetricCryptoKey");
|
jest.mock("@bitwarden/common/models/domain/symmetricCryptoKey");
|
||||||
|
|
||||||
describe("AttachmentView", () => {
|
describe("AttachmentView", () => {
|
||||||
it("fromJSON initializes nested objects", () => {
|
it("fromJSON initializes nested objects", () => {
|
||||||
const mockFromJson = (stub: string) => stub + "_fromJSON";
|
jest.spyOn(SymmetricCryptoKey, "fromJSON").mockImplementation(mockFromJson);
|
||||||
jest.spyOn(SymmetricCryptoKey, "fromJSON").mockImplementation(mockFromJson as any);
|
|
||||||
|
|
||||||
const actual = AttachmentView.fromJSON({
|
const actual = AttachmentView.fromJSON({
|
||||||
key: "encKeyB64" as any,
|
key: "encKeyB64" as any,
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import { LoginView } from "@bitwarden/common/models/view/loginView";
|
|||||||
import { PasswordHistoryView } from "@bitwarden/common/models/view/passwordHistoryView";
|
import { PasswordHistoryView } from "@bitwarden/common/models/view/passwordHistoryView";
|
||||||
import { SecureNoteView } from "@bitwarden/common/models/view/secureNoteView";
|
import { SecureNoteView } from "@bitwarden/common/models/view/secureNoteView";
|
||||||
|
|
||||||
|
import { mockFromJson } from "../../utils";
|
||||||
|
|
||||||
jest.mock("@bitwarden/common/models/view/loginView");
|
jest.mock("@bitwarden/common/models/view/loginView");
|
||||||
jest.mock("@bitwarden/common/models/view/attachmentView");
|
jest.mock("@bitwarden/common/models/view/attachmentView");
|
||||||
jest.mock("@bitwarden/common/models/view/fieldView");
|
jest.mock("@bitwarden/common/models/view/fieldView");
|
||||||
@@ -22,8 +24,6 @@ describe("CipherView", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("fromJSON", () => {
|
describe("fromJSON", () => {
|
||||||
const mockFromJson = (stub: any) => (stub + "_fromJSON") as any;
|
|
||||||
|
|
||||||
it("initializes nested objects", () => {
|
it("initializes nested objects", () => {
|
||||||
jest.spyOn(AttachmentView, "fromJSON").mockImplementation(mockFromJson);
|
jest.spyOn(AttachmentView, "fromJSON").mockImplementation(mockFromJson);
|
||||||
jest.spyOn(FieldView, "fromJSON").mockImplementation(mockFromJson);
|
jest.spyOn(FieldView, "fromJSON").mockImplementation(mockFromJson);
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { LoginUriView } from "@bitwarden/common/models/view/loginUriView";
|
import { LoginUriView } from "@bitwarden/common/models/view/loginUriView";
|
||||||
import { LoginView } from "@bitwarden/common/models/view/loginView";
|
import { LoginView } from "@bitwarden/common/models/view/loginView";
|
||||||
|
|
||||||
|
import { mockFromJson } from "../../utils";
|
||||||
|
|
||||||
jest.mock("@bitwarden/common/models/view/loginUriView");
|
jest.mock("@bitwarden/common/models/view/loginUriView");
|
||||||
|
|
||||||
describe("LoginView", () => {
|
describe("LoginView", () => {
|
||||||
@@ -9,8 +11,7 @@ describe("LoginView", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("fromJSON initializes nested objects", () => {
|
it("fromJSON initializes nested objects", () => {
|
||||||
const mockFromJson = (stub: string) => stub + "_fromJSON";
|
jest.spyOn(LoginUriView, "fromJSON").mockImplementation(mockFromJson);
|
||||||
jest.spyOn(LoginUriView, "fromJSON").mockImplementation(mockFromJson as any);
|
|
||||||
|
|
||||||
const passwordRevisionDate = new Date();
|
const passwordRevisionDate = new Date();
|
||||||
|
|
||||||
|
|||||||
@@ -35,3 +35,8 @@ export function makeStaticByteArray(length: number, start = 0) {
|
|||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use to mock a return value of a static fromJSON method.
|
||||||
|
*/
|
||||||
|
export const mockFromJson = (stub: any) => (stub + "_fromJSON") as any;
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Jsonify } from "type-fest";
|
||||||
|
|
||||||
import { Utils } from "../../misc/utils";
|
import { Utils } from "../../misc/utils";
|
||||||
import { AttachmentData } from "../data/attachmentData";
|
import { AttachmentData } from "../data/attachmentData";
|
||||||
import { AttachmentView } from "../view/attachmentView";
|
import { AttachmentView } from "../view/attachmentView";
|
||||||
@@ -90,4 +92,18 @@ export class Attachment extends Domain {
|
|||||||
);
|
);
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fromJSON(obj: Partial<Jsonify<Attachment>>): Attachment {
|
||||||
|
if (obj == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const key = EncString.fromJSON(obj.key);
|
||||||
|
const fileName = EncString.fromJSON(obj.fileName);
|
||||||
|
|
||||||
|
return Object.assign(new Attachment(), obj, {
|
||||||
|
key,
|
||||||
|
fileName,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Jsonify } from "type-fest";
|
||||||
|
|
||||||
import { CardData } from "../data/cardData";
|
import { CardData } from "../data/cardData";
|
||||||
import { CardView } from "../view/cardView";
|
import { CardView } from "../view/cardView";
|
||||||
|
|
||||||
@@ -62,4 +64,25 @@ export class Card extends Domain {
|
|||||||
});
|
});
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fromJSON(obj: Partial<Jsonify<Card>>): Card {
|
||||||
|
if (obj == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cardholderName = EncString.fromJSON(obj.cardholderName);
|
||||||
|
const brand = EncString.fromJSON(obj.brand);
|
||||||
|
const number = EncString.fromJSON(obj.number);
|
||||||
|
const expMonth = EncString.fromJSON(obj.expMonth);
|
||||||
|
const expYear = EncString.fromJSON(obj.expYear);
|
||||||
|
const code = EncString.fromJSON(obj.code);
|
||||||
|
return Object.assign(new Card(), obj, {
|
||||||
|
cardholderName,
|
||||||
|
brand,
|
||||||
|
number,
|
||||||
|
expMonth,
|
||||||
|
expYear,
|
||||||
|
code,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Jsonify } from "type-fest";
|
||||||
|
|
||||||
import { CipherRepromptType } from "../../enums/cipherRepromptType";
|
import { CipherRepromptType } from "../../enums/cipherRepromptType";
|
||||||
import { CipherType } from "../../enums/cipherType";
|
import { CipherType } from "../../enums/cipherType";
|
||||||
import { CipherData } from "../data/cipherData";
|
import { CipherData } from "../data/cipherData";
|
||||||
@@ -234,4 +236,48 @@ export class Cipher extends Domain {
|
|||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fromJSON(obj: Jsonify<Cipher>) {
|
||||||
|
if (obj == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const domain = new Cipher();
|
||||||
|
const name = EncString.fromJSON(obj.name);
|
||||||
|
const notes = EncString.fromJSON(obj.notes);
|
||||||
|
const revisionDate = obj.revisionDate == null ? null : new Date(obj.revisionDate);
|
||||||
|
const deletedDate = obj.deletedDate == null ? null : new Date(obj.deletedDate);
|
||||||
|
const attachments = obj.attachments?.map((a: any) => Attachment.fromJSON(a));
|
||||||
|
const fields = obj.fields?.map((f: any) => Field.fromJSON(f));
|
||||||
|
const passwordHistory = obj.passwordHistory?.map((ph: any) => Password.fromJSON(ph));
|
||||||
|
|
||||||
|
Object.assign(domain, obj, {
|
||||||
|
name,
|
||||||
|
notes,
|
||||||
|
revisionDate,
|
||||||
|
deletedDate,
|
||||||
|
attachments,
|
||||||
|
fields,
|
||||||
|
passwordHistory,
|
||||||
|
});
|
||||||
|
|
||||||
|
switch (obj.type) {
|
||||||
|
case CipherType.Card:
|
||||||
|
domain.card = Card.fromJSON(obj.card);
|
||||||
|
break;
|
||||||
|
case CipherType.Identity:
|
||||||
|
domain.identity = Identity.fromJSON(obj.identity);
|
||||||
|
break;
|
||||||
|
case CipherType.Login:
|
||||||
|
domain.login = Login.fromJSON(obj.login);
|
||||||
|
break;
|
||||||
|
case CipherType.SecureNote:
|
||||||
|
domain.secureNote = SecureNote.fromJSON(obj.secureNote);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,10 @@ export class EncString implements IEncrypted {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static fromJSON(obj: Jsonify<EncString>): EncString {
|
static fromJSON(obj: Jsonify<EncString>): EncString {
|
||||||
|
if (obj == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return new EncString(obj);
|
return new EncString(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Jsonify } from "type-fest";
|
||||||
|
|
||||||
import { FieldType } from "../../enums/fieldType";
|
import { FieldType } from "../../enums/fieldType";
|
||||||
import { LinkedIdType } from "../../enums/linkedIdType";
|
import { LinkedIdType } from "../../enums/linkedIdType";
|
||||||
import { FieldData } from "../data/fieldData";
|
import { FieldData } from "../data/fieldData";
|
||||||
@@ -59,4 +61,18 @@ export class Field extends Domain {
|
|||||||
);
|
);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fromJSON(obj: Partial<Jsonify<Field>>): Field {
|
||||||
|
if (obj == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const name = EncString.fromJSON(obj.name);
|
||||||
|
const value = EncString.fromJSON(obj.value);
|
||||||
|
|
||||||
|
return Object.assign(new Field(), obj, {
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Jsonify } from "type-fest";
|
||||||
|
|
||||||
import { IdentityData } from "../data/identityData";
|
import { IdentityData } from "../data/identityData";
|
||||||
import { IdentityView } from "../view/identityView";
|
import { IdentityView } from "../view/identityView";
|
||||||
|
|
||||||
@@ -110,4 +112,50 @@ export class Identity extends Domain {
|
|||||||
});
|
});
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fromJSON(obj: Jsonify<Identity>): Identity {
|
||||||
|
if (obj == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const title = EncString.fromJSON(obj.title);
|
||||||
|
const firstName = EncString.fromJSON(obj.firstName);
|
||||||
|
const middleName = EncString.fromJSON(obj.middleName);
|
||||||
|
const lastName = EncString.fromJSON(obj.lastName);
|
||||||
|
const address1 = EncString.fromJSON(obj.address1);
|
||||||
|
const address2 = EncString.fromJSON(obj.address2);
|
||||||
|
const address3 = EncString.fromJSON(obj.address3);
|
||||||
|
const city = EncString.fromJSON(obj.city);
|
||||||
|
const state = EncString.fromJSON(obj.state);
|
||||||
|
const postalCode = EncString.fromJSON(obj.postalCode);
|
||||||
|
const country = EncString.fromJSON(obj.country);
|
||||||
|
const company = EncString.fromJSON(obj.company);
|
||||||
|
const email = EncString.fromJSON(obj.email);
|
||||||
|
const phone = EncString.fromJSON(obj.phone);
|
||||||
|
const ssn = EncString.fromJSON(obj.ssn);
|
||||||
|
const username = EncString.fromJSON(obj.username);
|
||||||
|
const passportNumber = EncString.fromJSON(obj.passportNumber);
|
||||||
|
const licenseNumber = EncString.fromJSON(obj.licenseNumber);
|
||||||
|
|
||||||
|
return Object.assign(new Identity(), obj, {
|
||||||
|
title,
|
||||||
|
firstName,
|
||||||
|
middleName,
|
||||||
|
lastName,
|
||||||
|
address1,
|
||||||
|
address2,
|
||||||
|
address3,
|
||||||
|
city,
|
||||||
|
state,
|
||||||
|
postalCode,
|
||||||
|
country,
|
||||||
|
company,
|
||||||
|
email,
|
||||||
|
phone,
|
||||||
|
ssn,
|
||||||
|
username,
|
||||||
|
passportNumber,
|
||||||
|
licenseNumber,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Jsonify } from "type-fest";
|
||||||
|
|
||||||
import { LoginData } from "../data/loginData";
|
import { LoginData } from "../data/loginData";
|
||||||
import { LoginView } from "../view/loginView";
|
import { LoginView } from "../view/loginView";
|
||||||
|
|
||||||
@@ -85,4 +87,25 @@ export class Login extends Domain {
|
|||||||
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fromJSON(obj: Partial<Jsonify<Login>>): Login {
|
||||||
|
if (obj == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const username = EncString.fromJSON(obj.username);
|
||||||
|
const password = EncString.fromJSON(obj.password);
|
||||||
|
const totp = EncString.fromJSON(obj.totp);
|
||||||
|
const passwordRevisionDate =
|
||||||
|
obj.passwordRevisionDate == null ? null : new Date(obj.passwordRevisionDate);
|
||||||
|
const uris = obj.uris?.map((uri: any) => LoginUri.fromJSON(uri));
|
||||||
|
|
||||||
|
return Object.assign(new Login(), obj, {
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
totp,
|
||||||
|
passwordRevisionDate: passwordRevisionDate,
|
||||||
|
uris: uris,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Jsonify } from "type-fest";
|
||||||
|
|
||||||
import { UriMatchType } from "../../enums/uriMatchType";
|
import { UriMatchType } from "../../enums/uriMatchType";
|
||||||
import { LoginUriData } from "../data/loginUriData";
|
import { LoginUriData } from "../data/loginUriData";
|
||||||
import { LoginUriView } from "../view/loginUriView";
|
import { LoginUriView } from "../view/loginUriView";
|
||||||
@@ -51,4 +53,15 @@ export class LoginUri extends Domain {
|
|||||||
);
|
);
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fromJSON(obj: Jsonify<LoginUri>): LoginUri {
|
||||||
|
if (obj == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uri = EncString.fromJSON(obj.uri);
|
||||||
|
return Object.assign(new LoginUri(), obj, {
|
||||||
|
uri,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Jsonify } from "type-fest";
|
||||||
|
|
||||||
import { PasswordHistoryData } from "../data/passwordHistoryData";
|
import { PasswordHistoryData } from "../data/passwordHistoryData";
|
||||||
import { PasswordHistoryView } from "../view/passwordHistoryView";
|
import { PasswordHistoryView } from "../view/passwordHistoryView";
|
||||||
|
|
||||||
@@ -40,4 +42,18 @@ export class Password extends Domain {
|
|||||||
});
|
});
|
||||||
return ph;
|
return ph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fromJSON(obj: Partial<Jsonify<Password>>): Password {
|
||||||
|
if (obj == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const password = EncString.fromJSON(obj.password);
|
||||||
|
const lastUsedDate = obj.lastUsedDate == null ? null : new Date(obj.lastUsedDate);
|
||||||
|
|
||||||
|
return Object.assign(new Password(), obj, {
|
||||||
|
password,
|
||||||
|
lastUsedDate,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Jsonify } from "type-fest";
|
||||||
|
|
||||||
import { SecureNoteType } from "../../enums/secureNoteType";
|
import { SecureNoteType } from "../../enums/secureNoteType";
|
||||||
import { SecureNoteData } from "../data/secureNoteData";
|
import { SecureNoteData } from "../data/secureNoteData";
|
||||||
import { SecureNoteView } from "../view/secureNoteView";
|
import { SecureNoteView } from "../view/secureNoteView";
|
||||||
@@ -26,4 +28,12 @@ export class SecureNote extends Domain {
|
|||||||
n.type = this.type;
|
n.type = this.type;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fromJSON(obj: Jsonify<SecureNote>): SecureNote {
|
||||||
|
if (obj == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.assign(new SecureNote(), obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user