1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-12 22:33:35 +00:00

[PM-20132] Total Member Count (#17330)

* PM-20132 total member count

* Apply suggestions from code review

Co-authored-by: Leslie Tilton <23057410+Banrion@users.noreply.github.com>

* PM-20132 updated PR comments

* PM-20132 update as per PR comments

* PM-20132 removed unwanted code

* PM-20132 fixed PR comment from Claude

* PM-20132 reduced ambiguity in code

* PM-20132 removed unwanted observables

* PM-20132 removed default value as it is not needed anymore

* PM-20132 fixed failed test

---------

Co-authored-by: Leslie Tilton <23057410+Banrion@users.noreply.github.com>
This commit is contained in:
Vijay Oommen
2025-11-13 13:33:56 -06:00
committed by GitHub
parent df59f7820a
commit a41c7b79b4
2 changed files with 23 additions and 6 deletions

View File

@@ -42,6 +42,7 @@ import {
createNewSummaryData, createNewSummaryData,
flattenMemberDetails, flattenMemberDetails,
getTrimmedCipherUris, getTrimmedCipherUris,
getUniqueMembers,
} from "../../helpers"; } from "../../helpers";
import { import {
ApplicationHealthReportDetailEnriched, ApplicationHealthReportDetailEnriched,
@@ -234,6 +235,7 @@ export class RiskInsightsOrchestratorService {
const updatedSummaryData = this.reportService.getApplicationsSummary( const updatedSummaryData = this.reportService.getApplicationsSummary(
report!.reportData, report!.reportData,
updatedApplicationData, updatedApplicationData,
report!.summaryData.totalMemberCount,
); );
// Used for creating metrics with updated application data // Used for creating metrics with updated application data
@@ -366,6 +368,7 @@ export class RiskInsightsOrchestratorService {
const updatedSummaryData = this.reportService.getApplicationsSummary( const updatedSummaryData = this.reportService.getApplicationsSummary(
report!.reportData, report!.reportData,
updatedApplicationData, updatedApplicationData,
report!.summaryData.totalMemberCount,
); );
// Used for creating metrics with updated application data // Used for creating metrics with updated application data
@@ -502,6 +505,7 @@ export class RiskInsightsOrchestratorService {
const updatedSummaryData = this.reportService.getApplicationsSummary( const updatedSummaryData = this.reportService.getApplicationsSummary(
report!.reportData, report!.reportData,
updatedApplicationData, updatedApplicationData,
report!.summaryData.totalMemberCount,
); );
// Used for creating metrics with updated application data // Used for creating metrics with updated application data
const manualEnrichedApplications = report!.reportData.map( const manualEnrichedApplications = report!.reportData.map(
@@ -656,19 +660,30 @@ export class RiskInsightsOrchestratorService {
switchMap(([ciphers, memberCiphers]) => { switchMap(([ciphers, memberCiphers]) => {
this.logService.debug("[RiskInsightsOrchestratorService] Analyzing password health"); this.logService.debug("[RiskInsightsOrchestratorService] Analyzing password health");
this._reportProgressSubject.next(ReportProgress.AnalyzingPasswords); 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.logService.debug("[RiskInsightsOrchestratorService] Calculating risk scores");
this._reportProgressSubject.next(ReportProgress.CalculatingRisks); this._reportProgressSubject.next(ReportProgress.CalculatingRisks);
return this.reportService.generateApplicationsReport(cipherHealthReports); const report = this.reportService.generateApplicationsReport(cipherHealthReports);
return { report, totalMemberCount };
}), }),
tap(() => { tap(() => {
this.logService.debug("[RiskInsightsOrchestratorService] Generating report data"); this.logService.debug("[RiskInsightsOrchestratorService] Generating report data");
this._reportProgressSubject.next(ReportProgress.GeneratingReport); this._reportProgressSubject.next(ReportProgress.GeneratingReport);
}), }),
withLatestFrom(this.rawReportData$), withLatestFrom(this.rawReportData$),
map(([report, previousReport]) => { map(([{ report, totalMemberCount }, previousReport]) => {
// Update the application data // Update the application data
const updatedApplicationData = this.reportService.getOrganizationApplications( const updatedApplicationData = this.reportService.getOrganizationApplications(
report, report,
@@ -688,6 +703,7 @@ export class RiskInsightsOrchestratorService {
const updatedSummary = this.reportService.getApplicationsSummary( const updatedSummary = this.reportService.getApplicationsSummary(
report, report,
updatedApplicationData, updatedApplicationData,
totalMemberCount,
); );
// For now, merge the report with the critical marking flag to make the enriched type // 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 // We don't care about the individual ciphers in this instance
@@ -964,6 +980,7 @@ export class RiskInsightsOrchestratorService {
const summary = this.reportService.getApplicationsSummary( const summary = this.reportService.getApplicationsSummary(
criticalApplications, criticalApplications,
enrichedReports.applicationData, enrichedReports.applicationData,
enrichedReports.summaryData.totalMemberCount,
); );
return { return {
...enrichedReports, ...enrichedReports,

View File

@@ -83,8 +83,8 @@ export class RiskInsightsReportService {
getApplicationsSummary( getApplicationsSummary(
reports: ApplicationHealthReportDetail[], reports: ApplicationHealthReportDetail[],
applicationData: OrganizationReportApplication[], applicationData: OrganizationReportApplication[],
totalMemberCount: number,
): OrganizationReportSummary { ): OrganizationReportSummary {
const totalUniqueMembers = getUniqueMembers(reports.flatMap((x) => x.memberDetails));
const atRiskUniqueMembers = getUniqueMembers(reports.flatMap((x) => x.atRiskMemberDetails)); const atRiskUniqueMembers = getUniqueMembers(reports.flatMap((x) => x.atRiskMemberDetails));
const criticalReports = this.filterApplicationsByCritical(reports, applicationData); const criticalReports = this.filterApplicationsByCritical(reports, applicationData);
@@ -94,7 +94,7 @@ export class RiskInsightsReportService {
); );
return { return {
totalMemberCount: totalUniqueMembers.length, totalMemberCount: totalMemberCount,
totalAtRiskMemberCount: atRiskUniqueMembers.length, totalAtRiskMemberCount: atRiskUniqueMembers.length,
totalApplicationCount: reports.length, totalApplicationCount: reports.length,
totalAtRiskApplicationCount: reports.filter((app) => app.atRiskPasswordCount > 0).length, totalAtRiskApplicationCount: reports.filter((app) => app.atRiskPasswordCount > 0).length,