From 18bc209b7308c936c408f13072d85d3e27df8a97 Mon Sep 17 00:00:00 2001 From: David Frankel <42774874+frankeld@users.noreply.github.com> Date: Tue, 11 Oct 2022 21:25:27 -0400 Subject: [PATCH] [PS-1194] Display Creation Date in Clients (#3181) * Add CreationDate to common libs * Add CreationDate to Browser * Add CreationDate to CLI * Add CreationDate to Desktop * Add CreationDate to Web * Update tests Co-authored-by: Matt Gibson --- apps/browser/src/_locales/en/messages.json | 4 ++++ .../browser/src/popup/vault/view.component.html | 4 ++++ apps/cli/src/models/response/cipherResponse.ts | 4 ++++ apps/desktop/src/app/vault/view.component.html | 4 ++++ apps/desktop/src/locales/en/messages.json | 4 ++++ apps/web/src/app/vault/add-edit.component.html | 4 ++++ apps/web/src/locales/en/messages.json | 4 ++++ libs/common/spec/models/domain/cipher.spec.ts | 17 +++++++++++++++++ libs/common/src/models/data/cipherData.ts | 2 ++ libs/common/src/models/domain/cipher.ts | 3 +++ .../src/models/response/cipherResponse.ts | 2 ++ libs/common/src/models/view/cipherView.ts | 2 ++ 12 files changed, 54 insertions(+) diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index e6d8a6b748..7a320e409e 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -1311,6 +1311,10 @@ "message": "Updated", "description": "ex. Date this item was updated" }, + "dateCreated": { + "message": "Created", + "description": "ex. Date this item was created" + }, "datePasswordUpdated": { "message": "Password updated", "description": "ex. Date this password was updated" diff --git a/apps/browser/src/popup/vault/view.component.html b/apps/browser/src/popup/vault/view.component.html index 5fa5d2aba6..ac117afd39 100644 --- a/apps/browser/src/popup/vault/view.component.html +++ b/apps/browser/src/popup/vault/view.component.html @@ -622,6 +622,10 @@ {{ "dateUpdated" | i18n }}: {{ cipher.revisionDate | date: "medium" }} +
+ {{ "dateCreated" | i18n }}: + {{ cipher.creationDate | date: "medium" }} +
{{ "datePasswordUpdated" | i18n }}: {{ cipher.passwordRevisionDisplayDate | date: "medium" }} diff --git a/apps/cli/src/models/response/cipherResponse.ts b/apps/cli/src/models/response/cipherResponse.ts index a52084de77..9f44fbb38a 100644 --- a/apps/cli/src/models/response/cipherResponse.ts +++ b/apps/cli/src/models/response/cipherResponse.ts @@ -11,6 +11,7 @@ export class CipherResponse extends CipherWithIdExport implements BaseResponse { object: string; attachments: AttachmentResponse[]; revisionDate: Date; + creationDate: Date; deletedDate: Date; passwordHistory: PasswordHistoryResponse[]; @@ -22,6 +23,9 @@ export class CipherResponse extends CipherWithIdExport implements BaseResponse { this.attachments = o.attachments.map((a) => new AttachmentResponse(a)); } this.revisionDate = o.revisionDate; + if (o.creationDate != null) { + this.creationDate = o.creationDate; + } this.deletedDate = o.deletedDate; if (o.passwordHistory != null) { this.passwordHistory = o.passwordHistory.map((h) => new PasswordHistoryResponse(h)); diff --git a/apps/desktop/src/app/vault/view.component.html b/apps/desktop/src/app/vault/view.component.html index 69201a18d6..b25c947a93 100644 --- a/apps/desktop/src/app/vault/view.component.html +++ b/apps/desktop/src/app/vault/view.component.html @@ -475,6 +475,10 @@ {{ "dateUpdated" | i18n }}: {{ cipher.revisionDate | date: "medium" }}
+
+ {{ "dateCreated" | i18n }}: + {{ cipher.creationDate | date: "medium" }} +
{{ "datePasswordUpdated" | i18n }}: {{ cipher.passwordRevisionDisplayDate | date: "medium" }} diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index 2c0967fa27..b656c5b196 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -1266,6 +1266,10 @@ "message": "Updated", "description": "ex. Date this item was updated" }, + "dateCreated": { + "message": "Created", + "description": "ex. Date this item was created" + }, "datePasswordUpdated": { "message": "Password Updated", "description": "ex. Date this password was updated" diff --git a/apps/web/src/app/vault/add-edit.component.html b/apps/web/src/app/vault/add-edit.component.html index bec9064b81..e936ef7ba6 100644 --- a/apps/web/src/app/vault/add-edit.component.html +++ b/apps/web/src/app/vault/add-edit.component.html @@ -787,6 +787,10 @@ {{ "dateUpdated" | i18n }}: {{ cipher.revisionDate | date: "medium" }}
+
+ {{ "dateCreated" | i18n }}: + {{ cipher.creationDate | date: "medium" }} +
{{ "datePasswordUpdated" | i18n }}: {{ cipher.passwordRevisionDisplayDate | date: "medium" }} diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 755eb80b7a..58215711d5 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -3313,6 +3313,10 @@ "message": "Updated", "description": "ex. Date this item was updated" }, + "dateCreated": { + "message": "Created", + "description": "ex. Date this item was created" + }, "datePasswordUpdated": { "message": "Password Updated", "description": "ex. Date this password was updated" diff --git a/libs/common/spec/models/domain/cipher.spec.ts b/libs/common/spec/models/domain/cipher.spec.ts index 763e57bb4e..316a20e98f 100644 --- a/libs/common/spec/models/domain/cipher.spec.ts +++ b/libs/common/spec/models/domain/cipher.spec.ts @@ -42,6 +42,7 @@ describe("Cipher DTO", () => { revisionDate: null, collectionIds: undefined, localData: null, + creationDate: null, deletedDate: null, reprompt: undefined, attachments: null, @@ -66,6 +67,7 @@ describe("Cipher DTO", () => { type: CipherType.Login, name: "EncryptedString", notes: "EncryptedString", + creationDate: "2022-01-01T12:00:00.000Z", deletedDate: null, reprompt: CipherRepromptType.None, login: { @@ -131,6 +133,7 @@ describe("Cipher DTO", () => { revisionDate: new Date("2022-01-31T12:00:00.000Z"), collectionIds: undefined, localData: null, + creationDate: new Date("2022-01-01T12:00:00.000Z"), deletedDate: null, reprompt: 0, login: { @@ -200,6 +203,7 @@ describe("Cipher DTO", () => { cipher.type = CipherType.Login; cipher.name = mockEnc("EncryptedString"); cipher.notes = mockEnc("EncryptedString"); + cipher.creationDate = new Date("2022-01-01T12:00:00.000Z"); cipher.deletedDate = null; cipher.reprompt = CipherRepromptType.None; @@ -230,6 +234,7 @@ describe("Cipher DTO", () => { passwordHistory: null, collectionIds: undefined, revisionDate: new Date("2022-01-31T12:00:00.000Z"), + creationDate: new Date("2022-01-01T12:00:00.000Z"), deletedDate: null, reprompt: 0, localData: undefined, @@ -253,6 +258,7 @@ describe("Cipher DTO", () => { type: CipherType.SecureNote, name: "EncryptedString", notes: "EncryptedString", + creationDate: "2022-01-01T12:00:00.000Z", deletedDate: null, reprompt: CipherRepromptType.None, secureNote: { @@ -278,6 +284,7 @@ describe("Cipher DTO", () => { revisionDate: new Date("2022-01-31T12:00:00.000Z"), collectionIds: undefined, localData: null, + creationDate: new Date("2022-01-01T12:00:00.000Z"), deletedDate: null, reprompt: 0, secureNote: { type: SecureNoteType.Generic }, @@ -305,6 +312,7 @@ describe("Cipher DTO", () => { cipher.type = CipherType.SecureNote; cipher.name = mockEnc("EncryptedString"); cipher.notes = mockEnc("EncryptedString"); + cipher.creationDate = new Date("2022-01-01T12:00:00.000Z"); cipher.deletedDate = null; cipher.reprompt = CipherRepromptType.None; cipher.secureNote = new SecureNote(); @@ -329,6 +337,7 @@ describe("Cipher DTO", () => { passwordHistory: null, collectionIds: undefined, revisionDate: new Date("2022-01-31T12:00:00.000Z"), + creationDate: new Date("2022-01-01T12:00:00.000Z"), deletedDate: null, reprompt: 0, localData: undefined, @@ -352,6 +361,7 @@ describe("Cipher DTO", () => { type: CipherType.Card, name: "EncryptedString", notes: "EncryptedString", + creationDate: "2022-01-01T12:00:00.000Z", deletedDate: null, reprompt: CipherRepromptType.None, card: { @@ -382,6 +392,7 @@ describe("Cipher DTO", () => { revisionDate: new Date("2022-01-31T12:00:00.000Z"), collectionIds: undefined, localData: null, + creationDate: new Date("2022-01-01T12:00:00.000Z"), deletedDate: null, reprompt: 0, card: { @@ -416,6 +427,7 @@ describe("Cipher DTO", () => { cipher.type = CipherType.Card; cipher.name = mockEnc("EncryptedString"); cipher.notes = mockEnc("EncryptedString"); + cipher.creationDate = new Date("2022-01-01T12:00:00.000Z"); cipher.deletedDate = null; cipher.reprompt = CipherRepromptType.None; @@ -446,6 +458,7 @@ describe("Cipher DTO", () => { passwordHistory: null, collectionIds: undefined, revisionDate: new Date("2022-01-31T12:00:00.000Z"), + creationDate: new Date("2022-01-01T12:00:00.000Z"), deletedDate: null, reprompt: 0, localData: undefined, @@ -469,6 +482,7 @@ describe("Cipher DTO", () => { type: CipherType.Identity, name: "EncryptedString", notes: "EncryptedString", + creationDate: "2022-01-01T12:00:00.000Z", deletedDate: null, reprompt: CipherRepromptType.None, identity: { @@ -511,6 +525,7 @@ describe("Cipher DTO", () => { revisionDate: new Date("2022-01-31T12:00:00.000Z"), collectionIds: undefined, localData: null, + creationDate: new Date("2022-01-01T12:00:00.000Z"), deletedDate: null, reprompt: 0, identity: { @@ -557,6 +572,7 @@ describe("Cipher DTO", () => { cipher.type = CipherType.Identity; cipher.name = mockEnc("EncryptedString"); cipher.notes = mockEnc("EncryptedString"); + cipher.creationDate = new Date("2022-01-01T12:00:00.000Z"); cipher.deletedDate = null; cipher.reprompt = CipherRepromptType.None; @@ -587,6 +603,7 @@ describe("Cipher DTO", () => { passwordHistory: null, collectionIds: undefined, revisionDate: new Date("2022-01-31T12:00:00.000Z"), + creationDate: new Date("2022-01-01T12:00:00.000Z"), deletedDate: null, reprompt: 0, localData: undefined, diff --git a/libs/common/src/models/data/cipherData.ts b/libs/common/src/models/data/cipherData.ts index aa82a5fd0b..34815a6596 100644 --- a/libs/common/src/models/data/cipherData.ts +++ b/libs/common/src/models/data/cipherData.ts @@ -30,6 +30,7 @@ export class CipherData { attachments?: AttachmentData[]; passwordHistory?: PasswordHistoryData[]; collectionIds?: string[]; + creationDate: string; deletedDate: string; reprompt: CipherRepromptType; @@ -50,6 +51,7 @@ export class CipherData { this.name = response.name; this.notes = response.notes; this.collectionIds = collectionIds != null ? collectionIds : response.collectionIds; + this.creationDate = response.creationDate; this.deletedDate = response.deletedDate; this.reprompt = response.reprompt; diff --git a/libs/common/src/models/domain/cipher.ts b/libs/common/src/models/domain/cipher.ts index ca792926c0..e2c15a1208 100644 --- a/libs/common/src/models/domain/cipher.ts +++ b/libs/common/src/models/domain/cipher.ts @@ -38,6 +38,7 @@ export class Cipher extends Domain { fields: Field[]; passwordHistory: Password[]; collectionIds: string[]; + creationDate: Date; deletedDate: Date; reprompt: CipherRepromptType; @@ -72,6 +73,7 @@ export class Cipher extends Domain { this.revisionDate = obj.revisionDate != null ? new Date(obj.revisionDate) : null; this.collectionIds = obj.collectionIds; this.localData = localData; + this.creationDate = obj.creationDate != null ? new Date(obj.creationDate) : null; this.deletedDate = obj.deletedDate != null ? new Date(obj.deletedDate) : null; this.reprompt = obj.reprompt; @@ -200,6 +202,7 @@ export class Cipher extends Domain { c.revisionDate = this.revisionDate != null ? this.revisionDate.toISOString() : null; c.type = this.type; c.collectionIds = this.collectionIds; + c.creationDate = this.creationDate != null ? this.creationDate.toISOString() : null; c.deletedDate = this.deletedDate != null ? this.deletedDate.toISOString() : null; c.reprompt = this.reprompt; diff --git a/libs/common/src/models/response/cipherResponse.ts b/libs/common/src/models/response/cipherResponse.ts index 5b461438e9..8eba6f6273 100644 --- a/libs/common/src/models/response/cipherResponse.ts +++ b/libs/common/src/models/response/cipherResponse.ts @@ -29,6 +29,7 @@ export class CipherResponse extends BaseResponse { attachments: AttachmentResponse[]; passwordHistory: PasswordHistoryResponse[]; collectionIds: string[]; + creationDate: string; deletedDate: string; reprompt: CipherRepromptType; @@ -50,6 +51,7 @@ export class CipherResponse extends BaseResponse { this.organizationUseTotp = this.getResponseProperty("OrganizationUseTotp"); this.revisionDate = this.getResponseProperty("RevisionDate"); this.collectionIds = this.getResponseProperty("CollectionIds"); + this.creationDate = this.getResponseProperty("CreationDate"); this.deletedDate = this.getResponseProperty("DeletedDate"); const login = this.getResponseProperty("Login"); diff --git a/libs/common/src/models/view/cipherView.ts b/libs/common/src/models/view/cipherView.ts index 4181c11d35..a835fa16ae 100644 --- a/libs/common/src/models/view/cipherView.ts +++ b/libs/common/src/models/view/cipherView.ts @@ -36,6 +36,7 @@ export class CipherView implements View { passwordHistory: PasswordHistoryView[] = null; collectionIds: string[] = null; revisionDate: Date = null; + creationDate: Date = null; deletedDate: Date = null; reprompt: CipherRepromptType = CipherRepromptType.None; @@ -55,6 +56,7 @@ export class CipherView implements View { this.localData = c.localData; this.collectionIds = c.collectionIds; this.revisionDate = c.revisionDate; + this.creationDate = c.creationDate; this.deletedDate = c.deletedDate; // Old locally stored ciphers might have reprompt == null. If so set it to None. this.reprompt = c.reprompt ?? CipherRepromptType.None;