mirror of
https://github.com/bitwarden/browser
synced 2025-12-18 09:13:33 +00:00
[PM-23680] Report Applications data (#16819)
* Move files to folders. Delete unused component. Move model to file * Move risk insights services to folder structure capturing domains, api, and view organization. Move mock data * Remove legacy risk insight report code * Move api model to file * Separate data service and orchestration of data to make the data service a facade * Add orchestration updates for fetching applications as well as migrating data. * Updated migration of critical applications and merged old saved data to new critical applications on report object * Update test cases * Fixed test case after merge. Cleaned up per comments on review * Fixed decryption and encryption issue when not using existing content key * Fix type errors * Fix test update * Fixe remove critical applications * Fix report generating flag not being reset * Removed extra logs
This commit is contained in:
@@ -12,7 +12,8 @@ import {
|
||||
RiskInsightsReportService,
|
||||
SecurityTasksApiService,
|
||||
} from "@bitwarden/bit-common/dirt/reports/risk-insights/services";
|
||||
import { RiskInsightsEncryptionService } from "@bitwarden/bit-common/dirt/reports/risk-insights/services/risk-insights-encryption.service";
|
||||
import { RiskInsightsEncryptionService } from "@bitwarden/bit-common/dirt/reports/risk-insights/services/domain/risk-insights-encryption.service";
|
||||
import { RiskInsightsOrchestratorService } from "@bitwarden/bit-common/dirt/reports/risk-insights/services/domain/risk-insights-orchestrator.service";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
@@ -24,6 +25,7 @@ import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/pass
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { ToastService } from "@bitwarden/components";
|
||||
import { KeyService } from "@bitwarden/key-management";
|
||||
import { LogService } from "@bitwarden/logging";
|
||||
|
||||
import { DefaultAdminTaskService } from "../../vault/services/default-admin-task.service";
|
||||
|
||||
@@ -52,28 +54,31 @@ import { AccessIntelligenceSecurityTasksService } from "./shared/security-tasks.
|
||||
safeProvider({
|
||||
provide: RiskInsightsReportService,
|
||||
useClass: RiskInsightsReportService,
|
||||
deps: [RiskInsightsApiService, RiskInsightsEncryptionService],
|
||||
}),
|
||||
safeProvider({
|
||||
provide: RiskInsightsOrchestratorService,
|
||||
deps: [
|
||||
AccountServiceAbstraction,
|
||||
CipherService,
|
||||
CriticalAppsService,
|
||||
LogService,
|
||||
MemberCipherDetailsApiService,
|
||||
OrganizationService,
|
||||
PasswordHealthService,
|
||||
RiskInsightsApiService,
|
||||
RiskInsightsReportService,
|
||||
RiskInsightsEncryptionService,
|
||||
],
|
||||
}),
|
||||
safeProvider({
|
||||
provide: RiskInsightsDataService,
|
||||
deps: [
|
||||
AccountServiceAbstraction,
|
||||
CriticalAppsService,
|
||||
OrganizationService,
|
||||
RiskInsightsReportService,
|
||||
],
|
||||
deps: [RiskInsightsOrchestratorService],
|
||||
}),
|
||||
{
|
||||
safeProvider({
|
||||
provide: RiskInsightsEncryptionService,
|
||||
useClass: RiskInsightsEncryptionService,
|
||||
deps: [KeyService, EncryptService, KeyGenerationService],
|
||||
},
|
||||
deps: [KeyService, EncryptService, KeyGenerationService, LogService],
|
||||
}),
|
||||
safeProvider({
|
||||
provide: CriticalAppsService,
|
||||
useClass: CriticalAppsService,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { Component, OnInit, ChangeDetectionStrategy } from "@angular/core";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { Subject, switchMap, takeUntil, of, BehaviorSubject, combineLatest } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import {
|
||||
AllActivitiesService,
|
||||
LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher,
|
||||
ApplicationHealthReportDetailEnriched,
|
||||
SecurityTasksApiService,
|
||||
TaskMetrics,
|
||||
OrganizationReportSummary,
|
||||
@@ -14,17 +14,12 @@ import {
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { ButtonModule, ProgressModule, TypographyModule } from "@bitwarden/components";
|
||||
|
||||
import { DefaultAdminTaskService } from "../../../vault/services/default-admin-task.service";
|
||||
import { AccessIntelligenceSecurityTasksService } from "../shared/security-tasks.service";
|
||||
|
||||
export const RenderMode = {
|
||||
noCriticalApps: "noCriticalApps",
|
||||
criticalAppsWithAtRiskAppsAndNoTasks: "criticalAppsWithAtRiskAppsAndNoTasks",
|
||||
criticalAppsWithAtRiskAppsAndTasks: "criticalAppsWithAtRiskAppsAndTasks",
|
||||
} as const;
|
||||
export type RenderMode = (typeof RenderMode)[keyof typeof RenderMode];
|
||||
import { DefaultAdminTaskService } from "../../../../vault/services/default-admin-task.service";
|
||||
import { RenderMode } from "../../models/activity.models";
|
||||
import { AccessIntelligenceSecurityTasksService } from "../../shared/security-tasks.service";
|
||||
|
||||
@Component({
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
selector: "dirt-password-change-metric",
|
||||
imports: [CommonModule, TypographyModule, JslibModule, ProgressModule, ButtonModule],
|
||||
templateUrl: "./password-change-metric.component.html",
|
||||
@@ -34,8 +29,7 @@ export class PasswordChangeMetricComponent implements OnInit {
|
||||
protected taskMetrics$ = new BehaviorSubject<TaskMetrics>({ totalTasks: 0, completedTasks: 0 });
|
||||
private completedTasks: number = 0;
|
||||
private totalTasks: number = 0;
|
||||
private allApplicationsDetails: LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher[] =
|
||||
[];
|
||||
private allApplicationsDetails: ApplicationHealthReportDetailEnriched[] = [];
|
||||
|
||||
atRiskAppsCount: number = 0;
|
||||
atRiskPasswordsCount: number = 0;
|
||||
@@ -43,6 +37,13 @@ export class PasswordChangeMetricComponent implements OnInit {
|
||||
private destroyRef = new Subject<void>();
|
||||
renderMode: RenderMode = "noCriticalApps";
|
||||
|
||||
constructor(
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private securityTasksApiService: SecurityTasksApiService,
|
||||
private allActivitiesService: AllActivitiesService,
|
||||
protected accessIntelligenceSecurityTasksService: AccessIntelligenceSecurityTasksService,
|
||||
) {}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
combineLatest([this.activatedRoute.paramMap, this.allActivitiesService.taskCreatedCount$])
|
||||
.pipe(
|
||||
@@ -83,13 +84,6 @@ export class PasswordChangeMetricComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
constructor(
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private securityTasksApiService: SecurityTasksApiService,
|
||||
private allActivitiesService: AllActivitiesService,
|
||||
protected accessIntelligenceSecurityTasksService: AccessIntelligenceSecurityTasksService,
|
||||
) {}
|
||||
|
||||
private determineRenderMode(
|
||||
summary: OrganizationReportSummary,
|
||||
taskMetrics: TaskMetrics,
|
||||
@@ -11,16 +11,16 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { getById } from "@bitwarden/common/platform/misc";
|
||||
import { ToastService, DialogService } from "@bitwarden/components";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
import { SharedModule } from "@bitwarden/web-vault/app/shared";
|
||||
|
||||
import { RiskInsightsTabType } from "../models/risk-insights.models";
|
||||
import { ApplicationsLoadingComponent } from "../shared/risk-insights-loading.component";
|
||||
|
||||
import { ActivityCardComponent } from "./activity-card.component";
|
||||
import { PasswordChangeMetricComponent } from "./activity-cards/password-change-metric.component";
|
||||
import { NewApplicationsDialogComponent } from "./new-applications-dialog.component";
|
||||
import { ApplicationsLoadingComponent } from "./risk-insights-loading.component";
|
||||
import { RiskInsightsTabType } from "./risk-insights.component";
|
||||
|
||||
@Component({
|
||||
selector: "dirt-all-activity",
|
||||
@@ -43,6 +43,15 @@ export class AllActivityComponent implements OnInit {
|
||||
|
||||
destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private accountService: AccountService,
|
||||
protected activatedRoute: ActivatedRoute,
|
||||
protected allActivitiesService: AllActivitiesService,
|
||||
protected dataService: RiskInsightsDataService,
|
||||
private dialogService: DialogService,
|
||||
protected organizationService: OrganizationService,
|
||||
) {}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
const organizationId = this.activatedRoute.snapshot.paramMap.get("organizationId");
|
||||
const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
|
||||
@@ -71,17 +80,6 @@ export class AllActivityComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
constructor(
|
||||
protected activatedRoute: ActivatedRoute,
|
||||
private accountService: AccountService,
|
||||
protected organizationService: OrganizationService,
|
||||
protected dataService: RiskInsightsDataService,
|
||||
protected allActivitiesService: AllActivitiesService,
|
||||
private toastService: ToastService,
|
||||
private i18nService: I18nService,
|
||||
private dialogService: DialogService,
|
||||
) {}
|
||||
|
||||
get RiskInsightsTabType() {
|
||||
return RiskInsightsTabType;
|
||||
}
|
||||
@@ -25,8 +25,8 @@ import { HeaderModule } from "@bitwarden/web-vault/app/layouts/header/header.mod
|
||||
import { SharedModule } from "@bitwarden/web-vault/app/shared";
|
||||
import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pipes/pipes.module";
|
||||
|
||||
import { AppTableRowScrollableComponent } from "./app-table-row-scrollable.component";
|
||||
import { ApplicationsLoadingComponent } from "./risk-insights-loading.component";
|
||||
import { AppTableRowScrollableComponent } from "../shared/app-table-row-scrollable.component";
|
||||
import { ApplicationsLoadingComponent } from "../shared/risk-insights-loading.component";
|
||||
|
||||
@Component({
|
||||
selector: "dirt-all-applications",
|
||||
@@ -67,7 +67,7 @@ export class AllApplicationsComponent implements OnInit {
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.dataService.reportResults$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
|
||||
this.dataService.enrichedReportData$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
|
||||
next: (report) => {
|
||||
this.applicationSummary = report?.summaryData ?? createNewSummaryData();
|
||||
this.dataSource.data = report?.reportData ?? [];
|
||||
@@ -23,11 +23,10 @@ import { HeaderModule } from "@bitwarden/web-vault/app/layouts/header/header.mod
|
||||
import { SharedModule } from "@bitwarden/web-vault/app/shared";
|
||||
import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pipes/pipes.module";
|
||||
|
||||
import { DefaultAdminTaskService } from "../../vault/services/default-admin-task.service";
|
||||
|
||||
import { AppTableRowScrollableComponent } from "./app-table-row-scrollable.component";
|
||||
import { RiskInsightsTabType } from "./risk-insights.component";
|
||||
import { AccessIntelligenceSecurityTasksService } from "./shared/security-tasks.service";
|
||||
import { DefaultAdminTaskService } from "../../../vault/services/default-admin-task.service";
|
||||
import { RiskInsightsTabType } from "../models/risk-insights.models";
|
||||
import { AppTableRowScrollableComponent } from "../shared/app-table-row-scrollable.component";
|
||||
import { AccessIntelligenceSecurityTasksService } from "../shared/security-tasks.service";
|
||||
|
||||
@Component({
|
||||
selector: "dirt-critical-applications",
|
||||
@@ -0,0 +1,7 @@
|
||||
export const RenderMode = {
|
||||
noCriticalApps: "noCriticalApps",
|
||||
criticalAppsWithAtRiskAppsAndNoTasks: "criticalAppsWithAtRiskAppsAndNoTasks",
|
||||
criticalAppsWithAtRiskAppsAndTasks: "criticalAppsWithAtRiskAppsAndTasks",
|
||||
} as const;
|
||||
|
||||
export type RenderMode = (typeof RenderMode)[keyof typeof RenderMode];
|
||||
@@ -0,0 +1,8 @@
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum RiskInsightsTabType {
|
||||
AllActivity = 0,
|
||||
AllApps = 1,
|
||||
CriticalApps = 2,
|
||||
NotifiedMembers = 3,
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<!-- <bit-table [dataSource]="dataSource"> -->
|
||||
<ng-container header>
|
||||
<tr>
|
||||
<th bitCell>{{ "member" | i18n }}</th>
|
||||
<th bitCell>{{ "atRiskPasswords" | i18n }}</th>
|
||||
<th bitCell>{{ "totalPasswords" | i18n }}</th>
|
||||
<th bitCell>{{ "atRiskApplications" | i18n }}</th>
|
||||
<th bitCell>{{ "totalApplications" | i18n }}</th>
|
||||
</tr>
|
||||
</ng-container>
|
||||
<!-- </bit-table> -->
|
||||
@@ -1,18 +0,0 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component } from "@angular/core";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { TableDataSource, TableModule } from "@bitwarden/components";
|
||||
|
||||
@Component({
|
||||
selector: "tools-notified-members-table",
|
||||
templateUrl: "./notified-members-table.component.html",
|
||||
imports: [CommonModule, JslibModule, TableModule],
|
||||
})
|
||||
export class NotifiedMembersTableComponent {
|
||||
dataSource = new TableDataSource<any>();
|
||||
|
||||
constructor() {
|
||||
this.dataSource.data = [];
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
} @else {
|
||||
<span class="tw-mx-4">{{ "noReportRan" | i18n }}</span>
|
||||
}
|
||||
@let isRunningReport = dataService.isRunningReport$ | async;
|
||||
@let isRunningReport = dataService.isGeneratingReport$ | async;
|
||||
<span class="tw-flex tw-justify-center">
|
||||
<button
|
||||
*ngIf="!isRunningReport"
|
||||
@@ -26,7 +26,7 @@
|
||||
buttonType="secondary"
|
||||
class="tw-border-none !tw-font-normal tw-cursor-pointer !tw-py-0"
|
||||
tabindex="0"
|
||||
[bitAction]="refreshData.bind(this)"
|
||||
[bitAction]="generateReport.bind(this)"
|
||||
>
|
||||
{{ "riskInsightsRunReport" | i18n }}
|
||||
</button>
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component, DestroyRef, OnInit, inject } from "@angular/core";
|
||||
import { Component, DestroyRef, OnDestroy, OnInit, inject } from "@angular/core";
|
||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { EMPTY } from "rxjs";
|
||||
import { map, switchMap } from "rxjs/operators";
|
||||
import { map, tap } from "rxjs/operators";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { RiskInsightsDataService } from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
||||
import { DrawerType } from "@bitwarden/bit-common/dirt/reports/risk-insights/models/report-models";
|
||||
import {
|
||||
DrawerType,
|
||||
RiskInsightsDataService,
|
||||
} from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
@@ -21,18 +23,10 @@ import {
|
||||
} from "@bitwarden/components";
|
||||
import { HeaderModule } from "@bitwarden/web-vault/app/layouts/header/header.module";
|
||||
|
||||
import { AllActivityComponent } from "./all-activity.component";
|
||||
import { AllApplicationsComponent } from "./all-applications.component";
|
||||
import { CriticalApplicationsComponent } from "./critical-applications.component";
|
||||
|
||||
// FIXME: update to use a const object instead of a typescript enum
|
||||
// eslint-disable-next-line @bitwarden/platform/no-enums
|
||||
export enum RiskInsightsTabType {
|
||||
AllActivity = 0,
|
||||
AllApps = 1,
|
||||
CriticalApps = 2,
|
||||
NotifiedMembers = 3,
|
||||
}
|
||||
import { AllActivityComponent } from "./activity/all-activity.component";
|
||||
import { AllApplicationsComponent } from "./all-applications/all-applications.component";
|
||||
import { CriticalApplicationsComponent } from "./critical-applications/critical-applications.component";
|
||||
import { RiskInsightsTabType } from "./models/risk-insights.models";
|
||||
|
||||
@Component({
|
||||
templateUrl: "./risk-insights.component.html",
|
||||
@@ -51,7 +45,7 @@ export enum RiskInsightsTabType {
|
||||
AllActivityComponent,
|
||||
],
|
||||
})
|
||||
export class RiskInsightsComponent implements OnInit {
|
||||
export class RiskInsightsComponent implements OnInit, OnDestroy {
|
||||
private destroyRef = inject(DestroyRef);
|
||||
private _isDrawerOpen: boolean = false;
|
||||
|
||||
@@ -65,7 +59,6 @@ export class RiskInsightsComponent implements OnInit {
|
||||
private organizationId: OrganizationId = "" as OrganizationId;
|
||||
|
||||
dataLastUpdated: Date | null = null;
|
||||
refetching: boolean = false;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
@@ -91,11 +84,10 @@ export class RiskInsightsComponent implements OnInit {
|
||||
.pipe(
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
map((params) => params.get("organizationId")),
|
||||
switchMap(async (orgId) => {
|
||||
tap((orgId) => {
|
||||
if (orgId) {
|
||||
// Initialize Data Service
|
||||
await this.dataService.initializeForOrganization(orgId as OrganizationId);
|
||||
|
||||
this.dataService.initializeForOrganization(orgId as OrganizationId);
|
||||
this.organizationId = orgId as OrganizationId;
|
||||
} else {
|
||||
return EMPTY;
|
||||
@@ -105,7 +97,7 @@ export class RiskInsightsComponent implements OnInit {
|
||||
.subscribe();
|
||||
|
||||
// Subscribe to report result details
|
||||
this.dataService.reportResults$
|
||||
this.dataService.enrichedReportData$
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((report) => {
|
||||
this.appsCount = report?.reportData.length ?? 0;
|
||||
@@ -119,15 +111,16 @@ export class RiskInsightsComponent implements OnInit {
|
||||
this._isDrawerOpen = details.open;
|
||||
});
|
||||
}
|
||||
runReport = () => {
|
||||
this.dataService.triggerReport();
|
||||
};
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.dataService.destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the data by re-fetching the applications report.
|
||||
* This will automatically notify child components subscribed to the RiskInsightsDataService observables.
|
||||
*/
|
||||
refreshData(): void {
|
||||
generateReport(): void {
|
||||
if (this.organizationId) {
|
||||
this.dataService.triggerReport();
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { mock } from "jest-mock-extended";
|
||||
|
||||
import {
|
||||
AllActivitiesService,
|
||||
LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher,
|
||||
ApplicationHealthReportDetailEnriched,
|
||||
} from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
@@ -43,7 +43,7 @@ describe("AccessIntelligenceSecurityTasksService", () => {
|
||||
isMarkedAsCritical: true,
|
||||
atRiskPasswordCount: 1,
|
||||
atRiskCipherIds: ["cid1"],
|
||||
} as LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher,
|
||||
} as ApplicationHealthReportDetailEnriched,
|
||||
];
|
||||
const spy = jest.spyOn(service, "requestPasswordChange").mockResolvedValue(2);
|
||||
await service.assignTasks(organizationId, apps);
|
||||
@@ -60,12 +60,12 @@ describe("AccessIntelligenceSecurityTasksService", () => {
|
||||
isMarkedAsCritical: true,
|
||||
atRiskPasswordCount: 2,
|
||||
atRiskCipherIds: ["cid1", "cid2"],
|
||||
} as LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher,
|
||||
} as ApplicationHealthReportDetailEnriched,
|
||||
{
|
||||
isMarkedAsCritical: true,
|
||||
atRiskPasswordCount: 1,
|
||||
atRiskCipherIds: ["cid2"],
|
||||
} as LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher,
|
||||
} as ApplicationHealthReportDetailEnriched,
|
||||
];
|
||||
defaultAdminTaskServiceSpy.bulkCreateTasks.mockResolvedValue(undefined);
|
||||
i18nServiceSpy.t.mockImplementation((key) => key);
|
||||
@@ -91,7 +91,7 @@ describe("AccessIntelligenceSecurityTasksService", () => {
|
||||
isMarkedAsCritical: true,
|
||||
atRiskPasswordCount: 1,
|
||||
atRiskCipherIds: ["cid3"],
|
||||
} as LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher,
|
||||
} as ApplicationHealthReportDetailEnriched,
|
||||
];
|
||||
defaultAdminTaskServiceSpy.bulkCreateTasks.mockRejectedValue(new Error("fail"));
|
||||
i18nServiceSpy.t.mockImplementation((key) => key);
|
||||
@@ -113,7 +113,7 @@ describe("AccessIntelligenceSecurityTasksService", () => {
|
||||
isMarkedAsCritical: true,
|
||||
atRiskPasswordCount: 0,
|
||||
atRiskCipherIds: ["cid4"],
|
||||
} as LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher,
|
||||
} as ApplicationHealthReportDetailEnriched,
|
||||
];
|
||||
const result = await service.requestPasswordChange(organizationId, apps);
|
||||
|
||||
@@ -128,7 +128,7 @@ describe("AccessIntelligenceSecurityTasksService", () => {
|
||||
isMarkedAsCritical: false,
|
||||
atRiskPasswordCount: 2,
|
||||
atRiskCipherIds: ["cid5", "cid6"],
|
||||
} as LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher,
|
||||
} as ApplicationHealthReportDetailEnriched,
|
||||
];
|
||||
const result = await service.requestPasswordChange(organizationId, apps);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Injectable } from "@angular/core";
|
||||
|
||||
import {
|
||||
AllActivitiesService,
|
||||
LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher,
|
||||
ApplicationHealthReportDetailEnriched,
|
||||
} from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { CipherId, OrganizationId } from "@bitwarden/common/types/guid";
|
||||
@@ -20,10 +20,7 @@ export class AccessIntelligenceSecurityTasksService {
|
||||
private toastService: ToastService,
|
||||
private i18nService: I18nService,
|
||||
) {}
|
||||
async assignTasks(
|
||||
organizationId: OrganizationId,
|
||||
apps: LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher[],
|
||||
) {
|
||||
async assignTasks(organizationId: OrganizationId, apps: ApplicationHealthReportDetailEnriched[]) {
|
||||
const taskCount = await this.requestPasswordChange(organizationId, apps);
|
||||
this.allActivitiesService.setTaskCreatedCount(taskCount);
|
||||
}
|
||||
@@ -31,7 +28,7 @@ export class AccessIntelligenceSecurityTasksService {
|
||||
// TODO: this method is shared between here and critical-applications.component.ts
|
||||
async requestPasswordChange(
|
||||
organizationId: OrganizationId,
|
||||
apps: LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher[],
|
||||
apps: ApplicationHealthReportDetailEnriched[],
|
||||
): Promise<number> {
|
||||
// Only create tasks for CRITICAL applications with at-risk passwords
|
||||
const cipherIds = apps
|
||||
|
||||
Reference in New Issue
Block a user