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..7468d71b9cb --- /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/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..cc7e70d43d2 --- /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/risk-insights.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/domain/risk-insights.ts new file mode 100644 index 00000000000..eca6f020d06 --- /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); + this.applications = conditionalEncString(obj.applications); + this.summary = conditionalEncString(obj.summary); + 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/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..4f01d5f716b --- /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 {} +}