From 10a0bf268b0bf2a24fd25a851090ca9ef7ba4844 Mon Sep 17 00:00:00 2001 From: gbubemismith Date: Fri, 28 Mar 2025 13:45:51 -0400 Subject: [PATCH] Created mappings for client domain object to SDK --- .../src/vault/models/data/cipher.data.ts | 2 +- .../vault/models/domain/attachment.spec.ts | 17 ++ .../src/vault/models/domain/attachment.ts | 18 ++ .../src/vault/models/domain/card.spec.ts | 17 ++ libs/common/src/vault/models/domain/card.ts | 18 ++ .../src/vault/models/domain/cipher.spec.ts | 160 +++++++++++++++++- libs/common/src/vault/models/domain/cipher.ts | 63 +++++++ .../models/domain/fido2-credential.spec.ts | 39 +++++ .../vault/models/domain/fido2-credential.ts | 25 +++ .../src/vault/models/domain/field.spec.ts | 24 ++- libs/common/src/vault/models/domain/field.ts | 17 ++ .../src/vault/models/domain/identity.spec.ts | 28 +++ .../src/vault/models/domain/identity.ts | 30 ++++ .../src/vault/models/domain/login-uri.spec.ts | 15 ++ .../src/vault/models/domain/login-uri.ts | 15 ++ .../src/vault/models/domain/login.spec.ts | 48 ++++++ libs/common/src/vault/models/domain/login.ts | 19 +++ .../src/vault/models/domain/password.spec.ts | 13 ++ .../src/vault/models/domain/password.ts | 14 ++ .../vault/models/domain/secure-note.spec.ts | 13 ++ .../src/vault/models/domain/secure-note.ts | 13 ++ .../src/vault/models/domain/ssh-key.spec.ts | 13 ++ .../common/src/vault/models/domain/ssh-key.ts | 15 ++ 23 files changed, 633 insertions(+), 3 deletions(-) diff --git a/libs/common/src/vault/models/data/cipher.data.ts b/libs/common/src/vault/models/data/cipher.data.ts index 1c86f91c82f..e120565c5e9 100644 --- a/libs/common/src/vault/models/data/cipher.data.ts +++ b/libs/common/src/vault/models/data/cipher.data.ts @@ -37,7 +37,7 @@ export class CipherData { passwordHistory?: PasswordHistoryData[]; collectionIds?: string[]; creationDate: string; - deletedDate: string; + deletedDate: string | null; reprompt: CipherRepromptType; key: string; diff --git a/libs/common/src/vault/models/domain/attachment.spec.ts b/libs/common/src/vault/models/domain/attachment.spec.ts index d1ee1dcc1ef..324b159722b 100644 --- a/libs/common/src/vault/models/domain/attachment.spec.ts +++ b/libs/common/src/vault/models/domain/attachment.spec.ts @@ -150,4 +150,21 @@ describe("Attachment", () => { expect(Attachment.fromJSON(null)).toBeNull(); }); }); + + describe("toSdkAttachment", () => { + it("should map to SDK Attachment", () => { + const attachment = new Attachment(data); + + const sdkAttachment = attachment.toSdkAttachment(); + + expect(sdkAttachment).toEqual({ + id: "id", + url: "url", + size: "1100", + sizeName: "1.1 KB", + fileName: "fileName", + key: "key", + }); + }); + }); }); diff --git a/libs/common/src/vault/models/domain/attachment.ts b/libs/common/src/vault/models/domain/attachment.ts index 4eee0307746..d949bd29ed7 100644 --- a/libs/common/src/vault/models/domain/attachment.ts +++ b/libs/common/src/vault/models/domain/attachment.ts @@ -2,6 +2,8 @@ // @ts-strict-ignore import { Jsonify } from "type-fest"; +import { Attachment as SdkAttachment } from "@bitwarden/sdk-internal"; + import { Utils } from "../../../platform/misc/utils"; import Domain from "../../../platform/models/domain/domain-base"; import { EncString } from "../../../platform/models/domain/enc-string"; @@ -114,4 +116,20 @@ export class Attachment extends Domain { fileName, }); } + + /** + * Maps to SDK Attachment + * + * @returns {SdkAttachment} - The SDK Attachment object + */ + toSdkAttachment(): SdkAttachment { + return { + id: this.id, + url: this.url, + size: this.size, + sizeName: this.sizeName, + fileName: this.fileName?.toJSON(), + key: this.key?.toJSON(), + }; + } } diff --git a/libs/common/src/vault/models/domain/card.spec.ts b/libs/common/src/vault/models/domain/card.spec.ts index a7011966d94..19546ddcb05 100644 --- a/libs/common/src/vault/models/domain/card.spec.ts +++ b/libs/common/src/vault/models/domain/card.spec.ts @@ -99,4 +99,21 @@ describe("Card", () => { expect(Card.fromJSON(null)).toBeNull(); }); }); + + describe("toSdkCard", () => { + it("should map to SDK Card", () => { + const card = new Card(data); + + const sdkCard = card.toSdkCard(); + + expect(sdkCard).toEqual({ + cardholderName: "encHolder", + brand: "encBrand", + number: "encNumber", + expMonth: "encMonth", + expYear: "encYear", + code: "encCode", + }); + }); + }); }); diff --git a/libs/common/src/vault/models/domain/card.ts b/libs/common/src/vault/models/domain/card.ts index fccfe3f595b..258ce1d507b 100644 --- a/libs/common/src/vault/models/domain/card.ts +++ b/libs/common/src/vault/models/domain/card.ts @@ -2,6 +2,8 @@ // @ts-strict-ignore import { Jsonify } from "type-fest"; +import { Card as SdkCard } from "@bitwarden/sdk-internal"; + import Domain from "../../../platform/models/domain/domain-base"; import { EncString } from "../../../platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; @@ -91,4 +93,20 @@ export class Card extends Domain { code, }); } + + /** + * Maps Card to SDK format. + * + * @returns {SdkCard} The SDK card object. + */ + toSdkCard(): SdkCard { + return { + cardholderName: this.cardholderName?.toJSON(), + brand: this.brand?.toJSON(), + number: this.number?.toJSON(), + expMonth: this.expMonth?.toJSON(), + expYear: this.expYear?.toJSON(), + code: this.code?.toJSON(), + }; + } } diff --git a/libs/common/src/vault/models/domain/cipher.spec.ts b/libs/common/src/vault/models/domain/cipher.spec.ts index 9eadd20f543..3971150c25f 100644 --- a/libs/common/src/vault/models/domain/cipher.spec.ts +++ b/libs/common/src/vault/models/domain/cipher.spec.ts @@ -2,6 +2,12 @@ import { mock } from "jest-mock-extended"; import { Jsonify } from "type-fest"; import { KeyService } from "@bitwarden/key-management"; +import { + CipherType as SdkCipherType, + UriMatchType, + CipherRepromptType as SdkCipherRepromptType, + LoginLinkedIdType, +} from "@bitwarden/sdk-internal"; import { makeStaticByteArray, mockEnc, mockFromJson } from "../../../../spec/utils"; import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; @@ -11,7 +17,7 @@ import { ContainerService } from "../../../platform/services/container.service"; import { InitializerKey } from "../../../platform/services/cryptography/initializer-key"; import { UserId } from "../../../types/guid"; import { CipherService } from "../../abstractions/cipher.service"; -import { FieldType, SecureNoteType } from "../../enums"; +import { FieldType, LoginLinkedId, SecureNoteType } from "../../enums"; import { CipherRepromptType } from "../../enums/cipher-reprompt-type"; import { CipherType } from "../../enums/cipher-type"; import { CipherData } from "../../models/data/cipher.data"; @@ -743,6 +749,158 @@ describe("Cipher DTO", () => { expect(Cipher.fromJSON(null)).toBeNull(); }); }); + + describe("toSdkCipher", () => { + it("should map to SDK Cipher", () => { + const cipherData: CipherData = { + id: "id", + organizationId: "orgId", + folderId: "folderId", + edit: true, + viewPassword: true, + organizationUseTotp: true, + favorite: false, + revisionDate: "2022-01-31T12:00:00.000Z", + type: CipherType.Login, + name: "EncryptedString", + notes: "EncryptedString", + creationDate: "2022-01-01T12:00:00.000Z", + deletedDate: null, + reprompt: CipherRepromptType.None, + key: "EncryptedString", + login: { + uris: [ + { + uri: "EncryptedString", + uriChecksum: "EncryptedString", + match: UriMatchStrategy.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.Linked, + linkedId: LoginLinkedId.Username, + }, + { + name: "EncryptedString", + value: "EncryptedString", + type: FieldType.Linked, + linkedId: LoginLinkedId.Password, + }, + ], + }; + + const cipher = new Cipher(cipherData); + const sdkCipher = cipher.toSdkCipher(); + + expect(sdkCipher).toEqual({ + id: "id", + organizationId: "orgId", + folderId: "folderId", + collectionIds: undefined, + key: "EncryptedString", + name: "EncryptedString", + notes: "EncryptedString", + type: SdkCipherType.Login, + login: { + username: "EncryptedString", + password: "EncryptedString", + passwordRevisionDate: "2022-01-31T12:00:00.000Z", + uris: [ + { + uri: "EncryptedString", + uriChecksum: "EncryptedString", + match: UriMatchType.Domain, + }, + ], + totp: "EncryptedString", + autofillOnPageLoad: false, + fido2Credentials: undefined, + }, + identity: undefined, + card: undefined, + secureNote: undefined, + sshKey: undefined, + favorite: false, + reprompt: SdkCipherRepromptType.None, + organizationUseTotp: true, + edit: true, + permissions: undefined, + viewPassword: true, + localData: undefined, + 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.Linked, + linkedId: LoginLinkedIdType.Username, + }, + { + name: "EncryptedString", + value: "EncryptedString", + type: FieldType.Linked, + linkedId: LoginLinkedIdType.Password, + }, + ], + passwordHistory: [ + { + password: "EncryptedString", + lastUsedDate: "2022-01-31T12:00:00.000Z", + }, + ], + creationDate: "2022-01-01T12:00:00.000Z", + deletedDate: undefined, + revisionDate: "2022-01-31T12:00:00.000Z", + }); + }); + }); }); const mockUserId = "TestUserId" as UserId; diff --git a/libs/common/src/vault/models/domain/cipher.ts b/libs/common/src/vault/models/domain/cipher.ts index 21538b87788..4e912ebdf8c 100644 --- a/libs/common/src/vault/models/domain/cipher.ts +++ b/libs/common/src/vault/models/domain/cipher.ts @@ -2,6 +2,8 @@ // @ts-strict-ignore import { Jsonify } from "type-fest"; +import { Cipher as SdkCipher } from "@bitwarden/sdk-internal"; + import { Decryptable } from "../../../platform/interfaces/decryptable.interface"; import { Utils } from "../../../platform/misc/utils"; import Domain from "../../../platform/models/domain/domain-base"; @@ -332,4 +334,65 @@ export class Cipher extends Domain implements Decryptable { return domain; } + + /** + * Maps Cipher to SDK format. + * + * @returns {SdkCipher} The SDK cipher object. + */ + toSdkCipher(): SdkCipher { + const sdkCipher: SdkCipher = { + id: this.id, + organizationId: this.organizationId, + folderId: this.folderId, + collectionIds: this.collectionIds, + key: this.key?.toJSON(), + name: this.name.toJSON(), + notes: this.notes?.toJSON(), + type: this.type, + favorite: this.favorite, + organizationUseTotp: this.organizationUseTotp, + edit: this.edit, + permissions: undefined, + viewPassword: this.viewPassword, + localData: this.localData + ? { lastUsedDate: this.localData.lastUsedDate, lastLaunched: this.localData.lastLaunched } + : undefined, + attachments: this.attachments?.map((a) => a.toSdkAttachment()), + fields: this.fields?.map((f) => f.toSdkField()), + passwordHistory: this.passwordHistory?.map((ph) => ph.toSdkPasswordHistory()), + revisionDate: this.revisionDate?.toISOString(), + creationDate: this.creationDate?.toISOString(), + deletedDate: this.deletedDate?.toISOString(), + reprompt: this.reprompt, + // Initialize all cipher-type-specific properties as undefined + login: undefined, + identity: undefined, + card: undefined, + secureNote: undefined, + sshKey: undefined, + }; + + switch (this.type) { + case CipherType.Login: + sdkCipher.login = this.login.toSdkLogin(); + break; + case CipherType.SecureNote: + sdkCipher.secureNote = this.secureNote.toSdkSecureNote(); + break; + case CipherType.Card: + sdkCipher.card = this.card.toSdkCard(); + break; + case CipherType.Identity: + sdkCipher.identity = this.identity.toSdkIdentity(); + break; + case CipherType.SshKey: + sdkCipher.sshKey = this.sshKey.toSdkSshKey(); + break; + default: + break; + } + + return sdkCipher; + } } diff --git a/libs/common/src/vault/models/domain/fido2-credential.spec.ts b/libs/common/src/vault/models/domain/fido2-credential.spec.ts index e2cddcea3f3..bde29d0e99c 100644 --- a/libs/common/src/vault/models/domain/fido2-credential.spec.ts +++ b/libs/common/src/vault/models/domain/fido2-credential.spec.ts @@ -167,6 +167,45 @@ describe("Fido2Credential", () => { expect(Fido2Credential.fromJSON(null)).toBeNull(); }); }); + + describe("SDK Fido2Credential Mapping", () => { + it("should map to SDK Fido2Credential", () => { + const data: Fido2CredentialData = { + credentialId: "credentialId", + keyType: "public-key", + keyAlgorithm: "ECDSA", + keyCurve: "P-256", + keyValue: "keyValue", + rpId: "rpId", + userHandle: "userHandle", + userName: "userName", + counter: "2", + rpName: "rpName", + userDisplayName: "userDisplayName", + discoverable: "discoverable", + creationDate: mockDate.toISOString(), + }; + + const credential = new Fido2Credential(data); + const sdkCredential = credential.toSdkFido2Credential(); + + expect(sdkCredential).toEqual({ + credentialId: "credentialId", + keyType: "public-key", + keyAlgorithm: "ECDSA", + keyCurve: "P-256", + keyValue: "keyValue", + rpId: "rpId", + userHandle: "userHandle", + userName: "userName", + counter: "2", + rpName: "rpName", + userDisplayName: "userDisplayName", + discoverable: "discoverable", + creationDate: mockDate.toISOString(), + }); + }); + }); }); function createEncryptedEncString(s: string): EncString { diff --git a/libs/common/src/vault/models/domain/fido2-credential.ts b/libs/common/src/vault/models/domain/fido2-credential.ts index 9aa2c753d7c..de9de4056b5 100644 --- a/libs/common/src/vault/models/domain/fido2-credential.ts +++ b/libs/common/src/vault/models/domain/fido2-credential.ts @@ -2,6 +2,8 @@ // @ts-strict-ignore import { Jsonify } from "type-fest"; +import { Fido2Credential as SdkFido2Credential } from "@bitwarden/sdk-internal"; + import Domain from "../../../platform/models/domain/domain-base"; import { EncString } from "../../../platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; @@ -151,4 +153,27 @@ export class Fido2Credential extends Domain { creationDate, }); } + + /** + * Maps Fido2Credential to SDK format. + * + * @returns {SdkFido2Credential} The SDK Fido2Credential object. + */ + toSdkFido2Credential(): SdkFido2Credential { + return { + credentialId: this.credentialId?.toJSON(), + keyType: this.keyType.toJSON(), + keyAlgorithm: this.keyAlgorithm.toJSON(), + keyCurve: this.keyCurve.toJSON(), + keyValue: this.keyValue.toJSON(), + rpId: this.rpId.toJSON(), + userHandle: this.userHandle.toJSON(), + userName: this.userName.toJSON(), + counter: this.counter.toJSON(), + rpName: this.rpName?.toJSON(), + userDisplayName: this.userDisplayName?.toJSON(), + discoverable: this.discoverable?.toJSON(), + creationDate: this.creationDate.toISOString(), + }; + } } diff --git a/libs/common/src/vault/models/domain/field.spec.ts b/libs/common/src/vault/models/domain/field.spec.ts index 7dc5556e6cf..c0f9713f7ab 100644 --- a/libs/common/src/vault/models/domain/field.spec.ts +++ b/libs/common/src/vault/models/domain/field.spec.ts @@ -1,6 +1,6 @@ import { mockEnc, mockFromJson } from "../../../../spec"; import { EncryptedString, EncString } from "../../../platform/models/domain/enc-string"; -import { FieldType } from "../../enums"; +import { CardLinkedId, FieldType, IdentityLinkedId, LoginLinkedId } from "../../enums"; import { FieldData } from "../../models/data/field.data"; import { Field } from "../../models/domain/field"; @@ -82,4 +82,26 @@ describe("Field", () => { expect(Field.fromJSON(null)).toBeNull(); }); }); + + describe("SDK Field Mapping", () => { + it("should map to SDK Field", () => { + // Test Login LinkedId + const loginField = new Field(data); + loginField.type = FieldType.Linked; + loginField.linkedId = LoginLinkedId.Username; + expect(loginField.toSdkField().linkedId).toBe(100); + + // Test Card LinkedId + const cardField = new Field(data); + cardField.type = FieldType.Linked; + cardField.linkedId = CardLinkedId.Number; + expect(cardField.toSdkField().linkedId).toBe(305); + + // Test Identity LinkedId + const identityField = new Field(data); + identityField.type = FieldType.Linked; + identityField.linkedId = IdentityLinkedId.LicenseNumber; + expect(identityField.toSdkField().linkedId).toBe(415); + }); + }); }); diff --git a/libs/common/src/vault/models/domain/field.ts b/libs/common/src/vault/models/domain/field.ts index f836184da6a..4b20ba83fc8 100644 --- a/libs/common/src/vault/models/domain/field.ts +++ b/libs/common/src/vault/models/domain/field.ts @@ -2,6 +2,8 @@ // @ts-strict-ignore import { Jsonify } from "type-fest"; +import { Field as SdkField, LinkedIdType as SdkLinkedIdType } from "@bitwarden/sdk-internal"; + import Domain from "../../../platform/models/domain/domain-base"; import { EncString } from "../../../platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; @@ -75,4 +77,19 @@ export class Field extends Domain { value, }); } + + /** + * Maps Field to SDK format. + * + * @returns {SdkField} The SDK field object. + */ + toSdkField(): SdkField { + return { + name: this.name?.toJSON(), + value: this.value?.toJSON(), + type: this.type, + // Safe type cast: client and SDK LinkedIdType enums have identical values + linkedId: this.linkedId as unknown as SdkLinkedIdType, + }; + } } diff --git a/libs/common/src/vault/models/domain/identity.spec.ts b/libs/common/src/vault/models/domain/identity.spec.ts index 3a95138998b..cf296a6ff08 100644 --- a/libs/common/src/vault/models/domain/identity.spec.ts +++ b/libs/common/src/vault/models/domain/identity.spec.ts @@ -184,4 +184,32 @@ describe("Identity", () => { expect(Identity.fromJSON(null)).toBeNull(); }); }); + + describe("toSdkIdentity", () => { + it("returns the correct SDK Identity object", () => { + const identity = new Identity(data); + const sdkIdentity = identity.toSdkIdentity(); + + expect(sdkIdentity).toEqual({ + 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", + }); + }); + }); }); diff --git a/libs/common/src/vault/models/domain/identity.ts b/libs/common/src/vault/models/domain/identity.ts index 570e6c0b4d5..525230d9615 100644 --- a/libs/common/src/vault/models/domain/identity.ts +++ b/libs/common/src/vault/models/domain/identity.ts @@ -2,6 +2,8 @@ // @ts-strict-ignore import { Jsonify } from "type-fest"; +import { Identity as SdkIdentity } from "@bitwarden/sdk-internal"; + import Domain from "../../../platform/models/domain/domain-base"; import { EncString } from "../../../platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; @@ -164,4 +166,32 @@ export class Identity extends Domain { licenseNumber, }); } + + /** + * Maps Identity to SDK format. + * + * @returns {SdkIdentity} The SDK identity object. + */ + toSdkIdentity(): SdkIdentity { + return { + title: this.title?.toJSON(), + firstName: this.firstName?.toJSON(), + middleName: this.middleName?.toJSON(), + lastName: this.lastName?.toJSON(), + address1: this.address1?.toJSON(), + address2: this.address2?.toJSON(), + address3: this.address3?.toJSON(), + city: this.city?.toJSON(), + state: this.state?.toJSON(), + postalCode: this.postalCode?.toJSON(), + country: this.country?.toJSON(), + company: this.company?.toJSON(), + email: this.email?.toJSON(), + phone: this.phone?.toJSON(), + ssn: this.ssn?.toJSON(), + username: this.username?.toJSON(), + passportNumber: this.passportNumber?.toJSON(), + licenseNumber: this.licenseNumber?.toJSON(), + }; + } } diff --git a/libs/common/src/vault/models/domain/login-uri.spec.ts b/libs/common/src/vault/models/domain/login-uri.spec.ts index 6346f38f0de..a0e6b6d7dc9 100644 --- a/libs/common/src/vault/models/domain/login-uri.spec.ts +++ b/libs/common/src/vault/models/domain/login-uri.spec.ts @@ -1,6 +1,8 @@ import { MockProxy, mock } from "jest-mock-extended"; import { Jsonify } from "type-fest"; +import { UriMatchType } from "@bitwarden/sdk-internal"; + import { mockEnc, mockFromJson } from "../../../../spec"; import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; import { UriMatchStrategy } from "../../../models/domain/domain-service"; @@ -118,4 +120,17 @@ describe("LoginUri", () => { expect(LoginUri.fromJSON(null)).toBeNull(); }); }); + + describe("SDK Login Uri Mapping", () => { + it("should map to SDK login uri", () => { + const loginUri = new LoginUri(data); + const sdkLoginUri = loginUri.toSdkLoginUri(); + + expect(sdkLoginUri).toEqual({ + uri: "encUri", + uriChecksum: "encUriChecksum", + match: UriMatchType.Domain, + }); + }); + }); }); diff --git a/libs/common/src/vault/models/domain/login-uri.ts b/libs/common/src/vault/models/domain/login-uri.ts index 36782a81502..1aff5d33575 100644 --- a/libs/common/src/vault/models/domain/login-uri.ts +++ b/libs/common/src/vault/models/domain/login-uri.ts @@ -2,6 +2,8 @@ // @ts-strict-ignore import { Jsonify } from "type-fest"; +import { LoginUri as SdkLoginUri } from "@bitwarden/sdk-internal"; + import { UriMatchStrategySetting } from "../../../models/domain/domain-service"; import { Utils } from "../../../platform/misc/utils"; import Domain from "../../../platform/models/domain/domain-base"; @@ -88,4 +90,17 @@ export class LoginUri extends Domain { uriChecksum, }); } + + /** + * Maps LoginUri to SDK format. + * + * @returns {SdkLoginUri} The SDK login uri object. + */ + toSdkLoginUri(): SdkLoginUri { + return { + uri: this.uri.toJSON(), + uriChecksum: this.uriChecksum.toJSON(), + match: this.match, + }; + } } diff --git a/libs/common/src/vault/models/domain/login.spec.ts b/libs/common/src/vault/models/domain/login.spec.ts index 4f9e4546220..84d12e8131f 100644 --- a/libs/common/src/vault/models/domain/login.spec.ts +++ b/libs/common/src/vault/models/domain/login.spec.ts @@ -202,6 +202,54 @@ describe("Login DTO", () => { expect(Login.fromJSON(null)).toBeNull(); }); }); + + describe("toSdkLogin", () => { + it("should map to SDK login", () => { + const data: LoginData = { + uris: [{ uri: "uri", uriChecksum: "checksum", match: UriMatchStrategy.Domain }], + username: "username", + password: "password", + passwordRevisionDate: "2022-01-31T12:00:00.000Z", + totp: "123", + autofillOnPageLoad: false, + fido2Credentials: [initializeFido2Credential(new Fido2CredentialData())], + }; + const login = new Login(data); + const sdkLogin = login.toSdkLogin(); + + expect(sdkLogin).toEqual({ + username: "username", + password: "password", + passwordRevisionDate: "2022-01-31T12:00:00.000Z", + uris: [ + { + match: 0, + uri: "uri", + uriChecksum: "checksum", + }, + ], + totp: "123", + autofillOnPageLoad: false, + fido2Credentials: [ + { + credentialId: "credentialId", + keyType: "public-key", + keyAlgorithm: "ECDSA", + keyCurve: "P-256", + keyValue: "keyValue", + rpId: "rpId", + userHandle: "userHandle", + userName: "userName", + counter: "counter", + rpName: "rpName", + userDisplayName: "userDisplayName", + discoverable: "discoverable", + creationDate: "2023-01-01T12:00:00.000Z", + }, + ], + }); + }); + }); }); type Fido2CredentialLike = Fido2CredentialData | Fido2CredentialView | Fido2CredentialApi; diff --git a/libs/common/src/vault/models/domain/login.ts b/libs/common/src/vault/models/domain/login.ts index f9a85cd818e..c44b6708895 100644 --- a/libs/common/src/vault/models/domain/login.ts +++ b/libs/common/src/vault/models/domain/login.ts @@ -2,6 +2,8 @@ // @ts-strict-ignore import { Jsonify } from "type-fest"; +import { Login as SdkLogin } from "@bitwarden/sdk-internal"; + import Domain from "../../../platform/models/domain/domain-base"; import { EncString } from "../../../platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; @@ -147,4 +149,21 @@ export class Login extends Domain { fido2Credentials, }); } + + /** + * Maps Login to SDK format. + * + * @returns {SdkLogin} The SDK login object. + */ + toSdkLogin(): SdkLogin { + return { + uris: this.uris?.map((u) => u.toSdkLoginUri()), + username: this.username?.toJSON(), + password: this.password?.toJSON(), + passwordRevisionDate: this.passwordRevisionDate?.toISOString(), + totp: this.totp?.toJSON(), + autofillOnPageLoad: this.autofillOnPageLoad, + fido2Credentials: this.fido2Credentials?.map((f) => f.toSdkFido2Credential()), + }; + } } diff --git a/libs/common/src/vault/models/domain/password.spec.ts b/libs/common/src/vault/models/domain/password.spec.ts index 614b9639e52..24163cccf36 100644 --- a/libs/common/src/vault/models/domain/password.spec.ts +++ b/libs/common/src/vault/models/domain/password.spec.ts @@ -70,4 +70,17 @@ describe("Password", () => { expect(Password.fromJSON(null)).toBeNull(); }); }); + + describe("toSdkPasswordHistory", () => { + it("returns the correct SDK PasswordHistory object", () => { + const password = new Password(data); + + const sdkPasswordHistory = password.toSdkPasswordHistory(); + + expect(sdkPasswordHistory).toEqual({ + password: "encPassword", + lastUsedDate: new Date("2022-01-31T12:00:00.000Z").toISOString(), + }); + }); + }); }); diff --git a/libs/common/src/vault/models/domain/password.ts b/libs/common/src/vault/models/domain/password.ts index 48063f495f0..49ae351ed34 100644 --- a/libs/common/src/vault/models/domain/password.ts +++ b/libs/common/src/vault/models/domain/password.ts @@ -2,6 +2,8 @@ // @ts-strict-ignore import { Jsonify } from "type-fest"; +import { PasswordHistory } from "@bitwarden/sdk-internal"; + import Domain from "../../../platform/models/domain/domain-base"; import { EncString } from "../../../platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; @@ -58,4 +60,16 @@ export class Password extends Domain { lastUsedDate, }); } + + /** + * Maps Password to SDK format. + * + * @returns {PasswordHistory} The SDK password history object. + */ + toSdkPasswordHistory(): PasswordHistory { + return { + password: this.password.toJSON(), + lastUsedDate: this.lastUsedDate.toISOString(), + }; + } } diff --git a/libs/common/src/vault/models/domain/secure-note.spec.ts b/libs/common/src/vault/models/domain/secure-note.spec.ts index 719cf59f136..ff71e53238d 100644 --- a/libs/common/src/vault/models/domain/secure-note.spec.ts +++ b/libs/common/src/vault/models/domain/secure-note.spec.ts @@ -50,4 +50,17 @@ describe("SecureNote", () => { expect(SecureNote.fromJSON(null)).toBeNull(); }); }); + + describe("toSdkSecureNote", () => { + it("returns the correct SDK SecureNote object", () => { + const secureNote = new SecureNote(); + secureNote.type = SecureNoteType.Generic; + + const sdkSecureNote = secureNote.toSdkSecureNote(); + + expect(sdkSecureNote).toEqual({ + type: 0, + }); + }); + }); }); diff --git a/libs/common/src/vault/models/domain/secure-note.ts b/libs/common/src/vault/models/domain/secure-note.ts index 693ae38d9fb..ac7977b0e46 100644 --- a/libs/common/src/vault/models/domain/secure-note.ts +++ b/libs/common/src/vault/models/domain/secure-note.ts @@ -2,6 +2,8 @@ // @ts-strict-ignore import { Jsonify } from "type-fest"; +import { SecureNote as SdkSecureNote } from "@bitwarden/sdk-internal"; + import Domain from "../../../platform/models/domain/domain-base"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; import { SecureNoteType } from "../../enums"; @@ -41,4 +43,15 @@ export class SecureNote extends Domain { return Object.assign(new SecureNote(), obj); } + + /** + * Maps Secure note to SDK format. + * + * @returns {SdkSecureNote} The SDK secure note object. + */ + toSdkSecureNote(): SdkSecureNote { + return { + type: this.type, + }; + } } diff --git a/libs/common/src/vault/models/domain/ssh-key.spec.ts b/libs/common/src/vault/models/domain/ssh-key.spec.ts index f56d738fde8..6576d1a41e9 100644 --- a/libs/common/src/vault/models/domain/ssh-key.spec.ts +++ b/libs/common/src/vault/models/domain/ssh-key.spec.ts @@ -64,4 +64,17 @@ describe("Sshkey", () => { expect(SshKey.fromJSON(null)).toBeNull(); }); }); + + describe("toSdkSshKey", () => { + it("returns the correct SDK SshKey object", () => { + const sshKey = new SshKey(data); + const sdkSshKey = sshKey.toSdkSshKey(); + + expect(sdkSshKey).toEqual({ + privateKey: "privateKey", + publicKey: "publicKey", + fingerprint: "keyFingerprint", + }); + }); + }); }); diff --git a/libs/common/src/vault/models/domain/ssh-key.ts b/libs/common/src/vault/models/domain/ssh-key.ts index b4df172e543..f5bc7abc33f 100644 --- a/libs/common/src/vault/models/domain/ssh-key.ts +++ b/libs/common/src/vault/models/domain/ssh-key.ts @@ -2,6 +2,8 @@ // @ts-strict-ignore import { Jsonify } from "type-fest"; +import { SshKey as SdkSshKey } from "@bitwarden/sdk-internal"; + import Domain from "../../../platform/models/domain/domain-base"; import { EncString } from "../../../platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; @@ -73,4 +75,17 @@ export class SshKey extends Domain { keyFingerprint, }); } + + /** + * Maps SSH key to SDK format. + * + * @returns {SdkSshKey} The SDK SSH key object. + */ + toSdkSshKey(): SdkSshKey { + return { + privateKey: this.privateKey.toJSON(), + publicKey: this.publicKey.toJSON(), + fingerprint: this.keyFingerprint.toJSON(), + }; + } }