1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-19 09:43:23 +00:00

[PM-21713] Include CipherId and find Ciphers in Risk Insights report (#14823)

This commit is contained in:
Vijay Oommen
2025-06-04 14:33:46 -05:00
committed by GitHub
parent a17cc0b265
commit 0032d1457f
7 changed files with 80 additions and 17 deletions

View File

@@ -2,7 +2,7 @@ import { Component, DestroyRef, inject, OnInit } from "@angular/core";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
import { FormControl } from "@angular/forms";
import { ActivatedRoute } from "@angular/router";
import { combineLatest, debounceTime, firstValueFrom, map, Observable, of, skipWhile } from "rxjs";
import { combineLatest, debounceTime, firstValueFrom, map, Observable, of, switchMap } from "rxjs";
import {
CriticalAppsService,
@@ -12,6 +12,7 @@ import {
import {
ApplicationHealthReportDetail,
ApplicationHealthReportDetailWithCriticalFlag,
ApplicationHealthReportDetailWithCriticalFlagAndCipher,
ApplicationHealthReportSummary,
} from "@bitwarden/bit-common/dirt/reports/risk-insights/models/password-health";
import {
@@ -56,7 +57,8 @@ import { ApplicationsLoadingComponent } from "./risk-insights-loading.component"
],
})
export class AllApplicationsComponent implements OnInit {
protected dataSource = new TableDataSource<ApplicationHealthReportDetailWithCriticalFlag>();
protected dataSource =
new TableDataSource<ApplicationHealthReportDetailWithCriticalFlagAndCipher>();
protected selectedUrls: Set<string> = new Set<string>();
protected searchControl = new FormControl("", { nonNullable: true });
protected loading = true;
@@ -74,7 +76,7 @@ export class AllApplicationsComponent implements OnInit {
isLoading$: Observable<boolean> = of(false);
async ngOnInit() {
const organizationId = this.activatedRoute.snapshot.paramMap.get("organizationId") ?? "";
const organizationId = this.activatedRoute.snapshot.paramMap.get("organizationId");
const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
if (organizationId) {
@@ -89,14 +91,32 @@ export class AllApplicationsComponent implements OnInit {
])
.pipe(
takeUntilDestroyed(this.destroyRef),
skipWhile(([_, __, organization]) => !organization),
map(([applications, criticalApps, organization]) => {
const criticalUrls = criticalApps.map((ca) => ca.uri);
const data = applications?.map((app) => ({
...app,
isMarkedAsCritical: criticalUrls.includes(app.applicationName),
})) as ApplicationHealthReportDetailWithCriticalFlag[];
return { data, organization };
if (applications && applications.length === 0 && criticalApps && criticalApps) {
const criticalUrls = criticalApps.map((ca) => ca.uri);
const data = applications?.map((app) => ({
...app,
isMarkedAsCritical: criticalUrls.includes(app.applicationName),
})) as ApplicationHealthReportDetailWithCriticalFlag[];
return { data, organization };
}
return { data: applications, organization };
}),
switchMap(async ({ data, organization }) => {
if (data && organization) {
const dataWithCiphers = await this.reportService.identifyCiphers(
data,
organization.id,
);
return {
data: dataWithCiphers,
organization,
};
}
return { data: [], organization };
}),
)
.subscribe(({ data, organization }) => {

View File

@@ -32,7 +32,7 @@
<i class="bwi bwi-star-f" *ngIf="row.isMarkedAsCritical"></i>
</td>
<td bitCell>
<app-vault-icon [cipher]="row.cipher"></app-vault-icon>
<app-vault-icon *ngIf="row.ciphers.length > 0" [cipher]="row.ciphers[0]"></app-vault-icon>
</td>
<td
class="tw-cursor-pointer"

View File

@@ -2,7 +2,7 @@ import { CommonModule } from "@angular/common";
import { Component, Input } from "@angular/core";
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { ApplicationHealthReportDetailWithCriticalFlag } from "@bitwarden/bit-common/dirt/reports/risk-insights/models/password-health";
import { 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,7 @@ import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pip
templateUrl: "./app-table-row-scrollable.component.html",
})
export class AppTableRowScrollableComponent {
@Input() dataSource!: TableDataSource<ApplicationHealthReportDetailWithCriticalFlag>;
@Input() dataSource!: TableDataSource<ApplicationHealthReportDetailWithCriticalFlagAndCipher>;
@Input() showRowMenuForCriticalApps: boolean = false;
@Input() showRowCheckBox: boolean = false;
@Input() selectedUrls: Set<string> = new Set<string>();

View File

@@ -4,7 +4,7 @@ import { Component, DestroyRef, inject, OnInit } from "@angular/core";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
import { FormControl } from "@angular/forms";
import { ActivatedRoute, Router } from "@angular/router";
import { combineLatest, debounceTime, map } from "rxjs";
import { combineLatest, debounceTime, map, switchMap } from "rxjs";
import {
CriticalAppsService,
@@ -13,6 +13,7 @@ import {
} from "@bitwarden/bit-common/dirt/reports/risk-insights";
import {
ApplicationHealthReportDetailWithCriticalFlag,
ApplicationHealthReportDetailWithCriticalFlagAndCipher,
ApplicationHealthReportSummary,
} from "@bitwarden/bit-common/dirt/reports/risk-insights/models/password-health";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
@@ -53,7 +54,8 @@ import { RiskInsightsTabType } from "./risk-insights.component";
providers: [DefaultAdminTaskService],
})
export class CriticalApplicationsComponent implements OnInit {
protected dataSource = new TableDataSource<ApplicationHealthReportDetailWithCriticalFlag>();
protected dataSource =
new TableDataSource<ApplicationHealthReportDetailWithCriticalFlagAndCipher>();
protected selectedIds: Set<number> = new Set<number>();
protected searchControl = new FormControl("", { nonNullable: true });
private destroyRef = inject(DestroyRef);
@@ -68,7 +70,9 @@ export class CriticalApplicationsComponent implements OnInit {
this.isNotificationsFeatureEnabled = await this.configService.getFeatureFlag(
FeatureFlag.EnableRiskInsightsNotifications,
);
this.organizationId = this.activatedRoute.snapshot.paramMap.get("organizationId") ?? "";
combineLatest([
this.dataService.applications$,
this.criticalAppsService.getAppsListForOrg(this.organizationId),
@@ -83,6 +87,16 @@ export class CriticalApplicationsComponent implements OnInit {
})) as ApplicationHealthReportDetailWithCriticalFlag[];
return data?.filter((app) => app.isMarkedAsCritical);
}),
switchMap(async (data) => {
if (data) {
const dataWithCiphers = await this.reportService.identifyCiphers(
data,
this.organizationId,
);
return dataWithCiphers;
}
return null;
}),
)
.subscribe((applications) => {
if (applications) {