1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-11 05:43:41 +00:00

[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
This commit is contained in:
Alex
2025-09-18 14:08:07 -04:00
committed by GitHub
parent 73a9bd81e7
commit d6cd30cf54
17 changed files with 322 additions and 229 deletions

View File

@@ -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<string>();
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 {

View File

@@ -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;
}

View File

@@ -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<string, "PasswordHealthReportApplicationId">;

View File

@@ -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<string, "PasswordHealthReportApplicationId">;
// -------------------- 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;
};

View File

@@ -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";

View File

@@ -7,7 +7,7 @@ import {
PasswordHealthReportApplicationDropRequest,
PasswordHealthReportApplicationsRequest,
PasswordHealthReportApplicationsResponse,
} from "../models/password-health";
} from "../models/api-models.types";
export class CriticalAppsApiService {
constructor(private apiService: ApiService) {}

View File

@@ -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";

View File

@@ -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";

View File

@@ -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);

View File

@@ -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) {}

View File

@@ -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 {

View File

@@ -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 = {

View File

@@ -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<CipherHealthReportDetail[]> {
generateRawDataReport$(
organizationId: OrganizationId,
): Observable<LEGACY_CipherHealthReportDetail[]> {
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<CipherHealthReportUriDetail[]> {
): Observable<LEGACY_CipherHealthReportUriDetail[]> {
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<ApplicationHealthReportDetailWithCriticalFlagAndCipher[]> {
): Promise<LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher[]> {
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<ReportInsightsReportData>({
return of<RiskInsightsReportData>({
data: [],
summary: {
totalMemberCount: 0,
@@ -237,12 +241,12 @@ export class RiskInsightsReportService {
});
}
return from(
this.riskInsightsEncryptionService.decryptRiskInsightsReport<ReportInsightsReportData>(
this.riskInsightsEncryptionService.decryptRiskInsightsReport<RiskInsightsReportData>(
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<CipherHealthReportDetail[]> {
const cipherHealthReports: CipherHealthReportDetail[] = [];
memberDetails: LEGACY_MemberDetailsFlat[],
): Promise<LEGACY_CipherHealthReportDetail[]> {
const cipherHealthReports: LEGACY_CipherHealthReportDetail[] = [];
const passwordUseMap = new Map<string, number>();
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) => {

View File

@@ -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<ApplicationHealthReportDetailWithCriticalFlagAndCipher>();
new TableDataSource<LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher>();
protected selectedUrls: Set<string> = new Set<string>();
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 };
}

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 { 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<ApplicationHealthReportDetailWithCriticalFlagAndCipher>;
@Input()
dataSource!: TableDataSource<LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher>;
@Input() showRowMenuForCriticalApps: boolean = false;
@Input() showRowCheckBox: boolean = false;
@Input() selectedUrls: Set<string> = new Set<string>();

View File

@@ -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<ApplicationHealthReportDetailWithCriticalFlagAndCipher>();
new TableDataSource<LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher>();
protected selectedIds: Set<number> = new Set<number>();
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) => {

View File

@@ -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";