From d6cd30cf5410a2fff8509a076f791eef53ba848b Mon Sep 17 00:00:00 2001 From: Alex <55413326+AlexRubik@users.noreply.github.com> Date: Thu, 18 Sep 2025 14:08:07 -0400 Subject: [PATCH] [PM-25607] Separate Models and account for legacy (#16448) * organize password-health.ts contents into new model files * revert naming * revert to state of use save service pr draft * LEGACY_MemberDetailsFlat * legacy updates to password health file * update imports * fix import errors * - revert unnecessary encrypteddatamodel changes -add it back to password-health.ts - revert the type changes of variables in EncryptedDataWithKey * quick fix --- .../helpers/risk-insights-data-mappers.ts | 22 +- .../risk-insights/models/api-models.types.ts | 49 +++++ .../risk-insights/models/password-health.ts | 196 +++--------------- .../risk-insights/models/report-models.ts | 162 +++++++++++++++ .../critical-apps-api.service.spec.ts | 4 +- .../services/critical-apps-api.service.ts | 2 +- .../services/critical-apps.service.spec.ts | 4 +- .../services/critical-apps.service.ts | 2 +- .../risk-insights-api.service.spec.ts | 7 +- .../services/risk-insights-api.service.ts | 4 +- .../services/risk-insights-data.service.ts | 4 +- .../risk-insights-report.service.spec.ts | 6 +- .../services/risk-insights-report.service.ts | 54 ++--- .../all-applications.component.ts | 14 +- .../app-table-row-scrollable.component.ts | 5 +- .../critical-applications.component.ts | 12 +- .../risk-insights.component.ts | 4 +- 17 files changed, 322 insertions(+), 229 deletions(-) create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api-models.types.ts create mode 100644 bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/report-models.ts diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/helpers/risk-insights-data-mappers.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/helpers/risk-insights-data-mappers.ts index 8dae10f369e..8fbe45efeab 100644 --- a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/helpers/risk-insights-data-mappers.ts +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/helpers/risk-insights-data-mappers.ts @@ -2,16 +2,16 @@ import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { - MemberDetailsFlat, - CipherHealthReportDetail, - CipherHealthReportUriDetail, - ApplicationHealthReportDetail, + LEGACY_MemberDetailsFlat, + LEGACY_CipherHealthReportDetail, + LEGACY_CipherHealthReportUriDetail, } from "../models/password-health"; +import { ApplicationHealthReportDetail } from "../models/report-models"; import { MemberCipherDetailsResponse } from "../response/member-cipher-details.response"; export function flattenMemberDetails( memberCiphers: MemberCipherDetailsResponse[], -): MemberDetailsFlat[] { +): LEGACY_MemberDetailsFlat[] { return memberCiphers.flatMap((member) => member.cipherIds.map((cipherId) => ({ userGuid: member.userGuid, @@ -44,7 +44,9 @@ export function getTrimmedCipherUris(cipher: CipherView): string[] { } // Returns a deduplicated array of members by email -export function getUniqueMembers(orgMembers: MemberDetailsFlat[]): MemberDetailsFlat[] { +export function getUniqueMembers( + orgMembers: LEGACY_MemberDetailsFlat[], +): LEGACY_MemberDetailsFlat[] { const existingEmails = new Set(); return orgMembers.filter((member) => { if (existingEmails.has(member.email)) { @@ -68,7 +70,7 @@ export function getMemberDetailsFlat( userName: string, email: string, cipherId: string, -): MemberDetailsFlat { +): LEGACY_MemberDetailsFlat { return { userGuid: userGuid, userName: userName, @@ -84,9 +86,9 @@ export function getMemberDetailsFlat( * @returns Flattened cipher health details to URI */ export function getFlattenedCipherDetails( - detail: CipherHealthReportDetail, + detail: LEGACY_CipherHealthReportDetail, uri: string, -): CipherHealthReportUriDetail { +): LEGACY_CipherHealthReportUriDetail { return { cipherId: detail.id, reusedPasswordCount: detail.reusedPasswordCount, @@ -107,7 +109,7 @@ export function getFlattenedCipherDetails( * @returns The new or updated application health report detail */ export function getApplicationReportDetail( - newUriDetail: CipherHealthReportUriDetail, + newUriDetail: LEGACY_CipherHealthReportUriDetail, isAtRisk: boolean, existingUriDetail?: ApplicationHealthReportDetail, ): ApplicationHealthReportDetail { diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api-models.types.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api-models.types.ts new file mode 100644 index 00000000000..1386b2d044f --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/api-models.types.ts @@ -0,0 +1,49 @@ +import { EncryptedString } from "@bitwarden/common/key-management/crypto/models/enc-string"; +import { OrganizationId } from "@bitwarden/common/types/guid"; + +import { PasswordHealthReportApplicationId, RiskInsightsReport } from "./report-models"; + +// -------------------- Password Health Report Models -------------------- +/** + * Request to drop a password health report application + * Model is expected by the API endpoint + */ +export interface PasswordHealthReportApplicationDropRequest { + organizationId: OrganizationId; + passwordHealthReportApplicationIds: string[]; +} + +/** + * Response from the API after marking an app as critical + */ +export interface PasswordHealthReportApplicationsResponse { + id: PasswordHealthReportApplicationId; + organizationId: OrganizationId; + uri: string; +} +/* + * Request to save a password health report application + * Model is expected by the API endpoint + */ +export interface PasswordHealthReportApplicationsRequest { + organizationId: OrganizationId; + url: string; +} + +// -------------------- Risk Insights Report Models -------------------- +export interface SaveRiskInsightsReportRequest { + data: RiskInsightsReport; +} + +export interface SaveRiskInsightsReportResponse { + id: string; +} + +export interface GetRiskInsightsReportResponse { + id: string; + organizationId: OrganizationId; + // TODO Update to use creationDate from server + date: string; + reportData: EncryptedString; + contentEncryptionKey: EncryptedString; +} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/password-health.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/password-health.ts index 07037f7da6d..872e883e42e 100644 --- a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/password-health.ts +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/password-health.ts @@ -1,75 +1,11 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { Opaque } from "type-fest"; - import { OrganizationId } from "@bitwarden/common/types/guid"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { BadgeVariant } from "@bitwarden/components"; import { EncString } from "@bitwarden/sdk-internal"; -/** - * All applications report summary. The total members, - * total at risk members, application, and at risk application - * counts. Aggregated from all calculated applications - */ -export type ApplicationHealthReportSummary = { - totalMemberCount: number; - totalAtRiskMemberCount: number; - totalApplicationCount: number; - totalAtRiskApplicationCount: number; -}; - -/** - * All applications report detail. Application is the cipher - * uri. Has the at risk, password, and member information - */ -export type ApplicationHealthReportDetail = { - applicationName: string; - passwordCount: number; - atRiskPasswordCount: number; - atRiskCipherIds: string[]; - memberCount: number; - atRiskMemberCount: number; - memberDetails: MemberDetailsFlat[]; - atRiskMemberDetails: MemberDetailsFlat[]; - cipherIds: string[]; -}; - -export type ApplicationHealthReportDetailWithCriticalFlag = ApplicationHealthReportDetail & { - isMarkedAsCritical: boolean; -}; - -export type ApplicationHealthReportDetailWithCriticalFlagAndCipher = - ApplicationHealthReportDetailWithCriticalFlag & { - ciphers: CipherView[]; - }; - -/** - * Breaks the cipher health info out by uri and passes - * along the password health and member info - */ -export type CipherHealthReportUriDetail = { - cipherId: string; - reusedPasswordCount: number; - weakPasswordDetail: WeakPasswordDetail; - exposedPasswordDetail: ExposedPasswordDetail; - cipherMembers: MemberDetailsFlat[]; - trimmedUri: string; - cipher: CipherView; -}; - -/** - * Associates a cipher with it's essential information. - * Gets the password health details, cipher members, and - * the trimmed uris for the cipher - */ -export type CipherHealthReportDetail = CipherView & { - reusedPasswordCount: number; - weakPasswordDetail: WeakPasswordDetail; - exposedPasswordDetail: ExposedPasswordDetail; - cipherMembers: MemberDetailsFlat[]; - trimmedUris: string[]; -}; +import { ApplicationHealthReportDetail } from "./report-models"; /** * Weak password details containing the score @@ -97,41 +33,6 @@ export type ExposedPasswordDetail = { exposedXTimes: number; } | null; -/** - * Flattened member details that associates an - * organization member to a cipher - */ -export type MemberDetailsFlat = { - userGuid: string; - userName: string; - email: string; - cipherId: string; -}; - -/** - * Member email with the number of at risk passwords - * At risk member detail that contains the email - * and the count of at risk ciphers - */ -export type AtRiskMemberDetail = { - email: string; - atRiskPasswordCount: number; -}; - -/* - * A list of applications and the count of - * at risk passwords for each application - */ -export type AtRiskApplicationDetail = { - applicationName: string; - atRiskPasswordCount: number; -}; - -export type AppAtRiskMembersDialogParams = { - members: MemberDetailsFlat[]; - applicationName: string; -}; - /* * After data is encrypted, it is returned with the * encryption key used to encrypt the data. @@ -142,31 +43,39 @@ export interface EncryptedDataWithKey { encryptionKey: EncString; } -/** - * Request to drop a password health report application - * Model is expected by the API endpoint - */ -export interface PasswordHealthReportApplicationDropRequest { - organizationId: OrganizationId; - passwordHealthReportApplicationIds: string[]; -} +export type LEGACY_MemberDetailsFlat = { + userGuid: string; + userName: string; + email: string; + cipherId: string; +}; -/** - * Response from the API after marking an app as critical - */ -export interface PasswordHealthReportApplicationsResponse { - id: PasswordHealthReportApplicationId; - organizationId: OrganizationId; - uri: string; -} -/* - * Request to save a password health report application - * Model is expected by the API endpoint - */ -export interface PasswordHealthReportApplicationsRequest { - organizationId: OrganizationId; - url: string; -} +export type LEGACY_ApplicationHealthReportDetailWithCriticalFlag = ApplicationHealthReportDetail & { + isMarkedAsCritical: boolean; +}; + +export type LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher = + LEGACY_ApplicationHealthReportDetailWithCriticalFlag & { + ciphers: CipherView[]; + }; + +export type LEGACY_CipherHealthReportDetail = CipherView & { + reusedPasswordCount: number; + weakPasswordDetail: WeakPasswordDetail; + exposedPasswordDetail: ExposedPasswordDetail; + cipherMembers: LEGACY_MemberDetailsFlat[]; + trimmedUris: string[]; +}; + +export type LEGACY_CipherHealthReportUriDetail = { + cipherId: string; + reusedPasswordCount: number; + weakPasswordDetail: WeakPasswordDetail; + exposedPasswordDetail: ExposedPasswordDetail; + cipherMembers: LEGACY_MemberDetailsFlat[]; + trimmedUri: string; + cipher: CipherView; +}; export interface EncryptedDataModel { organizationId: OrganizationId; @@ -174,42 +83,3 @@ export interface EncryptedDataModel { encryptionKey: string; date: Date; } - -// FIXME: update to use a const object instead of a typescript enum -// eslint-disable-next-line @bitwarden/platform/no-enums -export enum DrawerType { - None = 0, - AppAtRiskMembers = 1, - OrgAtRiskMembers = 2, - OrgAtRiskApps = 3, -} - -export interface RiskInsightsReport { - organizationId: OrganizationId; - date: string; - reportData: string; - reportKey: string; -} - -export interface ReportInsightsReportData { - data: ApplicationHealthReportDetail[]; - summary: ApplicationHealthReportSummary; -} - -export interface SaveRiskInsightsReportRequest { - data: RiskInsightsReport; -} - -export interface SaveRiskInsightsReportResponse { - id: string; -} - -export interface GetRiskInsightsReportResponse { - id: string; - organizationId: OrganizationId; - date: string; - reportData: EncString; - reportKey: EncString; -} - -export type PasswordHealthReportApplicationId = Opaque; diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/report-models.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/report-models.ts new file mode 100644 index 00000000000..631170be4f9 --- /dev/null +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/report-models.ts @@ -0,0 +1,162 @@ +import { Opaque } from "type-fest"; + +import { OrganizationId } from "@bitwarden/common/types/guid"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { BadgeVariant } from "@bitwarden/components"; + +import { ExposedPasswordDetail, WeakPasswordDetail } from "./password-health"; + +// -------------------- Drawer and UI Models -------------------- +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums +export enum DrawerType { + None = 0, + AppAtRiskMembers = 1, + OrgAtRiskMembers = 2, + OrgAtRiskApps = 3, +} + +export type DrawerDetails = { + open: boolean; + invokerId: string; + activeDrawerType: DrawerType; + atRiskMemberDetails?: AtRiskMemberDetail[]; + appAtRiskMembers?: AppAtRiskMembersDialogParams | null; + atRiskAppDetails?: AtRiskApplicationDetail[] | null; +}; + +export type AppAtRiskMembersDialogParams = { + members: MemberDetails[]; + applicationName: string; +}; + +// -------------------- Member Models -------------------- +/** + * Member email with the number of at risk passwords + * At risk member detail that contains the email + * and the count of at risk ciphers + */ +export type AtRiskMemberDetail = { + email: string; + atRiskPasswordCount: number; +}; + +/** + * Flattened member details that associates an + * organization member to a cipher + */ +export type MemberDetails = { + userGuid: string; + userName: string; + email: string; + cipherId: string; +}; + +// -------------------- Cipher Models -------------------- + +export type PasswordHealthData = { + reusedPasswordCount: number; + weakPasswordDetail: WeakPasswordDetail; + exposedPasswordDetail: ExposedPasswordDetail; +}; + +/** + * Associates a cipher with it's essential information. + * Gets the password health details, cipher members, and + * the trimmed uris for the cipher + */ +export type CipherHealthReport = { + applications: string[]; + cipherMembers: MemberDetails[]; + healthData: PasswordHealthData; + cipher: CipherView; +}; + +/** + * Breaks the cipher health info out by uri and passes + * along the password health and member info + */ +export type CipherApplicationView = { + cipherId: string; + cipher: CipherView; + cipherMembers: MemberDetails[]; + application: string; + healthData: PasswordHealthData; +}; + +// -------------------- Application Health Report Models -------------------- +/** + * All applications report summary. The total members, + * total at risk members, application, and at risk application + * counts. Aggregated from all calculated applications + */ +export type ApplicationHealthReportSummary = { + totalMemberCount: number; + totalAtRiskMemberCount: number; + totalApplicationCount: number; + totalAtRiskApplicationCount: number; +}; + +export type CriticalSummaryDetails = { + totalCriticalMembersCount: number; + totalCriticalApplicationsCount: number; +}; + +/** + * All applications report detail. Application is the cipher + * uri. Has the at risk, password, and member information + */ +export type ApplicationHealthReportDetail = { + applicationName: string; + passwordCount: number; + atRiskPasswordCount: number; + atRiskCipherIds: string[]; + memberCount: number; + atRiskMemberCount: number; + memberDetails: MemberDetails[]; + atRiskMemberDetails: MemberDetails[]; + cipherIds: string[]; +}; + +export type ApplicationHealthReportDetailEnriched = ApplicationHealthReportDetail & { + isMarkedAsCritical: boolean; + ciphers: CipherView[]; +}; + +/* + * A list of applications and the count of + * at risk passwords for each application + */ +export type AtRiskApplicationDetail = { + applicationName: string; + atRiskPasswordCount: number; +}; + +// -------------------- Password Health Report Models -------------------- +export type PasswordHealthReportApplicationId = Opaque; + +// -------------------- Risk Insights Report Models -------------------- +export interface RiskInsightsReportData { + data: ApplicationHealthReportDetailEnriched[]; + summary: ApplicationHealthReportSummary; +} +export interface RiskInsightsReport { + organizationId: OrganizationId; + date: string; + reportData: string; + reportKey: string; +} + +export type ReportScore = { label: string; badgeVariant: BadgeVariant; sortOrder: number }; + +export type ReportResult = CipherView & { + score: number; + reportValue: ReportScore; + scoreKey: number; +}; + +export type ReportDetailsAndSummary = { + data: ApplicationHealthReportDetailEnriched[]; + summary: ApplicationHealthReportSummary; + dateCreated: Date; +}; diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/critical-apps-api.service.spec.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/critical-apps-api.service.spec.ts index 5ed88c4cac9..f53bf92c47f 100644 --- a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/critical-apps-api.service.spec.ts +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/critical-apps-api.service.spec.ts @@ -5,10 +5,10 @@ import { OrganizationId } from "@bitwarden/common/types/guid"; import { PasswordHealthReportApplicationDropRequest, - PasswordHealthReportApplicationId, PasswordHealthReportApplicationsRequest, PasswordHealthReportApplicationsResponse, -} from "../models/password-health"; +} from "../models/api-models.types"; +import { PasswordHealthReportApplicationId } from "../models/report-models"; import { CriticalAppsApiService } from "./critical-apps-api.service"; diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/critical-apps-api.service.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/critical-apps-api.service.ts index c02a3686dfd..29d2364f302 100644 --- a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/critical-apps-api.service.ts +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/critical-apps-api.service.ts @@ -7,7 +7,7 @@ import { PasswordHealthReportApplicationDropRequest, PasswordHealthReportApplicationsRequest, PasswordHealthReportApplicationsResponse, -} from "../models/password-health"; +} from "../models/api-models.types"; export class CriticalAppsApiService { constructor(private apiService: ApiService) {} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/critical-apps.service.spec.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/critical-apps.service.spec.ts index 5b40f16ec9e..067d3f887ea 100644 --- a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/critical-apps.service.spec.ts +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/critical-apps.service.spec.ts @@ -12,10 +12,10 @@ import { OrgKey } from "@bitwarden/common/types/key"; import { KeyService } from "@bitwarden/key-management"; import { - PasswordHealthReportApplicationId, PasswordHealthReportApplicationsRequest, PasswordHealthReportApplicationsResponse, -} from "../models/password-health"; +} from "../models/api-models.types"; +import { PasswordHealthReportApplicationId } from "../models/report-models"; import { CriticalAppsApiService } from "./critical-apps-api.service"; import { CriticalAppsService } from "./critical-apps.service"; diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/critical-apps.service.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/critical-apps.service.ts index bdf28624733..be17bb2c0a5 100644 --- a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/critical-apps.service.ts +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/critical-apps.service.ts @@ -22,7 +22,7 @@ import { KeyService } from "@bitwarden/key-management"; import { PasswordHealthReportApplicationsRequest, PasswordHealthReportApplicationsResponse, -} from "../models/password-health"; +} from "../models/api-models.types"; import { CriticalAppsApiService } from "./critical-apps-api.service"; diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-api.service.spec.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-api.service.spec.ts index 50051c39861..ffcdceadad7 100644 --- a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-api.service.spec.ts +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-api.service.spec.ts @@ -4,7 +4,8 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { makeEncString } from "@bitwarden/common/spec"; import { OrganizationId, OrganizationReportId } from "@bitwarden/common/types/guid"; -import { EncryptedDataModel, SaveRiskInsightsReportRequest } from "../models/password-health"; +import { SaveRiskInsightsReportRequest } from "../models/api-models.types"; +import { EncryptedDataModel } from "../models/password-health"; import { RiskInsightsApiService } from "./risk-insights-api.service"; @@ -200,7 +201,9 @@ describe("RiskInsightsApiService", () => { it("Get Applications: should call apiService.send with correct parameters and return an Observable", (done) => { const reportId = "report123" as OrganizationReportId; - const mockResponse: EncryptedDataModel | null = { encryptedData: "abc" } as EncryptedDataModel; + const mockResponse: EncryptedDataModel | null = { + encryptedData: "abc", + } as EncryptedDataModel; mockApiService.send.mockResolvedValueOnce(mockResponse); diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-api.service.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-api.service.ts index 29df485da03..9d8c2291749 100644 --- a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-api.service.ts +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-api.service.ts @@ -4,11 +4,11 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { OrganizationId, OrganizationReportId } from "@bitwarden/common/types/guid"; import { - EncryptedDataModel, GetRiskInsightsReportResponse, SaveRiskInsightsReportRequest, SaveRiskInsightsReportResponse, -} from "../models/password-health"; +} from "../models/api-models.types"; +import { EncryptedDataModel } from "../models/password-health"; export class RiskInsightsApiService { constructor(private apiService: ApiService) {} diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-data.service.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-data.service.ts index 5e6dbcd54b5..81648f08934 100644 --- a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-data.service.ts +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-data.service.ts @@ -5,11 +5,11 @@ import { OrganizationId } from "@bitwarden/common/types/guid"; import { AppAtRiskMembersDialogParams, - ApplicationHealthReportDetail, AtRiskApplicationDetail, AtRiskMemberDetail, DrawerType, -} from "../models/password-health"; + ApplicationHealthReportDetail, +} from "../models/report-models"; import { RiskInsightsReportService } from "./risk-insights-report.service"; export class RiskInsightsDataService { diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-report.service.spec.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-report.service.spec.ts index 1d090f52299..f78018194a5 100644 --- a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-report.service.spec.ts +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-report.service.spec.ts @@ -8,7 +8,7 @@ import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/pass import { OrganizationId, UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; -import { GetRiskInsightsReportResponse } from "../models/password-health"; +import { GetRiskInsightsReportResponse } from "../models/api-models.types"; import { mockCiphers } from "./ciphers.mock"; import { MemberCipherDetailsApiService } from "./member-cipher-details-api.service"; @@ -197,7 +197,7 @@ describe("RiskInsightsReportService", () => { date: new Date().toISOString(), organizationId: "orgId", reportData: "encryptedReportData", - reportKey: "encryptionKey", + contentEncryptionKey: "encryptionKey", } as GetRiskInsightsReportResponse; const organizationId = "orgId" as OrganizationId; @@ -227,7 +227,7 @@ describe("RiskInsightsReportService", () => { date: new Date().toISOString(), organizationId: organizationId as OrganizationId, reportData: "encryptedReportData", - reportKey: "encryptionKey", + contentEncryptionKey: "encryptionKey", } as GetRiskInsightsReportResponse; const decryptedReport = { diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-report.service.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-report.service.ts index a184f7c1abc..e0f43b2b54e 100644 --- a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-report.service.ts +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-report.service.ts @@ -29,20 +29,22 @@ import { getTrimmedCipherUris, getUniqueMembers, } from "../helpers/risk-insights-data-mappers"; +import { + LEGACY_CipherHealthReportDetail, + LEGACY_CipherHealthReportUriDetail, + ExposedPasswordDetail, + LEGACY_MemberDetailsFlat, + WeakPasswordDetail, + WeakPasswordScore, + LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher, +} from "../models/password-health"; import { ApplicationHealthReportDetail, ApplicationHealthReportSummary, AtRiskMemberDetail, AtRiskApplicationDetail, - CipherHealthReportDetail, - CipherHealthReportUriDetail, - ExposedPasswordDetail, - MemberDetailsFlat, - WeakPasswordDetail, - WeakPasswordScore, - ApplicationHealthReportDetailWithCriticalFlagAndCipher, - ReportInsightsReportData, -} from "../models/password-health"; + RiskInsightsReportData, +} from "../models/report-models"; import { MemberCipherDetailsApiService } from "./member-cipher-details-api.service"; import { RiskInsightsApiService } from "./risk-insights-api.service"; @@ -76,7 +78,9 @@ export class RiskInsightsReportService { * @param organizationId * @returns Cipher health report data with members and trimmed uris */ - generateRawDataReport$(organizationId: OrganizationId): Observable { + generateRawDataReport$( + organizationId: OrganizationId, + ): Observable { const allCiphers$ = from(this.cipherService.getAllFromApiForOrganization(organizationId)); const memberCiphers$ = from( this.memberCipherDetailsApiService.getMemberCipherDetails(organizationId), @@ -84,7 +88,7 @@ export class RiskInsightsReportService { const results$ = zip(allCiphers$, memberCiphers$).pipe( map(([allCiphers, memberCiphers]) => { - const details: MemberDetailsFlat[] = memberCiphers.flatMap((dtl) => + const details: LEGACY_MemberDetailsFlat[] = memberCiphers.flatMap((dtl) => dtl.cipherIds.map((c) => getMemberDetailsFlat(dtl.userGuid, dtl.userName, dtl.email, c)), ); return [allCiphers, details] as const; @@ -104,7 +108,7 @@ export class RiskInsightsReportService { */ generateRawDataUriReport$( organizationId: OrganizationId, - ): Observable { + ): Observable { const cipherHealthDetails$ = this.generateRawDataReport$(organizationId); const results$ = cipherHealthDetails$.pipe( map((healthDetails) => this.getCipherUriDetails(healthDetails)), @@ -206,7 +210,7 @@ export class RiskInsightsReportService { async identifyCiphers( data: ApplicationHealthReportDetail[], organizationId: OrganizationId, - ): Promise { + ): Promise { const cipherViews = await this.cipherService.getAllFromApiForOrganization(organizationId); const dataWithCiphers = data.map( @@ -214,7 +218,7 @@ export class RiskInsightsReportService { ({ ...app, ciphers: cipherViews.filter((c) => app.cipherIds.some((a) => a === c.id)), - }) as ApplicationHealthReportDetailWithCriticalFlagAndCipher, + }) as LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher, ); return dataWithCiphers; } @@ -226,7 +230,7 @@ export class RiskInsightsReportService { switchMap((response) => { if (!response) { // Return an empty report and summary if response is falsy - return of({ + return of({ data: [], summary: { totalMemberCount: 0, @@ -237,12 +241,12 @@ export class RiskInsightsReportService { }); } return from( - this.riskInsightsEncryptionService.decryptRiskInsightsReport( + this.riskInsightsEncryptionService.decryptRiskInsightsReport( organizationId, userId, new EncString(response.reportData), - new EncString(response.reportKey), - (data) => data as ReportInsightsReportData, + new EncString(response.contentEncryptionKey), + (data) => data as RiskInsightsReportData, ), ); }), @@ -297,9 +301,9 @@ export class RiskInsightsReportService { */ private async getCipherDetails( ciphers: CipherView[], - memberDetails: MemberDetailsFlat[], - ): Promise { - const cipherHealthReports: CipherHealthReportDetail[] = []; + memberDetails: LEGACY_MemberDetailsFlat[], + ): Promise { + const cipherHealthReports: LEGACY_CipherHealthReportDetail[] = []; const passwordUseMap = new Map(); const exposedDetails = await this.findExposedPasswords(ciphers); for (const cipher of ciphers) { @@ -329,7 +333,7 @@ export class RiskInsightsReportService { exposedPasswordDetail: exposedPassword, cipherMembers: cipherMembers, trimmedUris: cipherTrimmedUris, - } as CipherHealthReportDetail; + } as LEGACY_CipherHealthReportDetail; cipherHealthReports.push(cipherHealth); } @@ -348,8 +352,8 @@ export class RiskInsightsReportService { * @returns Flattened cipher health details to uri */ private getCipherUriDetails( - cipherHealthReport: CipherHealthReportDetail[], - ): CipherHealthReportUriDetail[] { + cipherHealthReport: LEGACY_CipherHealthReportDetail[], + ): LEGACY_CipherHealthReportUriDetail[] { return cipherHealthReport.flatMap((rpt) => rpt.trimmedUris.map((u) => getFlattenedCipherDetails(rpt, u)), ); @@ -362,7 +366,7 @@ export class RiskInsightsReportService { * @returns Application health reports */ private getApplicationHealthReport( - cipherHealthUriReport: CipherHealthReportUriDetail[], + cipherHealthUriReport: LEGACY_CipherHealthReportUriDetail[], ): ApplicationHealthReportDetail[] { const appReports: ApplicationHealthReportDetail[] = []; cipherHealthUriReport.forEach((uri) => { diff --git a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/all-applications.component.ts b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/all-applications.component.ts index e8a69ddec25..50f2d6de687 100644 --- a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/all-applications.component.ts +++ b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/all-applications.component.ts @@ -11,11 +11,13 @@ import { RiskInsightsReportService, } from "@bitwarden/bit-common/dirt/reports/risk-insights"; import { - ApplicationHealthReportDetail, - ApplicationHealthReportDetailWithCriticalFlag, - ApplicationHealthReportDetailWithCriticalFlagAndCipher, - ApplicationHealthReportSummary, + LEGACY_ApplicationHealthReportDetailWithCriticalFlag, + LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher, } from "@bitwarden/bit-common/dirt/reports/risk-insights/models/password-health"; +import { + ApplicationHealthReportDetail, + ApplicationHealthReportSummary, +} from "@bitwarden/bit-common/dirt/reports/risk-insights/models/report-models"; import { RiskInsightsEncryptionService } from "@bitwarden/bit-common/dirt/reports/risk-insights/services/risk-insights-encryption.service"; import { getOrganizationById, @@ -60,7 +62,7 @@ import { ApplicationsLoadingComponent } from "./risk-insights-loading.component" }) export class AllApplicationsComponent implements OnInit { protected dataSource = - new TableDataSource(); + new TableDataSource(); protected selectedUrls: Set = new Set(); protected searchControl = new FormControl("", { nonNullable: true }); protected loading = true; @@ -99,7 +101,7 @@ export class AllApplicationsComponent implements OnInit { const data = applications?.map((app) => ({ ...app, isMarkedAsCritical: criticalUrls.includes(app.applicationName), - })) as ApplicationHealthReportDetailWithCriticalFlag[]; + })) as LEGACY_ApplicationHealthReportDetailWithCriticalFlag[]; return { data, organization }; } diff --git a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/app-table-row-scrollable.component.ts b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/app-table-row-scrollable.component.ts index c6923bf5c77..e9574413825 100644 --- a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/app-table-row-scrollable.component.ts +++ b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/app-table-row-scrollable.component.ts @@ -2,7 +2,7 @@ import { CommonModule } from "@angular/common"; import { Component, Input } from "@angular/core"; import { JslibModule } from "@bitwarden/angular/jslib.module"; -import { ApplicationHealthReportDetailWithCriticalFlagAndCipher } from "@bitwarden/bit-common/dirt/reports/risk-insights/models/password-health"; +import { LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher } from "@bitwarden/bit-common/dirt/reports/risk-insights/models/password-health"; import { MenuModule, TableDataSource, TableModule } from "@bitwarden/components"; import { SharedModule } from "@bitwarden/web-vault/app/shared"; import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pipes/pipes.module"; @@ -13,7 +13,8 @@ import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pip templateUrl: "./app-table-row-scrollable.component.html", }) export class AppTableRowScrollableComponent { - @Input() dataSource!: TableDataSource; + @Input() + dataSource!: TableDataSource; @Input() showRowMenuForCriticalApps: boolean = false; @Input() showRowCheckBox: boolean = false; @Input() selectedUrls: Set = new Set(); diff --git a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/critical-applications.component.ts b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/critical-applications.component.ts index 2d28d38c29c..eb5d9bd4499 100644 --- a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/critical-applications.component.ts +++ b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/critical-applications.component.ts @@ -13,10 +13,10 @@ import { RiskInsightsReportService, } from "@bitwarden/bit-common/dirt/reports/risk-insights"; import { - ApplicationHealthReportDetailWithCriticalFlag, - ApplicationHealthReportDetailWithCriticalFlagAndCipher, - ApplicationHealthReportSummary, + LEGACY_ApplicationHealthReportDetailWithCriticalFlag, + LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher, } from "@bitwarden/bit-common/dirt/reports/risk-insights/models/password-health"; +import { ApplicationHealthReportSummary } from "@bitwarden/bit-common/dirt/reports/risk-insights/models/report-models"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; @@ -51,7 +51,7 @@ import { RiskInsightsTabType } from "./risk-insights.component"; }) export class CriticalApplicationsComponent implements OnInit { protected dataSource = - new TableDataSource(); + new TableDataSource(); protected selectedIds: Set = new Set(); protected searchControl = new FormControl("", { nonNullable: true }); private destroyRef = inject(DestroyRef); @@ -79,7 +79,7 @@ export class CriticalApplicationsComponent implements OnInit { const data = applications?.map((app) => ({ ...app, isMarkedAsCritical: criticalUrls.includes(app.applicationName), - })) as ApplicationHealthReportDetailWithCriticalFlag[]; + })) as LEGACY_ApplicationHealthReportDetailWithCriticalFlag[]; return data?.filter((app) => app.isMarkedAsCritical); }), switchMap(async (data) => { @@ -200,7 +200,7 @@ export class CriticalApplicationsComponent implements OnInit { this.dataService.setDrawerForOrgAtRiskApps(data, invokerId); }; - trackByFunction(_: number, item: ApplicationHealthReportDetailWithCriticalFlag) { + trackByFunction(_: number, item: LEGACY_ApplicationHealthReportDetailWithCriticalFlag) { return item.applicationName; } isDrawerOpenForTableRow = (applicationName: string) => { diff --git a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/risk-insights.component.ts b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/risk-insights.component.ts index 03cd60667b7..b7e440880e3 100644 --- a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/risk-insights.component.ts +++ b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/risk-insights.component.ts @@ -10,11 +10,11 @@ import { CriticalAppsService, RiskInsightsDataService, } from "@bitwarden/bit-common/dirt/reports/risk-insights"; +import { PasswordHealthReportApplicationsResponse } from "@bitwarden/bit-common/dirt/reports/risk-insights/models/api-models.types"; import { ApplicationHealthReportDetail, DrawerType, - PasswordHealthReportApplicationsResponse, -} from "@bitwarden/bit-common/dirt/reports/risk-insights/models/password-health"; +} from "@bitwarden/bit-common/dirt/reports/risk-insights/models/report-models"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";