From eab6e7ce804fa1c3c5c30f47f6f6165e109d7ee8 Mon Sep 17 00:00:00 2001 From: Leslie Tilton <23057410+Banrion@users.noreply.github.com> Date: Fri, 6 Feb 2026 16:02:19 -0600 Subject: [PATCH] Update Risk Insights models to follow architecture (#17356) * Member details model updates * Add application model for risk insights reports following company architecture * Add summary model for risk insights reports following company architecture * Updated comment in risk insights summary data * Add models following company architecture for risk insights generated report data * Use deep jsonify for class json structure * Use deepjsonify for class partial json structure * Add risk insights model following client model architecture * Fix type check errors --- .../models/api/member-details.api.ts | 33 ++++++++++ .../api/risk-insights-application.api.ts | 32 +++++++++ .../models/api/risk-insights-report.api.ts | 53 +++++++++++++++ .../models/api/risk-insights-summary.api.ts | 42 ++++++++++++ .../models/api/risk-insights.api.ts | 56 ++++++++++++++++ .../models/data/member-details.data.ts | 30 +++++++++ .../data/risk-insights-application.data.ts | 29 +++++++++ .../models/data/risk-insights-report.data.ts | 48 ++++++++++++++ .../models/data/risk-insights-summary.data.ts | 38 +++++++++++ .../models/data/risk-insights.data.ts | 49 ++++++++++++++ .../models/domain/member-details.ts | 34 ++++++++++ .../domain/risk-insights-application.ts | 31 +++++++++ .../models/domain/risk-insights-report.ts | 59 +++++++++++++++++ .../models/domain/risk-insights-summary.ts | 50 ++++++++++++++ .../models/domain/risk-insights.ts | 49 ++++++++++++++ .../models/view/member-details.view.ts | 43 ++++++++++++ .../view/risk-insights-application.view.ts | 45 +++++++++++++ .../models/view/risk-insights-report.view.ts | 64 ++++++++++++++++++ .../models/view/risk-insights-summary.view.ts | 53 +++++++++++++++ .../models/view/risk-insights.view.ts | 65 +++++++++++++++++++ 20 files changed, 903 insertions(+) create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/member-details.api.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/risk-insights-application.api.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/risk-insights-report.api.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/risk-insights-summary.api.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/risk-insights.api.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/member-details.data.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/risk-insights-application.data.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/risk-insights-report.data.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/risk-insights-summary.data.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/risk-insights.data.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/member-details.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/risk-insights-application.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/risk-insights-report.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/risk-insights-summary.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/risk-insights.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/member-details.view.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/risk-insights-application.view.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/risk-insights-report.view.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/risk-insights-summary.view.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/risk-insights.view.ts diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/member-details.api.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/member-details.api.ts new file mode 100644 index 00000000000..7d43382bd1a --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/member-details.api.ts @@ -0,0 +1,33 @@ +import { BaseResponse } from "@bitwarden/common/models/response/base.response"; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { MemberDetailsData } from "../data/member-details.data"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { MemberDetails } from "../domain/member-details"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { MemberDetailsView } from "../view/member-details.view"; + +/** + * Converts a MemberDetails API response + * + * - See {@link MemberDetails} for domain model + * - See {@link MemberDetailsData} for data model + * - See {@link MemberDetailsView} from View Model + */ +export class MemberDetailsApi extends BaseResponse { + userGuid: string = ""; + userName: string = ""; + email: string = ""; + cipherId: string = ""; + + constructor(data: any = null) { + super(data); + if (data == null) { + return; + } + this.userGuid = this.getResponseProperty("userGuid"); + this.userName = this.getResponseProperty("userName"); + this.email = this.getResponseProperty("email"); + this.cipherId = this.getResponseProperty("cipherId"); + } +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/risk-insights-application.api.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/risk-insights-application.api.ts new file mode 100644 index 00000000000..9ba86d59815 --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/risk-insights-application.api.ts @@ -0,0 +1,32 @@ +import { BaseResponse } from "@bitwarden/common/models/response/base.response"; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsApplicationData } from "../data/risk-insights-application.data"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsApplication } from "../domain/risk-insights-application"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsApplicationView } from "../view/risk-insights-application.view"; + +/** + * Converts a RiskInsightsApplication API response + * + * - See {@link RiskInsightsApplication} for domain model + * - See {@link RiskInsightsApplicationData} for data model + * - See {@link RiskInsightsApplicationView} from View Model + */ +export class RiskInsightsApplicationApi extends BaseResponse { + applicationName: string = ""; + isCritical: boolean = false; + reviewedDate: string | undefined; + + constructor(data: any) { + super(data); + if (data == null) { + return; + } + + this.applicationName = this.getResponseProperty("applicationName"); + this.isCritical = this.getResponseProperty("isCritical") ?? false; + this.reviewedDate = this.getResponseProperty("reviewedDate"); + } +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/risk-insights-report.api.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/risk-insights-report.api.ts new file mode 100644 index 00000000000..0a606feb2a1 --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/risk-insights-report.api.ts @@ -0,0 +1,53 @@ +import { BaseResponse } from "@bitwarden/common/models/response/base.response"; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsReportData } from "../data/risk-insights-report.data"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsReport } from "../domain/risk-insights-report"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsReportView } from "../view/risk-insights-report.view"; + +import { MemberDetailsApi } from "./member-details.api"; + +/** + * Converts a RiskInsightsReport API response + * + * - See {@link RiskInsightsReport} for domain model + * - See {@link RiskInsightsReportData} for data model + * - See {@link RiskInsightsReportView} from View Model + */ +export class RiskInsightsReportApi extends BaseResponse { + applicationName: string = ""; + passwordCount: number = 0; + atRiskPasswordCount: number = 0; + atRiskCipherIds: string[] = []; + memberCount: number = 0; + atRiskMemberCount: number = 0; + memberDetails: MemberDetailsApi[] = []; + atRiskMemberDetails: MemberDetailsApi[] = []; + cipherIds: string[] = []; + + constructor(data: any) { + super(data); + if (data == null) { + return; + } + + this.applicationName = this.getResponseProperty("applicationName"); + this.passwordCount = this.getResponseProperty("passwordCount"); + this.atRiskPasswordCount = this.getResponseProperty("atRiskPasswordCount"); + this.atRiskCipherIds = this.getResponseProperty("atRiskCipherIds"); + this.memberCount = this.getResponseProperty("memberCount"); + this.atRiskMemberCount = this.getResponseProperty("atRiskMemberCount"); + this.cipherIds = this.getResponseProperty("cipherIds"); + + const memberDetails = this.getResponseProperty("memberDetails"); + if (memberDetails != null) { + this.memberDetails = memberDetails.map((f: any) => new MemberDetailsApi(f)); + } + const atRiskMemberDetails = this.getResponseProperty("atRiskMemberDetails"); + if (atRiskMemberDetails != null) { + this.atRiskMemberDetails = atRiskMemberDetails.map((f: any) => new MemberDetailsApi(f)); + } + } +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/risk-insights-summary.api.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/risk-insights-summary.api.ts new file mode 100644 index 00000000000..06d175f6371 --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/risk-insights-summary.api.ts @@ -0,0 +1,42 @@ +import { BaseResponse } from "@bitwarden/common/models/response/base.response"; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsSummaryData } from "../data/risk-insights-summary.data"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsSummary } from "../domain/risk-insights-summary"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsSummaryView } from "../view/risk-insights-summary.view"; + +/** + * Converts a RiskInsightsSummary API response + * + * - See {@link RiskInsightsSummary} for domain model + * - See {@link RiskInsightsSummaryData} for data model + * - See {@link RiskInsightsSummaryView} from View Model + */ +export class RiskInsightsSummaryApi extends BaseResponse { + totalMemberCount: number = 0; + totalApplicationCount: number = 0; + totalAtRiskMemberCount: number = 0; + totalAtRiskApplicationCount: number = 0; + totalCriticalApplicationCount: number = 0; + totalCriticalMemberCount: number = 0; + totalCriticalAtRiskMemberCount: number = 0; + totalCriticalAtRiskApplicationCount: number = 0; + + constructor(data: any) { + super(data); + + this.totalMemberCount = this.getResponseProperty("totalMemberCount") || 0; + this.totalApplicationCount = this.getResponseProperty("totalApplicationCount") || 0; + this.totalAtRiskMemberCount = this.getResponseProperty("totalAtRiskMemberCount") || 0; + this.totalAtRiskApplicationCount = this.getResponseProperty("totalAtRiskApplicationCount") || 0; + this.totalCriticalApplicationCount = + this.getResponseProperty("totalCriticalApplicationCount") || 0; + this.totalCriticalMemberCount = this.getResponseProperty("totalCriticalMemberCount") || 0; + this.totalCriticalAtRiskMemberCount = + this.getResponseProperty("totalCriticalAtRiskMemberCount") || 0; + this.totalCriticalAtRiskApplicationCount = + this.getResponseProperty("totalCriticalAtRiskApplicationCount") || 0; + } +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/risk-insights.api.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/risk-insights.api.ts new file mode 100644 index 00000000000..30ea5c745a2 --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api/risk-insights.api.ts @@ -0,0 +1,56 @@ +import { BaseResponse } from "@bitwarden/common/models/response/base.response"; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsData } from "../data/risk-insights.data"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsights } from "../domain/risk-insights"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsView } from "../view/risk-insights.view"; + +/** + * Converts a RiskInsights API response + * + * - See {@link RiskInsights} for domain model + * - See {@link RiskInsightsData} for data model + * - See {@link RiskInsightsView} from View Model + */ +// [TODO] To replace GetRiskInsightsReportResponse +export class RiskInsightsApi extends BaseResponse { + id: string = ""; + organizationId: string = ""; + reports: string = ""; + applications: string = ""; + summary: string = ""; + creationDate: string = ""; + contentEncryptionKey: string = ""; + + constructor(data: any = null) { + super(data); + if (data == null) { + return; + } + + this.id = this.getResponseProperty("id"); + this.organizationId = this.getResponseProperty("organizationId"); + this.creationDate = this.getResponseProperty("creationDate"); + this.reports = this.getResponseProperty("reportData"); + this.applications = this.getResponseProperty("applicationData"); + this.summary = this.getResponseProperty("summaryData"); + this.contentEncryptionKey = this.getResponseProperty("contentEncryptionKey"); + + // Use when individual values are encrypted + // const summary = this.getResponseProperty("summaryData"); + // if (summary != null) { + // this.summary = new RiskInsightsSummaryApi(summary); + // } + + // const reports = this.getResponseProperty("reportData"); + // if (reports != null) { + // this.reports = reports.map((r: any) => new RiskInsightsReportApi(r)); + // } + // const applications = this.getResponseProperty("applicationData"); + // if (applications != null) { + // this.applications = applications.map((f: any) => new RiskInsightsApplicationApi(f)); + // } + } +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/member-details.data.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/member-details.data.ts new file mode 100644 index 00000000000..16657b8151a --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/member-details.data.ts @@ -0,0 +1,30 @@ +import { MemberDetailsApi } from "../api/member-details.api"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { MemberDetails } from "../domain/member-details"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { MemberDetailsView } from "../view/member-details.view"; + +/** + * Serializable data model for member details in risk insights report + * + * - See {@link MemberDetails} for domain model + * - See {@link MemberDetailsApi} for API model + * - See {@link MemberDetailsView} from View Model + */ +export class MemberDetailsData { + userGuid: string = ""; + userName: string = ""; + email: string = ""; + cipherId: string = ""; + + constructor(data?: MemberDetailsApi) { + if (data == null) { + return; + } + + this.userGuid = data.userGuid; + this.userName = data.userName; + this.email = data.email; + this.cipherId = data.cipherId; + } +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/risk-insights-application.data.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/risk-insights-application.data.ts new file mode 100644 index 00000000000..849f83b521a --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/risk-insights-application.data.ts @@ -0,0 +1,29 @@ +import { RiskInsightsApplicationApi } from "../api/risk-insights-application.api"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsApplication } from "../domain/risk-insights-application"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsApplicationView } from "../view/risk-insights-application.view"; + +/** + * Serializable data model for Application data in risk insights report + * + * - See {@link RiskInsightsApplication} for domain model + * - See {@link RiskInsightsApplicationApi} for API model + * - See {@link RiskInsightsApplicationView} from View Model + */ + +export class RiskInsightsApplicationData { + applicationName: string = ""; + isCritical: boolean = false; + reviewedDate: string | undefined; + + constructor(data?: RiskInsightsApplicationApi) { + if (data == null) { + return; + } + + this.applicationName = data.applicationName; + this.isCritical = data.isCritical; + this.reviewedDate = data.reviewedDate; + } +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/risk-insights-report.data.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/risk-insights-report.data.ts new file mode 100644 index 00000000000..6a5ee2a86fa --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/risk-insights-report.data.ts @@ -0,0 +1,48 @@ +import { RiskInsightsReportApi } from "../api/risk-insights-report.api"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsReport } from "../domain/risk-insights-report"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsReportView } from "../view/risk-insights-report.view"; + +import { MemberDetailsData } from "./member-details.data"; + +/** + * Serializable data model for generated report in risk insights report + * + * - See {@link RiskInsightsReport} for domain model + * - See {@link RiskInsightsReportApi} for API model + * - See {@link RiskInsightsReportView} from View Model + */ +export class RiskInsightsReportData { + applicationName: string = ""; + passwordCount: number = 0; + atRiskPasswordCount: number = 0; + atRiskCipherIds: string[] = []; + memberCount: number = 0; + atRiskMemberCount: number = 0; + memberDetails: MemberDetailsData[] = []; + atRiskMemberDetails: MemberDetailsData[] = []; + cipherIds: string[] = []; + + constructor(data?: RiskInsightsReportApi) { + if (data == null) { + return; + } + this.applicationName = data.applicationName; + this.passwordCount = data.passwordCount; + this.atRiskPasswordCount = data.atRiskPasswordCount; + this.atRiskCipherIds = data.atRiskCipherIds; + this.memberCount = data.memberCount; + this.atRiskMemberCount = data.atRiskMemberCount; + this.memberDetails = data.memberDetails; + this.atRiskMemberDetails = data.atRiskMemberDetails; + this.cipherIds = data.cipherIds; + + if (data.memberDetails != null) { + this.memberDetails = data.memberDetails.map((m) => new MemberDetailsData(m)); + } + if (data.atRiskMemberDetails != null) { + this.atRiskMemberDetails = data.atRiskMemberDetails.map((m) => new MemberDetailsData(m)); + } + } +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/risk-insights-summary.data.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/risk-insights-summary.data.ts new file mode 100644 index 00000000000..895d0acd0ff --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/risk-insights-summary.data.ts @@ -0,0 +1,38 @@ +import { RiskInsightsSummaryApi } from "../api/risk-insights-summary.api"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsSummary } from "../domain/risk-insights-summary"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsSummaryView } from "../view/risk-insights-summary.view"; + +/** + * Serializable data model for report summary in risk insights report + * + * - See {@link RiskInsightsSummary} for domain model + * - See {@link RiskInsightsSummaryApi} for API model + * - See {@link RiskInsightsSummaryView} from View Model + */ +export class RiskInsightsSummaryData { + totalMemberCount: number = 0; + totalApplicationCount: number = 0; + totalAtRiskMemberCount: number = 0; + totalAtRiskApplicationCount: number = 0; + totalCriticalApplicationCount: number = 0; + totalCriticalMemberCount: number = 0; + totalCriticalAtRiskMemberCount: number = 0; + totalCriticalAtRiskApplicationCount: number = 0; + + constructor(data?: RiskInsightsSummaryApi) { + if (data == null) { + return; + } + + this.totalMemberCount = data.totalMemberCount; + this.totalApplicationCount = data.totalApplicationCount; + this.totalAtRiskMemberCount = data.totalAtRiskMemberCount; + this.totalAtRiskApplicationCount = data.totalAtRiskApplicationCount; + this.totalCriticalApplicationCount = data.totalCriticalApplicationCount; + this.totalCriticalMemberCount = data.totalCriticalMemberCount; + this.totalCriticalAtRiskMemberCount = data.totalCriticalAtRiskMemberCount; + this.totalCriticalAtRiskApplicationCount = data.totalCriticalAtRiskApplicationCount; + } +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/risk-insights.data.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/risk-insights.data.ts new file mode 100644 index 00000000000..5d83ebc3dfe --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/data/risk-insights.data.ts @@ -0,0 +1,49 @@ +import { RiskInsightsApi } from "../api/risk-insights.api"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsights } from "../domain/risk-insights"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsView } from "../view/risk-insights.view"; + +/** + * Serializable data model for member details in risk insights report + * + * - See {@link RiskInsights} for domain model + * - See {@link RiskInsightsApi} for API model + * - See {@link RiskInsightsView} from View Model + */ +export class RiskInsightsData { + id: string = ""; + organizationId: string = ""; + reports: string = ""; + applications: string = ""; + summary: string = ""; + // [TODO] Update types when individual values are encrypted instead of the entire object + // reports: RiskInsightsReportData[]; // Previously ApplicationHealthReportDetail Data type + // applications: RiskInsightsApplicationsData[]; // Previously OrganizationReportApplication Data type + // summary: RiskInsightsSummaryData; // Previously OrganizationReportSummary Data type + creationDate: string = ""; + contentEncryptionKey: string = ""; + + constructor(response?: RiskInsightsApi) { + if (response == null) { + return; + } + + this.id = response.id; + this.organizationId = response.organizationId; + this.reports = response.reports; + this.applications = response.applications; + this.summary = response.summary; + this.creationDate = response.creationDate; + this.contentEncryptionKey = response.contentEncryptionKey; + + // [TODO] Update types when individual values are encrypted instead of the entire object + // this.summary = new RiskInsightsSummaryData(response.summaryData); + // if (response.reports != null) { + // this.reports = response.reports.map((r) => new RiskInsightsReportData(r)); + // } + // if (response.applications != null) { + // this.applications = response.applications.map((a) => new RiskInsightsApplicationData(a)); + // } + } +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/member-details.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/member-details.ts new file mode 100644 index 00000000000..b5704c8f27d --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/member-details.ts @@ -0,0 +1,34 @@ +import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string"; +import Domain from "@bitwarden/common/platform/models/domain/domain-base"; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { MemberDetailsApi } from "../api/member-details.api"; +import { MemberDetailsData } from "../data/member-details.data"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { MemberDetailsView } from "../view/member-details.view"; + +/** + * Domain model for Member Details in Risk Insights containing encrypted properties + * + * - See {@link MemberDetailsApi} for API model + * - See {@link MemberDetailsData} for data model + * - See {@link MemberDetailsView} from View Model + */ +export class MemberDetails extends Domain { + userGuid: EncString = new EncString(""); + userName: EncString = new EncString(""); + email: EncString = new EncString(""); + cipherId: EncString = new EncString(""); + + constructor(data?: MemberDetailsData) { + super(); + if (data == null) { + return; + } + + this.userGuid = new EncString(data.userGuid); + this.userName = new EncString(data.userName); + this.email = new EncString(data.email); + this.cipherId = new EncString(data.cipherId); + } +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/risk-insights-application.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/risk-insights-application.ts new file mode 100644 index 00000000000..b224a63f0ae --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/risk-insights-application.ts @@ -0,0 +1,31 @@ +import Domain from "@bitwarden/common/platform/models/domain/domain-base"; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsApplicationApi } from "../api/risk-insights-application.api"; +import { RiskInsightsApplicationData } from "../data/risk-insights-application.data"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsApplicationView } from "../view/risk-insights-application.view"; + +/** + * Domain model for Application data in Risk Insights containing encrypted properties + * + * - See {@link RiskInsightsApplicationApi} for API model + * - See {@link RiskInsightsApplicationData} for data model + * - See {@link RiskInsightsApplicationView} from View Model + */ +export class RiskInsightsApplication extends Domain { + applicationName: string = ""; // TODO: Encrypt? + isCritical: boolean = false; + reviewedDate?: Date; + + constructor(obj?: RiskInsightsApplicationData) { + super(); + if (obj == null) { + return; + } + + this.applicationName = obj.applicationName; + this.isCritical = obj.isCritical; + this.reviewedDate = obj.reviewedDate ? new Date(obj.reviewedDate) : undefined; + } +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/risk-insights-report.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/risk-insights-report.ts new file mode 100644 index 00000000000..16ee5307b4c --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/risk-insights-report.ts @@ -0,0 +1,59 @@ +import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string"; +import Domain from "@bitwarden/common/platform/models/domain/domain-base"; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsReportApi } from "../api/risk-insights-report.api"; +import { RiskInsightsReportData } from "../data/risk-insights-report.data"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsReportView } from "../view/risk-insights-report.view"; + +import { MemberDetails } from "./member-details"; + +/** + * Domain model for generated report data in Risk Insights containing encrypted properties + * + * - See {@link RiskInsightsReportApi} for API model + * - See {@link RiskInsightsReportData} for data model + * - See {@link RiskInsightsReportView} from View Model + */ +export class RiskInsightsReport extends Domain { + applicationName: EncString = new EncString(""); + passwordCount: EncString = new EncString(""); + atRiskPasswordCount: EncString = new EncString(""); + atRiskCipherIds: string[] = []; + memberCount: EncString = new EncString(""); + atRiskMemberCount: EncString = new EncString(""); + memberDetails: MemberDetails[] = []; + atRiskMemberDetails: MemberDetails[] = []; + cipherIds: string[] = []; + + constructor(obj?: RiskInsightsReportData) { + super(); + if (obj == null) { + return; + } + this.applicationName = new EncString(obj.applicationName); + this.passwordCount = new EncString(obj.passwordCount); + this.atRiskPasswordCount = new EncString(obj.atRiskPasswordCount); + this.atRiskCipherIds = obj.atRiskCipherIds; + this.memberCount = new EncString(obj.memberCount); + this.atRiskMemberCount = new EncString(obj.atRiskMemberCount); + this.cipherIds = obj.cipherIds; + + if (obj.memberDetails != null) { + this.memberDetails = obj.memberDetails.map((m) => new MemberDetails(m)); + } + if (obj.atRiskMemberDetails != null) { + this.atRiskMemberDetails = obj.atRiskMemberDetails.map((m) => new MemberDetails(m)); + } + } + + // [TODO] Domain level methods + // static fromJSON(): RiskInsightsReport {} + // decrypt(): RiskInsightsReportView {} + // toData(): RiskInsightsReportData {} + + // [TODO] SDK Mapping + // toSdkRiskInsightsReport(): SdkRiskInsightsReport {} + // static fromSdkRiskInsightsReport(obj?: SdkRiskInsightsReport): RiskInsightsReport | undefined {} +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/risk-insights-summary.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/risk-insights-summary.ts new file mode 100644 index 00000000000..712c488d54e --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/risk-insights-summary.ts @@ -0,0 +1,50 @@ +import Domain from "@bitwarden/common/platform/models/domain/domain-base"; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsSummaryApi } from "../api/risk-insights-summary.api"; +import { RiskInsightsSummaryData } from "../data/risk-insights-summary.data"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsSummaryView } from "../view/risk-insights-summary.view"; + +/** + * Domain model for Member Details in Risk Insights containing encrypted properties + * + * - See {@link RiskInsightsSummaryApi} for API model + * - See {@link RiskInsightsSummaryData} for data model + * - See {@link RiskInsightsSummaryView} from View Model + */ +export class RiskInsightsSummary extends Domain { + totalMemberCount: number = 0; + totalApplicationCount: number = 0; + totalAtRiskMemberCount: number = 0; + totalAtRiskApplicationCount: number = 0; + totalCriticalApplicationCount: number = 0; + totalCriticalMemberCount: number = 0; + totalCriticalAtRiskMemberCount: number = 0; + totalCriticalAtRiskApplicationCount: number = 0; + + constructor(obj?: RiskInsightsSummaryData) { + super(); + if (obj == null) { + return; + } + + this.totalMemberCount = obj.totalMemberCount; + this.totalApplicationCount = obj.totalApplicationCount; + this.totalAtRiskMemberCount = obj.totalAtRiskMemberCount; + this.totalAtRiskApplicationCount = obj.totalAtRiskApplicationCount; + this.totalCriticalApplicationCount = obj.totalCriticalApplicationCount; + this.totalCriticalMemberCount = obj.totalCriticalMemberCount; + this.totalCriticalAtRiskMemberCount = obj.totalCriticalAtRiskMemberCount; + this.totalCriticalAtRiskApplicationCount = obj.totalCriticalAtRiskApplicationCount; + } + + // [TODO] Domain level methods + // static fromJSON(): RiskInsightsSummary {} + // decrypt(): RiskInsightsSummaryView {} + // toData(): RiskInsightsSummaryData {} + + // [TODO] SDK Mapping + // toSdkRiskInsightsReport(): SdkRiskInsightsReport {} + // static fromSdkRiskInsightsReport(obj?: SdkRiskInsightsReport): RiskInsightsReport | undefined {} +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/risk-insights.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/risk-insights.ts new file mode 100644 index 00000000000..fe1a277d62f --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/risk-insights.ts @@ -0,0 +1,49 @@ +import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string"; +import Domain from "@bitwarden/common/platform/models/domain/domain-base"; +import { conditionalEncString } from "@bitwarden/common/vault/utils/domain-utils"; + +import { RiskInsightsData } from "../data/risk-insights.data"; + +export class RiskInsights extends Domain { + id: string = ""; + organizationId: string = ""; + reports: EncString = new EncString(""); + applications: EncString = new EncString(""); + summary: EncString = new EncString(""); + creationDate: Date; + contentEncryptionKey?: EncString; + + constructor(obj?: RiskInsightsData) { + super(); + if (obj == null) { + this.creationDate = new Date(); + return; + } + this.id = obj.id; + this.organizationId = obj.organizationId; + this.reports = conditionalEncString(obj.reports) ?? new EncString(""); + this.applications = conditionalEncString(obj.applications) ?? new EncString(""); + this.summary = conditionalEncString(obj.summary) ?? new EncString(""); + this.creationDate = new Date(obj.creationDate); + this.contentEncryptionKey = conditionalEncString(obj.contentEncryptionKey); + + // Example usage when individual keys are encrypted instead of the entire object + // this.summary = new RiskInsightsSummary(obj.summary); + + // if (obj.reports != null) { + // this.reports = obj.reports.map((r) => new RiskInsightsReport(r)); + // } + // if (obj.applications != null) { + // this.applications = obj.applications.map((a) => new RiskInsightsApplication(a)); + // } + } + + // [TODO] Domain level methods + // static fromJSON(obj: Jsonify): RiskInsights {} + // decrypt() RiskInsightsView {} + // toData(): RiskInsightsData {} + + // [TODO] SDK Mapping + // toSdkRiskInsights(): SdkRiskInsights {} + // static fromSdkRiskInsights(obj?: SdkRiskInsights): RiskInsights | undefined {} +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/member-details.view.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/member-details.view.ts new file mode 100644 index 00000000000..7d4434a8a7e --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/member-details.view.ts @@ -0,0 +1,43 @@ +import { Jsonify } from "type-fest"; + +import { View } from "@bitwarden/common/models/view/view"; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { MemberDetailsApi } from "../api/member-details.api"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { MemberDetailsData } from "../data/member-details.data"; +import { MemberDetails } from "../domain/member-details"; + +/** + * View model for Member Details in Risk Insights containing decrypted properties + * + * - See {@link MemberDetails} for domain model + * - See {@link MemberDetailsData} for data model + * - See {@link MemberDetailsApi} for API model + */ +export class MemberDetailsView implements View { + userGuid: string = ""; + userName: string = ""; + email: string = ""; + cipherId: string = ""; + + constructor(m?: MemberDetails) { + if (m == null) { + return; + } + } + + toJSON() { + return this; + } + + static fromJSON( + obj: Partial> | undefined, + ): MemberDetailsView | undefined { + return Object.assign(new MemberDetailsView(), obj); + } + + // [TODO] SDK Mapping + // toSdkMemberDetailsView(): SdkMemberDetailsView {} + // static fromMemberDetailsView(obj?: SdkMemberDetailsView): MemberDetailsView | undefined {} +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/risk-insights-application.view.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/risk-insights-application.view.ts new file mode 100644 index 00000000000..b79b735d458 --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/risk-insights-application.view.ts @@ -0,0 +1,45 @@ +import { View } from "@bitwarden/common/models/view/view"; +import { DeepJsonify } from "@bitwarden/common/types/deep-jsonify"; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsApplicationApi } from "../api/risk-insights-application.api"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsApplicationData } from "../data/risk-insights-application.data"; +import { RiskInsightsApplication } from "../domain/risk-insights-application"; + +/** + * View model for Application data in Risk Insights containing decrypted properties + * + * - See {@link RiskInsightsApplication} for domain model + * - See {@link RiskInsightsApplicationData} for data model + * - See {@link RiskInsightsApplicationApi} for API model + */ +export class RiskInsightsApplicationView implements View { + applicationName: string = ""; + isCritical = false; + reviewedDate?: Date; + + constructor(a?: RiskInsightsApplication) { + if (a == null) { + return; + } + + this.applicationName = a.applicationName; + this.isCritical = a.isCritical; + this.reviewedDate = a.reviewedDate; + } + + toJSON() { + return this; + } + + static fromJSON( + obj: Partial>, + ): RiskInsightsApplicationView { + return Object.assign(new RiskInsightsApplicationView(), obj); + } + + // [TODO] SDK Mapping + // toSdkRiskInsightsApplicationView(): SdkRiskInsightsApplicationView {} + // static fromRiskInsightsApplicationView(obj?: SdkRiskInsightsApplicationView): RiskInsightsApplicationView | undefined {} +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/risk-insights-report.view.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/risk-insights-report.view.ts new file mode 100644 index 00000000000..c4deb7fadd4 --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/risk-insights-report.view.ts @@ -0,0 +1,64 @@ +import { View } from "@bitwarden/common/models/view/view"; +import { DeepJsonify } from "@bitwarden/common/types/deep-jsonify"; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsReportApi } from "../api/risk-insights-report.api"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsReportData } from "../data/risk-insights-report.data"; +import { RiskInsightsReport } from "../domain/risk-insights-report"; + +import { MemberDetailsView } from "./member-details.view"; + +/** + * View model for Member Details in Risk Insights containing decrypted properties + * + * - See {@link RiskInsightsReport} for domain model + * - See {@link RiskInsightsReportData} for data model + * - See {@link RiskInsightsReportApi} for API model + */ +export class RiskInsightsReportView implements View { + applicationName: string = ""; + passwordCount: number = 0; + atRiskPasswordCount: number = 0; + atRiskCipherIds: string[] = []; + memberCount: number = 0; + atRiskMemberCount: number = 0; + memberDetails: MemberDetailsView[] = []; + atRiskMemberDetails: MemberDetailsView[] = []; + cipherIds: string[] = []; + + constructor(r?: RiskInsightsReport) { + if (r == null) { + return; + } + } + + toJSON() { + return this; + } + + static fromJSON( + obj: Partial> | undefined, + ): RiskInsightsReportView { + if (obj == undefined) { + return new RiskInsightsReportView(); + } + + const view = Object.assign(new RiskInsightsReportView(), obj) as RiskInsightsReportView; + + view.memberDetails = + obj.memberDetails + ?.map((m: any) => MemberDetailsView.fromJSON(m)) + .filter((m): m is MemberDetailsView => m !== undefined) ?? []; + view.atRiskMemberDetails = + obj.atRiskMemberDetails + ?.map((m: any) => MemberDetailsView.fromJSON(m)) + .filter((m): m is MemberDetailsView => m !== undefined) ?? []; + + return view; + } + + // [TODO] SDK Mapping + // toSdkRiskInsightsReportView(): SdkRiskInsightsReportView {} + // static fromRiskInsightsReportView(obj?: SdkRiskInsightsReportView): RiskInsightsReportView | undefined {} +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/risk-insights-summary.view.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/risk-insights-summary.view.ts new file mode 100644 index 00000000000..98fe76938c4 --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/risk-insights-summary.view.ts @@ -0,0 +1,53 @@ +import { View } from "@bitwarden/common/models/view/view"; +import { DeepJsonify } from "@bitwarden/common/types/deep-jsonify"; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsSummaryApi } from "../api/risk-insights-summary.api"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsSummaryData } from "../data/risk-insights-summary.data"; +import { RiskInsightsSummary } from "../domain/risk-insights-summary"; + +/** + * View model for Report Summary in Risk Insights containing decrypted properties + * + * - See {@link RiskInsightsSummary} for domain model + * - See {@link RiskInsightsSummaryData} for data model + * - See {@link RiskInsightsSummaryApi} for API model + */ +export class RiskInsightsSummaryView implements View { + totalMemberCount: number = 0; + totalApplicationCount: number = 0; + totalAtRiskMemberCount: number = 0; + totalAtRiskApplicationCount: number = 0; + totalCriticalApplicationCount: number = 0; + totalCriticalMemberCount: number = 0; + totalCriticalAtRiskMemberCount: number = 0; + totalCriticalAtRiskApplicationCount: number = 0; + + constructor(obj?: RiskInsightsSummary) { + if (obj == null) { + return; + } + + this.totalMemberCount = obj.totalMemberCount; + this.totalApplicationCount = obj.totalApplicationCount; + this.totalAtRiskMemberCount = obj.totalAtRiskMemberCount; + this.totalAtRiskApplicationCount = obj.totalAtRiskApplicationCount; + this.totalCriticalApplicationCount = obj.totalCriticalApplicationCount; + this.totalCriticalMemberCount = obj.totalCriticalMemberCount; + this.totalCriticalAtRiskMemberCount = obj.totalCriticalAtRiskMemberCount; + this.totalCriticalAtRiskApplicationCount = obj.totalCriticalAtRiskApplicationCount; + } + + toJSON() { + return this; + } + + static fromJSON(obj: Partial>): RiskInsightsSummaryView { + return Object.assign(new RiskInsightsSummaryView(), obj); + } + + // [TODO] SDK Mapping + // toSdkRiskInsightsSummaryView(): SdkRiskInsightsSummaryView {} + // static fromRiskInsightsSummaryView(obj?: SdkRiskInsightsSummaryView): RiskInsightsSummaryView | undefined {} +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/risk-insights.view.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/risk-insights.view.ts new file mode 100644 index 00000000000..7ce1fd28046 --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/view/risk-insights.view.ts @@ -0,0 +1,65 @@ +import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string"; +import { View } from "@bitwarden/common/models/view/view"; +import { DeepJsonify } from "@bitwarden/common/types/deep-jsonify"; +import { OrganizationId, OrganizationReportId } from "@bitwarden/common/types/guid"; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsApi } from "../api/risk-insights.api"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { RiskInsightsData } from "../data/risk-insights.data"; +import { RiskInsights } from "../domain/risk-insights"; + +import { RiskInsightsApplicationView } from "./risk-insights-application.view"; +import { RiskInsightsReportView } from "./risk-insights-report.view"; +import { RiskInsightsSummaryView } from "./risk-insights-summary.view"; + +/** + * View model for Member Details in Risk Insights containing decrypted properties + * + * - See {@link RiskInsights} for domain model + * - See {@link RiskInsightsData} for data model + * - See {@link RiskInsightsApi} for API model + */ +export class RiskInsightsView implements View { + id: OrganizationReportId = "" as OrganizationReportId; + organizationId: OrganizationId = "" as OrganizationId; + reports: RiskInsightsReportView[] = []; + applications: RiskInsightsApplicationView[] = []; + summary = new RiskInsightsSummaryView(); + creationDate: Date; + contentEncryptionKey?: EncString; + + constructor(report?: RiskInsights) { + if (!report) { + this.creationDate = new Date(); + return; + } + + this.id = report.id as OrganizationReportId; + this.organizationId = report.organizationId as OrganizationId; + this.creationDate = report.creationDate; + this.contentEncryptionKey = report.contentEncryptionKey; + } + + toJSON() { + return this; + } + + static fromJSON(obj: Partial> | null): RiskInsightsView { + if (obj == undefined) { + return new RiskInsightsView(); + } + + const view = Object.assign(new RiskInsightsView(), obj) as RiskInsightsView; + + view.reports = obj.reports?.map((report) => RiskInsightsReportView.fromJSON(report)) ?? []; + view.applications = obj.applications?.map((a) => RiskInsightsApplicationView.fromJSON(a)) ?? []; + view.summary = RiskInsightsSummaryView.fromJSON(obj.summary ?? {}); + + return view; + } + + // [TODO] SDK Mapping + // toSdkRiskInsightsView(): SdkRiskInsightsView {} + // static fromRiskInsightsView(obj?: SdkRiskInsightsView): RiskInsightsView | undefined {} +}