From 3559b3e94e3ffcb95a8eadd03356a6e069922f3e Mon Sep 17 00:00:00 2001 From: Tom Date: Wed, 4 Dec 2024 11:23:56 -0500 Subject: [PATCH] Adding more documentation and moving types to it's own file --- .../risk-insights/models/password-health.ts | 90 +++++++++++++++++++ .../services/risk-insights-report.service.ts | 72 +++------------ 2 files changed, 103 insertions(+), 59 deletions(-) create mode 100644 bitwarden_license/bit-common/src/tools/reports/risk-insights/models/password-health.ts diff --git a/bitwarden_license/bit-common/src/tools/reports/risk-insights/models/password-health.ts b/bitwarden_license/bit-common/src/tools/reports/risk-insights/models/password-health.ts new file mode 100644 index 00000000000..73ff0d0be38 --- /dev/null +++ b/bitwarden_license/bit-common/src/tools/reports/risk-insights/models/password-health.ts @@ -0,0 +1,90 @@ +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { BadgeVariant } from "@bitwarden/components"; + +/** + * 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; + memberCount: number; + atRiskMemberCount: number; + + memberDetails: MemberDetailsFlat[]; + atRiskMemberDetails: MemberDetailsFlat[]; +}; + +/** + * 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; +}; + +/** + * 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[]; +}; + +/** + * Weak password details containing the score + * and the score type for the label and badge + */ +export type WeakPasswordDetail = { + score: number; + detailValue: WeakPasswordScore; +}; + +/** + * Weak password details containing the badge and + * the label for the password score + */ +export type WeakPasswordScore = { + label: string; + badgeVariant: BadgeVariant; +}; + +/** + * How many times a password has been exposed + */ +export type ExposedPasswordDetail = { + exposedXTimes: number; +}; + +/** + * Flattened member details that associates an + * organization member to a cipher + */ +export type MemberDetailsFlat = { + userName: string; + email: string; + cipherId: string; +}; diff --git a/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/risk-insights-report.service.ts b/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/risk-insights-report.service.ts index 19b56f3dda5..247a62ec3bb 100644 --- a/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/risk-insights-report.service.ts +++ b/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/risk-insights-report.service.ts @@ -6,64 +6,20 @@ import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/pass import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -import { BadgeVariant } from "@bitwarden/components"; + +import { + ApplicationHealthReportDetail, + ApplicationHealthReportSummary, + CipherHealthReportDetail, + CipherHealthReportUriDetail, + ExposedPasswordDetail, + MemberDetailsFlat, + WeakPasswordDetail, + WeakPasswordScore, +} from "../models/password-health"; import { MemberCipherDetailsApiService } from "./member-cipher-details-api.service"; -export type ApplicationHealthReportSummary = { - totalMemberCount: number; - totalAtRiskMemberCount: number; - totalApplicationCount: number; - totalAtRiskApplicationCount: number; -}; - -export type ApplicationHealthReportDetail = { - applicationName: string; - passwordCount: number; - atRiskPasswordCount: number; - memberCount: number; - atRiskMemberCount: number; - - memberDetails: MemberDetailsFlat[]; - atRiskMemberDetails: MemberDetailsFlat[]; -}; - -export type CipherHealthReportUriDetail = { - cipherId: string; - reusedPasswordCount: number; - weakPasswordDetail: WeakPasswordDetail; - exposedPasswordDetail: ExposedPasswordDetail; - cipherMembers: MemberDetailsFlat[]; - trimmedUri: string; -}; - -export type CipherHealthReportDetail = CipherView & { - reusedPasswordCount: number; - weakPasswordDetail: WeakPasswordDetail; - exposedPasswordDetail: ExposedPasswordDetail; - cipherMembers: MemberDetailsFlat[]; - trimmedUris: string[]; -}; - -type WeakPasswordDetail = { - score: number; - detailValue: WeakPasswordScore; -}; - -type WeakPasswordScore = { - label: string; - badgeVariant: BadgeVariant; -}; - -type ExposedPasswordDetail = { - exposedXTimes: number; -}; - -export type MemberDetailsFlat = { - userName: string; - email: string; - cipherId: string; -}; @Injectable() export class RiskInsightsReportService { passwordUseMap = new Map(); @@ -80,7 +36,7 @@ export class RiskInsightsReportService { * Can be used in the Raw Data diagnostic tab (just exclude the members in the view) * and can be used in the raw data + members tab when including the members in the view * @param organizationId - * @returns + * @returns Cipher health report data with members and trimmed uris */ async generateRawDataReport(organizationId: string): Promise { const allCiphers = await this.cipherService.getAllFromApiForOrganization(organizationId); @@ -181,9 +137,7 @@ export class RiskInsightsReportService { // loop for reused passwords cipherHealthReports.forEach((detail) => { - detail.reusedPasswordCount = this.passwordUseMap.has(detail.id) - ? this.passwordUseMap.get(detail.id) - : 0; + detail.reusedPasswordCount = this.passwordUseMap.get(detail.id) ?? 0; }); return cipherHealthReports; }