diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/domain/risk-insights-orchestrator.service.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/domain/risk-insights-orchestrator.service.ts index 59affad10da..38e12373182 100644 --- a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/domain/risk-insights-orchestrator.service.ts +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/domain/risk-insights-orchestrator.service.ts @@ -42,6 +42,7 @@ import { createNewSummaryData, flattenMemberDetails, getTrimmedCipherUris, + getUniqueMembers, } from "../../helpers"; import { ApplicationHealthReportDetailEnriched, @@ -234,6 +235,7 @@ export class RiskInsightsOrchestratorService { const updatedSummaryData = this.reportService.getApplicationsSummary( report!.reportData, updatedApplicationData, + report!.summaryData.totalMemberCount, ); // Used for creating metrics with updated application data @@ -366,6 +368,7 @@ export class RiskInsightsOrchestratorService { const updatedSummaryData = this.reportService.getApplicationsSummary( report!.reportData, updatedApplicationData, + report!.summaryData.totalMemberCount, ); // Used for creating metrics with updated application data @@ -502,6 +505,7 @@ export class RiskInsightsOrchestratorService { const updatedSummaryData = this.reportService.getApplicationsSummary( report!.reportData, updatedApplicationData, + report!.summaryData.totalMemberCount, ); // Used for creating metrics with updated application data const manualEnrichedApplications = report!.reportData.map( @@ -656,19 +660,30 @@ export class RiskInsightsOrchestratorService { switchMap(([ciphers, memberCiphers]) => { this.logService.debug("[RiskInsightsOrchestratorService] Analyzing password health"); this._reportProgressSubject.next(ReportProgress.AnalyzingPasswords); - return this._getCipherHealth(ciphers ?? [], memberCiphers); + return forkJoin({ + memberDetails: of(memberCiphers), + cipherHealthReports: this._getCipherHealth(ciphers ?? [], memberCiphers), + }).pipe( + map(({ memberDetails, cipherHealthReports }) => { + const uniqueMembers = getUniqueMembers(memberDetails); + const totalMemberCount = uniqueMembers.length; + + return { cipherHealthReports, totalMemberCount }; + }), + ); }), - map((cipherHealthReports) => { + map(({ cipherHealthReports, totalMemberCount }) => { this.logService.debug("[RiskInsightsOrchestratorService] Calculating risk scores"); this._reportProgressSubject.next(ReportProgress.CalculatingRisks); - return this.reportService.generateApplicationsReport(cipherHealthReports); + const report = this.reportService.generateApplicationsReport(cipherHealthReports); + return { report, totalMemberCount }; }), tap(() => { this.logService.debug("[RiskInsightsOrchestratorService] Generating report data"); this._reportProgressSubject.next(ReportProgress.GeneratingReport); }), withLatestFrom(this.rawReportData$), - map(([report, previousReport]) => { + map(([{ report, totalMemberCount }, previousReport]) => { // Update the application data const updatedApplicationData = this.reportService.getOrganizationApplications( report, @@ -688,6 +703,7 @@ export class RiskInsightsOrchestratorService { const updatedSummary = this.reportService.getApplicationsSummary( report, updatedApplicationData, + totalMemberCount, ); // For now, merge the report with the critical marking flag to make the enriched type // We don't care about the individual ciphers in this instance @@ -964,6 +980,7 @@ export class RiskInsightsOrchestratorService { const summary = this.reportService.getApplicationsSummary( criticalApplications, enrichedReports.applicationData, + enrichedReports.summaryData.totalMemberCount, ); return { ...enrichedReports, diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/domain/risk-insights-report.service.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/domain/risk-insights-report.service.ts index 94c9c85f955..37b788a8e3d 100644 --- a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/domain/risk-insights-report.service.ts +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/domain/risk-insights-report.service.ts @@ -83,8 +83,8 @@ export class RiskInsightsReportService { getApplicationsSummary( reports: ApplicationHealthReportDetail[], applicationData: OrganizationReportApplication[], + totalMemberCount: number, ): OrganizationReportSummary { - const totalUniqueMembers = getUniqueMembers(reports.flatMap((x) => x.memberDetails)); const atRiskUniqueMembers = getUniqueMembers(reports.flatMap((x) => x.atRiskMemberDetails)); const criticalReports = this.filterApplicationsByCritical(reports, applicationData); @@ -94,7 +94,7 @@ export class RiskInsightsReportService { ); return { - totalMemberCount: totalUniqueMembers.length, + totalMemberCount: totalMemberCount, totalAtRiskMemberCount: atRiskUniqueMembers.length, totalApplicationCount: reports.length, totalAtRiskApplicationCount: reports.filter((app) => app.atRiskPasswordCount > 0).length,