mirror of
https://github.com/bitwarden/browser
synced 2025-12-06 00:13:28 +00:00
[PM-25820] - Migrate cipher data model to adhere to ts-strict (#17073)
* Migrate cipher data model to adhere to ts-strict & added unit tests where applicable
This commit is contained in:
@@ -1,14 +1,12 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { AttachmentResponse } from "../response/attachment.response";
|
||||
|
||||
export class AttachmentData {
|
||||
id: string;
|
||||
url: string;
|
||||
fileName: string;
|
||||
key: string;
|
||||
size: string;
|
||||
sizeName: string;
|
||||
id?: string;
|
||||
url?: string;
|
||||
fileName?: string;
|
||||
key?: string;
|
||||
size?: string;
|
||||
sizeName?: string;
|
||||
|
||||
constructor(response?: AttachmentResponse) {
|
||||
if (response == null) {
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { CardApi } from "../api/card.api";
|
||||
|
||||
export class CardData {
|
||||
cardholderName: string;
|
||||
brand: string;
|
||||
number: string;
|
||||
expMonth: string;
|
||||
expYear: string;
|
||||
code: string;
|
||||
cardholderName?: string;
|
||||
brand?: string;
|
||||
number?: string;
|
||||
expMonth?: string;
|
||||
expYear?: string;
|
||||
code?: string;
|
||||
|
||||
constructor(data?: CardApi) {
|
||||
if (data == null) {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Jsonify } from "type-fest";
|
||||
|
||||
import { CipherRepromptType } from "../../enums/cipher-reprompt-type";
|
||||
@@ -17,18 +15,18 @@ import { SecureNoteData } from "./secure-note.data";
|
||||
import { SshKeyData } from "./ssh-key.data";
|
||||
|
||||
export class CipherData {
|
||||
id: string;
|
||||
organizationId: string;
|
||||
folderId: string;
|
||||
edit: boolean;
|
||||
viewPassword: boolean;
|
||||
permissions: CipherPermissionsApi;
|
||||
organizationUseTotp: boolean;
|
||||
favorite: boolean;
|
||||
id: string = "";
|
||||
organizationId?: string;
|
||||
folderId?: string;
|
||||
edit: boolean = false;
|
||||
viewPassword: boolean = true;
|
||||
permissions?: CipherPermissionsApi;
|
||||
organizationUseTotp: boolean = false;
|
||||
favorite: boolean = false;
|
||||
revisionDate: string;
|
||||
type: CipherType;
|
||||
name: string;
|
||||
notes: string;
|
||||
type: CipherType = CipherType.Login;
|
||||
name: string = "";
|
||||
notes?: string;
|
||||
login?: LoginData;
|
||||
secureNote?: SecureNoteData;
|
||||
card?: CardData;
|
||||
@@ -39,13 +37,14 @@ export class CipherData {
|
||||
passwordHistory?: PasswordHistoryData[];
|
||||
collectionIds?: string[];
|
||||
creationDate: string;
|
||||
deletedDate: string | undefined;
|
||||
archivedDate: string | undefined;
|
||||
reprompt: CipherRepromptType;
|
||||
key: string;
|
||||
deletedDate?: string;
|
||||
archivedDate?: string;
|
||||
reprompt: CipherRepromptType = CipherRepromptType.None;
|
||||
key?: string;
|
||||
|
||||
constructor(response?: CipherResponse, collectionIds?: string[]) {
|
||||
if (response == null) {
|
||||
this.creationDate = this.revisionDate = new Date().toISOString();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -101,7 +100,9 @@ export class CipherData {
|
||||
|
||||
static fromJSON(obj: Jsonify<CipherData>) {
|
||||
const result = Object.assign(new CipherData(), obj);
|
||||
result.permissions = CipherPermissionsApi.fromJSON(obj.permissions);
|
||||
if (obj.permissions != null) {
|
||||
result.permissions = CipherPermissionsApi.fromJSON(obj.permissions);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Fido2CredentialApi } from "../api/fido2-credential.api";
|
||||
|
||||
export class Fido2CredentialData {
|
||||
credentialId: string;
|
||||
keyType: "public-key";
|
||||
keyAlgorithm: "ECDSA";
|
||||
keyCurve: "P-256";
|
||||
keyValue: string;
|
||||
rpId: string;
|
||||
userHandle: string;
|
||||
userName: string;
|
||||
counter: string;
|
||||
rpName: string;
|
||||
userDisplayName: string;
|
||||
discoverable: string;
|
||||
creationDate: string;
|
||||
credentialId!: string;
|
||||
keyType!: string;
|
||||
keyAlgorithm!: string;
|
||||
keyCurve!: string;
|
||||
keyValue!: string;
|
||||
rpId!: string;
|
||||
userHandle?: string;
|
||||
userName?: string;
|
||||
counter!: string;
|
||||
rpName?: string;
|
||||
userDisplayName?: string;
|
||||
discoverable!: string;
|
||||
creationDate!: string;
|
||||
|
||||
constructor(data?: Fido2CredentialApi) {
|
||||
if (data == null) {
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { FieldType, LinkedIdType } from "../../enums";
|
||||
import { FieldApi } from "../api/field.api";
|
||||
|
||||
export class FieldData {
|
||||
type: FieldType;
|
||||
name: string;
|
||||
value: string;
|
||||
linkedId: LinkedIdType | null;
|
||||
type: FieldType = FieldType.Text;
|
||||
name?: string;
|
||||
value?: string;
|
||||
linkedId?: LinkedIdType;
|
||||
|
||||
constructor(response?: FieldApi) {
|
||||
if (response == null) {
|
||||
|
||||
@@ -1,26 +1,24 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { IdentityApi } from "../api/identity.api";
|
||||
|
||||
export class IdentityData {
|
||||
title: string;
|
||||
firstName: string;
|
||||
middleName: string;
|
||||
lastName: string;
|
||||
address1: string;
|
||||
address2: string;
|
||||
address3: string;
|
||||
city: string;
|
||||
state: string;
|
||||
postalCode: string;
|
||||
country: string;
|
||||
company: string;
|
||||
email: string;
|
||||
phone: string;
|
||||
ssn: string;
|
||||
username: string;
|
||||
passportNumber: string;
|
||||
licenseNumber: string;
|
||||
title?: string;
|
||||
firstName?: string;
|
||||
middleName?: string;
|
||||
lastName?: string;
|
||||
address1?: string;
|
||||
address2?: string;
|
||||
address3?: string;
|
||||
city?: string;
|
||||
state?: string;
|
||||
postalCode?: string;
|
||||
country?: string;
|
||||
company?: string;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
ssn?: string;
|
||||
username?: string;
|
||||
passportNumber?: string;
|
||||
licenseNumber?: string;
|
||||
|
||||
constructor(data?: IdentityApi) {
|
||||
if (data == null) {
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { UriMatchStrategySetting } from "../../../models/domain/domain-service";
|
||||
import { LoginUriApi } from "../api/login-uri.api";
|
||||
|
||||
export class LoginUriData {
|
||||
uri: string;
|
||||
uriChecksum: string;
|
||||
match: UriMatchStrategySetting = null;
|
||||
uri?: string;
|
||||
uriChecksum?: string;
|
||||
match?: UriMatchStrategySetting;
|
||||
|
||||
constructor(data?: LoginUriApi) {
|
||||
if (data == null) {
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { LoginApi } from "../api/login.api";
|
||||
|
||||
import { Fido2CredentialData } from "./fido2-credential.data";
|
||||
import { LoginUriData } from "./login-uri.data";
|
||||
|
||||
export class LoginData {
|
||||
uris: LoginUriData[];
|
||||
username: string;
|
||||
password: string;
|
||||
passwordRevisionDate: string;
|
||||
totp: string;
|
||||
autofillOnPageLoad: boolean;
|
||||
uris?: LoginUriData[];
|
||||
username?: string;
|
||||
password?: string;
|
||||
passwordRevisionDate?: string;
|
||||
totp?: string;
|
||||
autofillOnPageLoad?: boolean;
|
||||
fido2Credentials?: Fido2CredentialData[];
|
||||
|
||||
constructor(data?: LoginApi) {
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { PasswordHistoryResponse } from "../response/password-history.response";
|
||||
|
||||
export class PasswordHistoryData {
|
||||
password: string;
|
||||
lastUsedDate: string;
|
||||
password!: string;
|
||||
lastUsedDate!: string;
|
||||
|
||||
constructor(response?: PasswordHistoryResponse) {
|
||||
if (response == null) {
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { SecureNoteType } from "../../enums";
|
||||
import { SecureNoteApi } from "../api/secure-note.api";
|
||||
|
||||
export class SecureNoteData {
|
||||
type: SecureNoteType;
|
||||
type: SecureNoteType = SecureNoteType.Generic;
|
||||
|
||||
constructor(data?: SecureNoteApi) {
|
||||
if (data == null) {
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { SshKeyApi } from "../api/ssh-key.api";
|
||||
|
||||
export class SshKeyData {
|
||||
privateKey: string;
|
||||
publicKey: string;
|
||||
keyFingerprint: string;
|
||||
privateKey!: string;
|
||||
publicKey!: string;
|
||||
keyFingerprint!: string;
|
||||
|
||||
constructor(data?: SshKeyApi) {
|
||||
if (data == null) {
|
||||
|
||||
@@ -39,6 +39,12 @@ describe("Attachment", () => {
|
||||
key: undefined,
|
||||
fileName: undefined,
|
||||
});
|
||||
expect(data.id).toBeUndefined();
|
||||
expect(data.url).toBeUndefined();
|
||||
expect(data.fileName).toBeUndefined();
|
||||
expect(data.key).toBeUndefined();
|
||||
expect(data.size).toBeUndefined();
|
||||
expect(data.sizeName).toBeUndefined();
|
||||
});
|
||||
|
||||
it("Convert", () => {
|
||||
|
||||
@@ -29,6 +29,13 @@ describe("Card", () => {
|
||||
expYear: undefined,
|
||||
code: undefined,
|
||||
});
|
||||
|
||||
expect(data.cardholderName).toBeUndefined();
|
||||
expect(data.brand).toBeUndefined();
|
||||
expect(data.number).toBeUndefined();
|
||||
expect(data.expMonth).toBeUndefined();
|
||||
expect(data.expYear).toBeUndefined();
|
||||
expect(data.code).toBeUndefined();
|
||||
});
|
||||
|
||||
it("Convert", () => {
|
||||
|
||||
@@ -44,22 +44,22 @@ describe("Cipher DTO", () => {
|
||||
const data = new CipherData();
|
||||
const cipher = new Cipher(data);
|
||||
|
||||
expect(cipher.id).toBeUndefined();
|
||||
expect(cipher.id).toEqual("");
|
||||
expect(cipher.organizationId).toBeUndefined();
|
||||
expect(cipher.folderId).toBeUndefined();
|
||||
expect(cipher.name).toBeInstanceOf(EncString);
|
||||
expect(cipher.notes).toBeUndefined();
|
||||
expect(cipher.type).toBeUndefined();
|
||||
expect(cipher.favorite).toBeUndefined();
|
||||
expect(cipher.organizationUseTotp).toBeUndefined();
|
||||
expect(cipher.edit).toBeUndefined();
|
||||
expect(cipher.viewPassword).toBeUndefined();
|
||||
expect(cipher.type).toEqual(CipherType.Login);
|
||||
expect(cipher.favorite).toEqual(false);
|
||||
expect(cipher.organizationUseTotp).toEqual(false);
|
||||
expect(cipher.edit).toEqual(false);
|
||||
expect(cipher.viewPassword).toEqual(true);
|
||||
expect(cipher.revisionDate).toBeInstanceOf(Date);
|
||||
expect(cipher.collectionIds).toEqual([]);
|
||||
expect(cipher.localData).toBeUndefined();
|
||||
expect(cipher.creationDate).toBeInstanceOf(Date);
|
||||
expect(cipher.deletedDate).toBeUndefined();
|
||||
expect(cipher.reprompt).toBeUndefined();
|
||||
expect(cipher.reprompt).toEqual(CipherRepromptType.None);
|
||||
expect(cipher.attachments).toBeUndefined();
|
||||
expect(cipher.fields).toBeUndefined();
|
||||
expect(cipher.passwordHistory).toBeUndefined();
|
||||
@@ -836,6 +836,38 @@ describe("Cipher DTO", () => {
|
||||
expect(actual).toBeInstanceOf(Cipher);
|
||||
});
|
||||
|
||||
it("handles null permissions correctly without calling CipherPermissionsApi constructor", () => {
|
||||
const spy = jest.spyOn(CipherPermissionsApi.prototype, "constructor" as any);
|
||||
const revisionDate = new Date("2022-08-04T01:06:40.441Z");
|
||||
const actual = Cipher.fromJSON({
|
||||
name: "myName",
|
||||
revisionDate: revisionDate.toISOString(),
|
||||
permissions: null,
|
||||
} as Jsonify<Cipher>);
|
||||
|
||||
expect(actual.permissions).toBeUndefined();
|
||||
expect(actual).toBeInstanceOf(Cipher);
|
||||
// Verify that CipherPermissionsApi constructor was not called for null permissions
|
||||
expect(spy).not.toHaveBeenCalledWith(null);
|
||||
spy.mockRestore();
|
||||
});
|
||||
|
||||
it("calls CipherPermissionsApi constructor when permissions are provided", () => {
|
||||
const spy = jest.spyOn(CipherPermissionsApi.prototype, "constructor" as any);
|
||||
const revisionDate = new Date("2022-08-04T01:06:40.441Z");
|
||||
const permissionsObj = { delete: true, restore: false };
|
||||
const actual = Cipher.fromJSON({
|
||||
name: "myName",
|
||||
revisionDate: revisionDate.toISOString(),
|
||||
permissions: permissionsObj,
|
||||
} as Jsonify<Cipher>);
|
||||
|
||||
expect(actual.permissions).toBeInstanceOf(CipherPermissionsApi);
|
||||
expect(actual.permissions.delete).toBe(true);
|
||||
expect(actual.permissions.restore).toBe(false);
|
||||
spy.mockRestore();
|
||||
});
|
||||
|
||||
test.each([
|
||||
// Test description, CipherType, expected output
|
||||
["LoginView", CipherType.Login, { login: "myLogin_fromJSON" }],
|
||||
|
||||
@@ -29,7 +29,7 @@ describe("Field", () => {
|
||||
const field = new Field(data);
|
||||
|
||||
expect(field).toEqual({
|
||||
type: undefined,
|
||||
type: FieldType.Text,
|
||||
name: undefined,
|
||||
value: undefined,
|
||||
linkedId: undefined,
|
||||
|
||||
@@ -53,6 +53,27 @@ describe("Identity", () => {
|
||||
title: undefined,
|
||||
username: undefined,
|
||||
});
|
||||
|
||||
expect(data).toEqual({
|
||||
title: undefined,
|
||||
firstName: undefined,
|
||||
middleName: undefined,
|
||||
lastName: undefined,
|
||||
address1: undefined,
|
||||
address2: undefined,
|
||||
address3: undefined,
|
||||
city: undefined,
|
||||
state: undefined,
|
||||
postalCode: undefined,
|
||||
country: undefined,
|
||||
company: undefined,
|
||||
email: undefined,
|
||||
phone: undefined,
|
||||
ssn: undefined,
|
||||
username: undefined,
|
||||
passportNumber: undefined,
|
||||
licenseNumber: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it("Convert", () => {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { mockEnc, mockFromJson } from "../../../../spec";
|
||||
import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service";
|
||||
import { EncString } from "../../../key-management/crypto/models/enc-string";
|
||||
import { UriMatchStrategy } from "../../../models/domain/domain-service";
|
||||
import { LoginUriApi } from "../api/login-uri.api";
|
||||
import { LoginUriData } from "../data/login-uri.data";
|
||||
|
||||
import { LoginUri } from "./login-uri";
|
||||
@@ -31,6 +32,9 @@ describe("LoginUri", () => {
|
||||
uri: undefined,
|
||||
uriChecksum: undefined,
|
||||
});
|
||||
expect(data.uri).toBeUndefined();
|
||||
expect(data.uriChecksum).toBeUndefined();
|
||||
expect(data.match).toBeUndefined();
|
||||
});
|
||||
|
||||
it("Convert", () => {
|
||||
@@ -61,6 +65,23 @@ describe("LoginUri", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("handle null match", () => {
|
||||
const apiData = Object.assign(new LoginUriApi(), {
|
||||
uri: "testUri",
|
||||
uriChecksum: "testChecksum",
|
||||
match: null,
|
||||
});
|
||||
|
||||
const loginUriData = new LoginUriData(apiData);
|
||||
|
||||
// The data model stores it as-is (null or undefined)
|
||||
expect(loginUriData.match).toBeNull();
|
||||
|
||||
// But the domain model converts null to undefined
|
||||
const loginUri = new LoginUri(loginUriData);
|
||||
expect(loginUri.match).toBeUndefined();
|
||||
});
|
||||
|
||||
describe("validateChecksum", () => {
|
||||
let encryptService: MockProxy<EncryptService>;
|
||||
|
||||
@@ -118,7 +139,7 @@ describe("LoginUri", () => {
|
||||
});
|
||||
|
||||
describe("SDK Login Uri Mapping", () => {
|
||||
it("should map to SDK login uri", () => {
|
||||
it("maps to SDK login uri", () => {
|
||||
const loginUri = new LoginUri(data);
|
||||
const sdkLoginUri = loginUri.toSdkLoginUri();
|
||||
|
||||
|
||||
@@ -25,6 +25,14 @@ describe("Login DTO", () => {
|
||||
password: undefined,
|
||||
totp: undefined,
|
||||
});
|
||||
|
||||
expect(data.username).toBeUndefined();
|
||||
expect(data.password).toBeUndefined();
|
||||
expect(data.passwordRevisionDate).toBeUndefined();
|
||||
expect(data.totp).toBeUndefined();
|
||||
expect(data.autofillOnPageLoad).toBeUndefined();
|
||||
expect(data.uris).toBeUndefined();
|
||||
expect(data.fido2Credentials).toBeUndefined();
|
||||
});
|
||||
|
||||
it("Convert from full LoginData", () => {
|
||||
|
||||
@@ -111,10 +111,7 @@ export class Login extends Domain {
|
||||
});
|
||||
|
||||
if (this.uris != null && this.uris.length > 0) {
|
||||
l.uris = [];
|
||||
this.uris.forEach((u) => {
|
||||
l.uris.push(u.toLoginUriData());
|
||||
});
|
||||
l.uris = this.uris.map((u) => u.toLoginUriData());
|
||||
}
|
||||
|
||||
if (this.fido2Credentials != null && this.fido2Credentials.length > 0) {
|
||||
|
||||
@@ -20,6 +20,9 @@ describe("Password", () => {
|
||||
expect(password).toBeInstanceOf(Password);
|
||||
expect(password.password).toBeInstanceOf(EncString);
|
||||
expect(password.lastUsedDate).toBeInstanceOf(Date);
|
||||
|
||||
expect(data.password).toBeUndefined();
|
||||
expect(data.lastUsedDate).toBeUndefined();
|
||||
});
|
||||
|
||||
it("Convert", () => {
|
||||
@@ -83,4 +86,47 @@ describe("Password", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("fromSdkPasswordHistory", () => {
|
||||
beforeEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("creates Password from SDK object", () => {
|
||||
const sdkPasswordHistory = {
|
||||
password: "2.encPassword|encryptedData" as EncryptedString,
|
||||
lastUsedDate: "2022-01-31T12:00:00.000Z",
|
||||
};
|
||||
|
||||
const password = Password.fromSdkPasswordHistory(sdkPasswordHistory);
|
||||
|
||||
expect(password).toBeInstanceOf(Password);
|
||||
expect(password?.password).toBeInstanceOf(EncString);
|
||||
expect(password?.password.encryptedString).toBe("2.encPassword|encryptedData");
|
||||
expect(password?.lastUsedDate).toEqual(new Date("2022-01-31T12:00:00.000Z"));
|
||||
});
|
||||
|
||||
it("returns undefined for null input", () => {
|
||||
const result = Password.fromSdkPasswordHistory(null as any);
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it("returns undefined for undefined input", () => {
|
||||
const result = Password.fromSdkPasswordHistory(undefined);
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it("handles empty SDK object", () => {
|
||||
const sdkPasswordHistory = {
|
||||
password: "" as EncryptedString,
|
||||
lastUsedDate: "",
|
||||
};
|
||||
|
||||
const password = Password.fromSdkPasswordHistory(sdkPasswordHistory);
|
||||
|
||||
expect(password).toBeInstanceOf(Password);
|
||||
expect(password?.password).toBeInstanceOf(EncString);
|
||||
expect(password?.lastUsedDate).toBeInstanceOf(Date);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,22 +16,27 @@ describe("SecureNote", () => {
|
||||
const data = new SecureNoteData();
|
||||
const secureNote = new SecureNote(data);
|
||||
|
||||
expect(secureNote).toEqual({
|
||||
type: undefined,
|
||||
});
|
||||
expect(data).toBeDefined();
|
||||
expect(secureNote).toEqual({ type: SecureNoteType.Generic });
|
||||
expect(data.type).toBe(SecureNoteType.Generic);
|
||||
});
|
||||
|
||||
it("Convert from undefined", () => {
|
||||
const data = new SecureNoteData(undefined);
|
||||
expect(data.type).toBe(SecureNoteType.Generic);
|
||||
});
|
||||
|
||||
it("Convert", () => {
|
||||
const secureNote = new SecureNote(data);
|
||||
|
||||
expect(secureNote).toEqual({
|
||||
type: 0,
|
||||
});
|
||||
expect(secureNote).toEqual({ type: 0 });
|
||||
expect(data.type).toBe(SecureNoteType.Generic);
|
||||
});
|
||||
|
||||
it("toSecureNoteData", () => {
|
||||
const secureNote = new SecureNote(data);
|
||||
expect(secureNote.toSecureNoteData()).toEqual(data);
|
||||
expect(secureNote.toSecureNoteData().type).toBe(SecureNoteType.Generic);
|
||||
});
|
||||
|
||||
it("Decrypt", async () => {
|
||||
@@ -49,6 +54,14 @@ describe("SecureNote", () => {
|
||||
it("returns undefined if object is null", () => {
|
||||
expect(SecureNote.fromJSON(null)).toBeUndefined();
|
||||
});
|
||||
|
||||
it("creates SecureNote instance from JSON object", () => {
|
||||
const jsonObj = { type: SecureNoteType.Generic };
|
||||
const result = SecureNote.fromJSON(jsonObj);
|
||||
|
||||
expect(result).toBeInstanceOf(SecureNote);
|
||||
expect(result.type).toBe(SecureNoteType.Generic);
|
||||
});
|
||||
});
|
||||
|
||||
describe("toSdkSecureNote", () => {
|
||||
@@ -63,4 +76,71 @@ describe("SecureNote", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("fromSdkSecureNote", () => {
|
||||
it("returns undefined when null is provided", () => {
|
||||
const result = SecureNote.fromSdkSecureNote(null);
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it("returns undefined when undefined is provided", () => {
|
||||
const result = SecureNote.fromSdkSecureNote(undefined);
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it("creates SecureNote with Generic type from SDK object", () => {
|
||||
const sdkSecureNote = {
|
||||
type: SecureNoteType.Generic,
|
||||
};
|
||||
|
||||
const result = SecureNote.fromSdkSecureNote(sdkSecureNote);
|
||||
|
||||
expect(result).toBeInstanceOf(SecureNote);
|
||||
expect(result.type).toBe(SecureNoteType.Generic);
|
||||
});
|
||||
|
||||
it("preserves the type value from SDK object", () => {
|
||||
const sdkSecureNote = {
|
||||
type: SecureNoteType.Generic,
|
||||
};
|
||||
|
||||
const result = SecureNote.fromSdkSecureNote(sdkSecureNote);
|
||||
|
||||
expect(result.type).toBe(0);
|
||||
});
|
||||
|
||||
it("creates a new SecureNote instance", () => {
|
||||
const sdkSecureNote = {
|
||||
type: SecureNoteType.Generic,
|
||||
};
|
||||
|
||||
const result = SecureNote.fromSdkSecureNote(sdkSecureNote);
|
||||
|
||||
expect(result).not.toBe(sdkSecureNote);
|
||||
expect(result).toBeInstanceOf(SecureNote);
|
||||
});
|
||||
|
||||
it("handles SDK object with undefined type", () => {
|
||||
const sdkSecureNote = {
|
||||
type: undefined as SecureNoteType,
|
||||
};
|
||||
|
||||
const result = SecureNote.fromSdkSecureNote(sdkSecureNote);
|
||||
|
||||
expect(result).toBeInstanceOf(SecureNote);
|
||||
expect(result.type).toBeUndefined();
|
||||
});
|
||||
|
||||
it("returns symmetric with toSdkSecureNote", () => {
|
||||
const original = new SecureNote();
|
||||
original.type = SecureNoteType.Generic;
|
||||
|
||||
const sdkFormat = original.toSdkSecureNote();
|
||||
const reconstructed = SecureNote.fromSdkSecureNote(sdkFormat);
|
||||
|
||||
expect(reconstructed.type).toBe(original.type);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string";
|
||||
import { EncString as SdkEncString, SshKey as SdkSshKey } from "@bitwarden/sdk-internal";
|
||||
|
||||
import { mockEnc } from "../../../../spec";
|
||||
import { SshKeyApi } from "../api/ssh-key.api";
|
||||
@@ -37,6 +38,9 @@ describe("Sshkey", () => {
|
||||
expect(sshKey.privateKey).toBeInstanceOf(EncString);
|
||||
expect(sshKey.publicKey).toBeInstanceOf(EncString);
|
||||
expect(sshKey.keyFingerprint).toBeInstanceOf(EncString);
|
||||
expect(data.privateKey).toBeUndefined();
|
||||
expect(data.publicKey).toBeUndefined();
|
||||
expect(data.keyFingerprint).toBeUndefined();
|
||||
});
|
||||
|
||||
it("toSshKeyData", () => {
|
||||
@@ -64,6 +68,21 @@ describe("Sshkey", () => {
|
||||
it("returns undefined if object is null", () => {
|
||||
expect(SshKey.fromJSON(null)).toBeUndefined();
|
||||
});
|
||||
|
||||
it("creates SshKey instance from JSON object", () => {
|
||||
const jsonObj = {
|
||||
privateKey: "2.privateKey|encryptedData",
|
||||
publicKey: "2.publicKey|encryptedData",
|
||||
keyFingerprint: "2.keyFingerprint|encryptedData",
|
||||
};
|
||||
|
||||
const result = SshKey.fromJSON(jsonObj);
|
||||
|
||||
expect(result).toBeInstanceOf(SshKey);
|
||||
expect(result.privateKey).toBeDefined();
|
||||
expect(result.publicKey).toBeDefined();
|
||||
expect(result.keyFingerprint).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("toSdkSshKey", () => {
|
||||
@@ -78,4 +97,58 @@ describe("Sshkey", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("fromSdkSshKey", () => {
|
||||
it("returns undefined when null is provided", () => {
|
||||
const result = SshKey.fromSdkSshKey(null);
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it("returns undefined when undefined is provided", () => {
|
||||
const result = SshKey.fromSdkSshKey(undefined);
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it("creates SshKey from SDK object", () => {
|
||||
const sdkSshKey: SdkSshKey = {
|
||||
privateKey: "2.privateKey|encryptedData" as SdkEncString,
|
||||
publicKey: "2.publicKey|encryptedData" as SdkEncString,
|
||||
fingerprint: "2.keyFingerprint|encryptedData" as SdkEncString,
|
||||
};
|
||||
|
||||
const result = SshKey.fromSdkSshKey(sdkSshKey);
|
||||
|
||||
expect(result).toBeInstanceOf(SshKey);
|
||||
expect(result.privateKey).toBeDefined();
|
||||
expect(result.publicKey).toBeDefined();
|
||||
expect(result.keyFingerprint).toBeDefined();
|
||||
});
|
||||
|
||||
it("creates a new SshKey instance", () => {
|
||||
const sdkSshKey: SdkSshKey = {
|
||||
privateKey: "2.privateKey|encryptedData" as SdkEncString,
|
||||
publicKey: "2.publicKey|encryptedData" as SdkEncString,
|
||||
fingerprint: "2.keyFingerprint|encryptedData" as SdkEncString,
|
||||
};
|
||||
|
||||
const result = SshKey.fromSdkSshKey(sdkSshKey);
|
||||
|
||||
expect(result).not.toBe(sdkSshKey);
|
||||
expect(result).toBeInstanceOf(SshKey);
|
||||
});
|
||||
|
||||
it("is symmetric with toSdkSshKey", () => {
|
||||
const original = new SshKey(data);
|
||||
const sdkFormat = original.toSdkSshKey();
|
||||
const reconstructed = SshKey.fromSdkSshKey(sdkFormat);
|
||||
|
||||
expect(reconstructed.privateKey.encryptedString).toBe(original.privateKey.encryptedString);
|
||||
expect(reconstructed.publicKey.encryptedString).toBe(original.publicKey.encryptedString);
|
||||
expect(reconstructed.keyFingerprint.encryptedString).toBe(
|
||||
original.keyFingerprint.encryptedString,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user