mirror of
https://github.com/bitwarden/browser
synced 2025-12-12 22:33:35 +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:
@@ -2,16 +2,16 @@ import { Utils } from "@bitwarden/common/platform/misc/utils";
|
|||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
MemberDetailsFlat,
|
LEGACY_MemberDetailsFlat,
|
||||||
CipherHealthReportDetail,
|
LEGACY_CipherHealthReportDetail,
|
||||||
CipherHealthReportUriDetail,
|
LEGACY_CipherHealthReportUriDetail,
|
||||||
ApplicationHealthReportDetail,
|
|
||||||
} from "../models/password-health";
|
} from "../models/password-health";
|
||||||
|
import { ApplicationHealthReportDetail } from "../models/report-models";
|
||||||
import { MemberCipherDetailsResponse } from "../response/member-cipher-details.response";
|
import { MemberCipherDetailsResponse } from "../response/member-cipher-details.response";
|
||||||
|
|
||||||
export function flattenMemberDetails(
|
export function flattenMemberDetails(
|
||||||
memberCiphers: MemberCipherDetailsResponse[],
|
memberCiphers: MemberCipherDetailsResponse[],
|
||||||
): MemberDetailsFlat[] {
|
): LEGACY_MemberDetailsFlat[] {
|
||||||
return memberCiphers.flatMap((member) =>
|
return memberCiphers.flatMap((member) =>
|
||||||
member.cipherIds.map((cipherId) => ({
|
member.cipherIds.map((cipherId) => ({
|
||||||
userGuid: member.userGuid,
|
userGuid: member.userGuid,
|
||||||
@@ -44,7 +44,9 @@ export function getTrimmedCipherUris(cipher: CipherView): string[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns a deduplicated array of members by email
|
// 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>();
|
const existingEmails = new Set<string>();
|
||||||
return orgMembers.filter((member) => {
|
return orgMembers.filter((member) => {
|
||||||
if (existingEmails.has(member.email)) {
|
if (existingEmails.has(member.email)) {
|
||||||
@@ -68,7 +70,7 @@ export function getMemberDetailsFlat(
|
|||||||
userName: string,
|
userName: string,
|
||||||
email: string,
|
email: string,
|
||||||
cipherId: string,
|
cipherId: string,
|
||||||
): MemberDetailsFlat {
|
): LEGACY_MemberDetailsFlat {
|
||||||
return {
|
return {
|
||||||
userGuid: userGuid,
|
userGuid: userGuid,
|
||||||
userName: userName,
|
userName: userName,
|
||||||
@@ -84,9 +86,9 @@ export function getMemberDetailsFlat(
|
|||||||
* @returns Flattened cipher health details to URI
|
* @returns Flattened cipher health details to URI
|
||||||
*/
|
*/
|
||||||
export function getFlattenedCipherDetails(
|
export function getFlattenedCipherDetails(
|
||||||
detail: CipherHealthReportDetail,
|
detail: LEGACY_CipherHealthReportDetail,
|
||||||
uri: string,
|
uri: string,
|
||||||
): CipherHealthReportUriDetail {
|
): LEGACY_CipherHealthReportUriDetail {
|
||||||
return {
|
return {
|
||||||
cipherId: detail.id,
|
cipherId: detail.id,
|
||||||
reusedPasswordCount: detail.reusedPasswordCount,
|
reusedPasswordCount: detail.reusedPasswordCount,
|
||||||
@@ -107,7 +109,7 @@ export function getFlattenedCipherDetails(
|
|||||||
* @returns The new or updated application health report detail
|
* @returns The new or updated application health report detail
|
||||||
*/
|
*/
|
||||||
export function getApplicationReportDetail(
|
export function getApplicationReportDetail(
|
||||||
newUriDetail: CipherHealthReportUriDetail,
|
newUriDetail: LEGACY_CipherHealthReportUriDetail,
|
||||||
isAtRisk: boolean,
|
isAtRisk: boolean,
|
||||||
existingUriDetail?: ApplicationHealthReportDetail,
|
existingUriDetail?: ApplicationHealthReportDetail,
|
||||||
): ApplicationHealthReportDetail {
|
): ApplicationHealthReportDetail {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -1,75 +1,11 @@
|
|||||||
// FIXME: Update this file to be type safe and remove this and next line
|
// FIXME: Update this file to be type safe and remove this and next line
|
||||||
// @ts-strict-ignore
|
// @ts-strict-ignore
|
||||||
import { Opaque } from "type-fest";
|
|
||||||
|
|
||||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
import { BadgeVariant } from "@bitwarden/components";
|
import { BadgeVariant } from "@bitwarden/components";
|
||||||
import { EncString } from "@bitwarden/sdk-internal";
|
import { EncString } from "@bitwarden/sdk-internal";
|
||||||
|
|
||||||
/**
|
import { ApplicationHealthReportDetail } from "./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;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Weak password details containing the score
|
* Weak password details containing the score
|
||||||
@@ -97,41 +33,6 @@ export type ExposedPasswordDetail = {
|
|||||||
exposedXTimes: number;
|
exposedXTimes: number;
|
||||||
} | null;
|
} | 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
|
* After data is encrypted, it is returned with the
|
||||||
* encryption key used to encrypt the data.
|
* encryption key used to encrypt the data.
|
||||||
@@ -142,31 +43,39 @@ export interface EncryptedDataWithKey {
|
|||||||
encryptionKey: EncString;
|
encryptionKey: EncString;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
export type LEGACY_MemberDetailsFlat = {
|
||||||
* Request to drop a password health report application
|
userGuid: string;
|
||||||
* Model is expected by the API endpoint
|
userName: string;
|
||||||
*/
|
email: string;
|
||||||
export interface PasswordHealthReportApplicationDropRequest {
|
cipherId: string;
|
||||||
organizationId: OrganizationId;
|
};
|
||||||
passwordHealthReportApplicationIds: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
export type LEGACY_ApplicationHealthReportDetailWithCriticalFlag = ApplicationHealthReportDetail & {
|
||||||
* Response from the API after marking an app as critical
|
isMarkedAsCritical: boolean;
|
||||||
*/
|
};
|
||||||
export interface PasswordHealthReportApplicationsResponse {
|
|
||||||
id: PasswordHealthReportApplicationId;
|
export type LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher =
|
||||||
organizationId: OrganizationId;
|
LEGACY_ApplicationHealthReportDetailWithCriticalFlag & {
|
||||||
uri: string;
|
ciphers: CipherView[];
|
||||||
}
|
};
|
||||||
/*
|
|
||||||
* Request to save a password health report application
|
export type LEGACY_CipherHealthReportDetail = CipherView & {
|
||||||
* Model is expected by the API endpoint
|
reusedPasswordCount: number;
|
||||||
*/
|
weakPasswordDetail: WeakPasswordDetail;
|
||||||
export interface PasswordHealthReportApplicationsRequest {
|
exposedPasswordDetail: ExposedPasswordDetail;
|
||||||
organizationId: OrganizationId;
|
cipherMembers: LEGACY_MemberDetailsFlat[];
|
||||||
url: string;
|
trimmedUris: string[];
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export type LEGACY_CipherHealthReportUriDetail = {
|
||||||
|
cipherId: string;
|
||||||
|
reusedPasswordCount: number;
|
||||||
|
weakPasswordDetail: WeakPasswordDetail;
|
||||||
|
exposedPasswordDetail: ExposedPasswordDetail;
|
||||||
|
cipherMembers: LEGACY_MemberDetailsFlat[];
|
||||||
|
trimmedUri: string;
|
||||||
|
cipher: CipherView;
|
||||||
|
};
|
||||||
|
|
||||||
export interface EncryptedDataModel {
|
export interface EncryptedDataModel {
|
||||||
organizationId: OrganizationId;
|
organizationId: OrganizationId;
|
||||||
@@ -174,42 +83,3 @@ export interface EncryptedDataModel {
|
|||||||
encryptionKey: string;
|
encryptionKey: string;
|
||||||
date: Date;
|
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">;
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -5,10 +5,10 @@ import { OrganizationId } from "@bitwarden/common/types/guid";
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
PasswordHealthReportApplicationDropRequest,
|
PasswordHealthReportApplicationDropRequest,
|
||||||
PasswordHealthReportApplicationId,
|
|
||||||
PasswordHealthReportApplicationsRequest,
|
PasswordHealthReportApplicationsRequest,
|
||||||
PasswordHealthReportApplicationsResponse,
|
PasswordHealthReportApplicationsResponse,
|
||||||
} from "../models/password-health";
|
} from "../models/api-models.types";
|
||||||
|
import { PasswordHealthReportApplicationId } from "../models/report-models";
|
||||||
|
|
||||||
import { CriticalAppsApiService } from "./critical-apps-api.service";
|
import { CriticalAppsApiService } from "./critical-apps-api.service";
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
PasswordHealthReportApplicationDropRequest,
|
PasswordHealthReportApplicationDropRequest,
|
||||||
PasswordHealthReportApplicationsRequest,
|
PasswordHealthReportApplicationsRequest,
|
||||||
PasswordHealthReportApplicationsResponse,
|
PasswordHealthReportApplicationsResponse,
|
||||||
} from "../models/password-health";
|
} from "../models/api-models.types";
|
||||||
|
|
||||||
export class CriticalAppsApiService {
|
export class CriticalAppsApiService {
|
||||||
constructor(private apiService: ApiService) {}
|
constructor(private apiService: ApiService) {}
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ import { OrgKey } from "@bitwarden/common/types/key";
|
|||||||
import { KeyService } from "@bitwarden/key-management";
|
import { KeyService } from "@bitwarden/key-management";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
PasswordHealthReportApplicationId,
|
|
||||||
PasswordHealthReportApplicationsRequest,
|
PasswordHealthReportApplicationsRequest,
|
||||||
PasswordHealthReportApplicationsResponse,
|
PasswordHealthReportApplicationsResponse,
|
||||||
} from "../models/password-health";
|
} from "../models/api-models.types";
|
||||||
|
import { PasswordHealthReportApplicationId } from "../models/report-models";
|
||||||
|
|
||||||
import { CriticalAppsApiService } from "./critical-apps-api.service";
|
import { CriticalAppsApiService } from "./critical-apps-api.service";
|
||||||
import { CriticalAppsService } from "./critical-apps.service";
|
import { CriticalAppsService } from "./critical-apps.service";
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import { KeyService } from "@bitwarden/key-management";
|
|||||||
import {
|
import {
|
||||||
PasswordHealthReportApplicationsRequest,
|
PasswordHealthReportApplicationsRequest,
|
||||||
PasswordHealthReportApplicationsResponse,
|
PasswordHealthReportApplicationsResponse,
|
||||||
} from "../models/password-health";
|
} from "../models/api-models.types";
|
||||||
|
|
||||||
import { CriticalAppsApiService } from "./critical-apps-api.service";
|
import { CriticalAppsApiService } from "./critical-apps-api.service";
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
|||||||
import { makeEncString } from "@bitwarden/common/spec";
|
import { makeEncString } from "@bitwarden/common/spec";
|
||||||
import { OrganizationId, OrganizationReportId } from "@bitwarden/common/types/guid";
|
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";
|
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) => {
|
it("Get Applications: should call apiService.send with correct parameters and return an Observable", (done) => {
|
||||||
const reportId = "report123" as OrganizationReportId;
|
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);
|
mockApiService.send.mockResolvedValueOnce(mockResponse);
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
|||||||
import { OrganizationId, OrganizationReportId } from "@bitwarden/common/types/guid";
|
import { OrganizationId, OrganizationReportId } from "@bitwarden/common/types/guid";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EncryptedDataModel,
|
|
||||||
GetRiskInsightsReportResponse,
|
GetRiskInsightsReportResponse,
|
||||||
SaveRiskInsightsReportRequest,
|
SaveRiskInsightsReportRequest,
|
||||||
SaveRiskInsightsReportResponse,
|
SaveRiskInsightsReportResponse,
|
||||||
} from "../models/password-health";
|
} from "../models/api-models.types";
|
||||||
|
import { EncryptedDataModel } from "../models/password-health";
|
||||||
|
|
||||||
export class RiskInsightsApiService {
|
export class RiskInsightsApiService {
|
||||||
constructor(private apiService: ApiService) {}
|
constructor(private apiService: ApiService) {}
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import { OrganizationId } from "@bitwarden/common/types/guid";
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
AppAtRiskMembersDialogParams,
|
AppAtRiskMembersDialogParams,
|
||||||
ApplicationHealthReportDetail,
|
|
||||||
AtRiskApplicationDetail,
|
AtRiskApplicationDetail,
|
||||||
AtRiskMemberDetail,
|
AtRiskMemberDetail,
|
||||||
DrawerType,
|
DrawerType,
|
||||||
} from "../models/password-health";
|
ApplicationHealthReportDetail,
|
||||||
|
} from "../models/report-models";
|
||||||
|
|
||||||
import { RiskInsightsReportService } from "./risk-insights-report.service";
|
import { RiskInsightsReportService } from "./risk-insights-report.service";
|
||||||
export class RiskInsightsDataService {
|
export class RiskInsightsDataService {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/pass
|
|||||||
import { OrganizationId, UserId } from "@bitwarden/common/types/guid";
|
import { OrganizationId, UserId } from "@bitwarden/common/types/guid";
|
||||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
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 { mockCiphers } from "./ciphers.mock";
|
||||||
import { MemberCipherDetailsApiService } from "./member-cipher-details-api.service";
|
import { MemberCipherDetailsApiService } from "./member-cipher-details-api.service";
|
||||||
@@ -197,7 +197,7 @@ describe("RiskInsightsReportService", () => {
|
|||||||
date: new Date().toISOString(),
|
date: new Date().toISOString(),
|
||||||
organizationId: "orgId",
|
organizationId: "orgId",
|
||||||
reportData: "encryptedReportData",
|
reportData: "encryptedReportData",
|
||||||
reportKey: "encryptionKey",
|
contentEncryptionKey: "encryptionKey",
|
||||||
} as GetRiskInsightsReportResponse;
|
} as GetRiskInsightsReportResponse;
|
||||||
|
|
||||||
const organizationId = "orgId" as OrganizationId;
|
const organizationId = "orgId" as OrganizationId;
|
||||||
@@ -227,7 +227,7 @@ describe("RiskInsightsReportService", () => {
|
|||||||
date: new Date().toISOString(),
|
date: new Date().toISOString(),
|
||||||
organizationId: organizationId as OrganizationId,
|
organizationId: organizationId as OrganizationId,
|
||||||
reportData: "encryptedReportData",
|
reportData: "encryptedReportData",
|
||||||
reportKey: "encryptionKey",
|
contentEncryptionKey: "encryptionKey",
|
||||||
} as GetRiskInsightsReportResponse;
|
} as GetRiskInsightsReportResponse;
|
||||||
|
|
||||||
const decryptedReport = {
|
const decryptedReport = {
|
||||||
|
|||||||
@@ -29,20 +29,22 @@ import {
|
|||||||
getTrimmedCipherUris,
|
getTrimmedCipherUris,
|
||||||
getUniqueMembers,
|
getUniqueMembers,
|
||||||
} from "../helpers/risk-insights-data-mappers";
|
} from "../helpers/risk-insights-data-mappers";
|
||||||
|
import {
|
||||||
|
LEGACY_CipherHealthReportDetail,
|
||||||
|
LEGACY_CipherHealthReportUriDetail,
|
||||||
|
ExposedPasswordDetail,
|
||||||
|
LEGACY_MemberDetailsFlat,
|
||||||
|
WeakPasswordDetail,
|
||||||
|
WeakPasswordScore,
|
||||||
|
LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher,
|
||||||
|
} from "../models/password-health";
|
||||||
import {
|
import {
|
||||||
ApplicationHealthReportDetail,
|
ApplicationHealthReportDetail,
|
||||||
ApplicationHealthReportSummary,
|
ApplicationHealthReportSummary,
|
||||||
AtRiskMemberDetail,
|
AtRiskMemberDetail,
|
||||||
AtRiskApplicationDetail,
|
AtRiskApplicationDetail,
|
||||||
CipherHealthReportDetail,
|
RiskInsightsReportData,
|
||||||
CipherHealthReportUriDetail,
|
} from "../models/report-models";
|
||||||
ExposedPasswordDetail,
|
|
||||||
MemberDetailsFlat,
|
|
||||||
WeakPasswordDetail,
|
|
||||||
WeakPasswordScore,
|
|
||||||
ApplicationHealthReportDetailWithCriticalFlagAndCipher,
|
|
||||||
ReportInsightsReportData,
|
|
||||||
} from "../models/password-health";
|
|
||||||
|
|
||||||
import { MemberCipherDetailsApiService } from "./member-cipher-details-api.service";
|
import { MemberCipherDetailsApiService } from "./member-cipher-details-api.service";
|
||||||
import { RiskInsightsApiService } from "./risk-insights-api.service";
|
import { RiskInsightsApiService } from "./risk-insights-api.service";
|
||||||
@@ -76,7 +78,9 @@ export class RiskInsightsReportService {
|
|||||||
* @param organizationId
|
* @param organizationId
|
||||||
* @returns Cipher health report data with members and trimmed uris
|
* @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 allCiphers$ = from(this.cipherService.getAllFromApiForOrganization(organizationId));
|
||||||
const memberCiphers$ = from(
|
const memberCiphers$ = from(
|
||||||
this.memberCipherDetailsApiService.getMemberCipherDetails(organizationId),
|
this.memberCipherDetailsApiService.getMemberCipherDetails(organizationId),
|
||||||
@@ -84,7 +88,7 @@ export class RiskInsightsReportService {
|
|||||||
|
|
||||||
const results$ = zip(allCiphers$, memberCiphers$).pipe(
|
const results$ = zip(allCiphers$, memberCiphers$).pipe(
|
||||||
map(([allCiphers, memberCiphers]) => {
|
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)),
|
dtl.cipherIds.map((c) => getMemberDetailsFlat(dtl.userGuid, dtl.userName, dtl.email, c)),
|
||||||
);
|
);
|
||||||
return [allCiphers, details] as const;
|
return [allCiphers, details] as const;
|
||||||
@@ -104,7 +108,7 @@ export class RiskInsightsReportService {
|
|||||||
*/
|
*/
|
||||||
generateRawDataUriReport$(
|
generateRawDataUriReport$(
|
||||||
organizationId: OrganizationId,
|
organizationId: OrganizationId,
|
||||||
): Observable<CipherHealthReportUriDetail[]> {
|
): Observable<LEGACY_CipherHealthReportUriDetail[]> {
|
||||||
const cipherHealthDetails$ = this.generateRawDataReport$(organizationId);
|
const cipherHealthDetails$ = this.generateRawDataReport$(organizationId);
|
||||||
const results$ = cipherHealthDetails$.pipe(
|
const results$ = cipherHealthDetails$.pipe(
|
||||||
map((healthDetails) => this.getCipherUriDetails(healthDetails)),
|
map((healthDetails) => this.getCipherUriDetails(healthDetails)),
|
||||||
@@ -206,7 +210,7 @@ export class RiskInsightsReportService {
|
|||||||
async identifyCiphers(
|
async identifyCiphers(
|
||||||
data: ApplicationHealthReportDetail[],
|
data: ApplicationHealthReportDetail[],
|
||||||
organizationId: OrganizationId,
|
organizationId: OrganizationId,
|
||||||
): Promise<ApplicationHealthReportDetailWithCriticalFlagAndCipher[]> {
|
): Promise<LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher[]> {
|
||||||
const cipherViews = await this.cipherService.getAllFromApiForOrganization(organizationId);
|
const cipherViews = await this.cipherService.getAllFromApiForOrganization(organizationId);
|
||||||
|
|
||||||
const dataWithCiphers = data.map(
|
const dataWithCiphers = data.map(
|
||||||
@@ -214,7 +218,7 @@ export class RiskInsightsReportService {
|
|||||||
({
|
({
|
||||||
...app,
|
...app,
|
||||||
ciphers: cipherViews.filter((c) => app.cipherIds.some((a) => a === c.id)),
|
ciphers: cipherViews.filter((c) => app.cipherIds.some((a) => a === c.id)),
|
||||||
}) as ApplicationHealthReportDetailWithCriticalFlagAndCipher,
|
}) as LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher,
|
||||||
);
|
);
|
||||||
return dataWithCiphers;
|
return dataWithCiphers;
|
||||||
}
|
}
|
||||||
@@ -226,7 +230,7 @@ export class RiskInsightsReportService {
|
|||||||
switchMap((response) => {
|
switchMap((response) => {
|
||||||
if (!response) {
|
if (!response) {
|
||||||
// Return an empty report and summary if response is falsy
|
// Return an empty report and summary if response is falsy
|
||||||
return of<ReportInsightsReportData>({
|
return of<RiskInsightsReportData>({
|
||||||
data: [],
|
data: [],
|
||||||
summary: {
|
summary: {
|
||||||
totalMemberCount: 0,
|
totalMemberCount: 0,
|
||||||
@@ -237,12 +241,12 @@ export class RiskInsightsReportService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
return from(
|
return from(
|
||||||
this.riskInsightsEncryptionService.decryptRiskInsightsReport<ReportInsightsReportData>(
|
this.riskInsightsEncryptionService.decryptRiskInsightsReport<RiskInsightsReportData>(
|
||||||
organizationId,
|
organizationId,
|
||||||
userId,
|
userId,
|
||||||
new EncString(response.reportData),
|
new EncString(response.reportData),
|
||||||
new EncString(response.reportKey),
|
new EncString(response.contentEncryptionKey),
|
||||||
(data) => data as ReportInsightsReportData,
|
(data) => data as RiskInsightsReportData,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
@@ -297,9 +301,9 @@ export class RiskInsightsReportService {
|
|||||||
*/
|
*/
|
||||||
private async getCipherDetails(
|
private async getCipherDetails(
|
||||||
ciphers: CipherView[],
|
ciphers: CipherView[],
|
||||||
memberDetails: MemberDetailsFlat[],
|
memberDetails: LEGACY_MemberDetailsFlat[],
|
||||||
): Promise<CipherHealthReportDetail[]> {
|
): Promise<LEGACY_CipherHealthReportDetail[]> {
|
||||||
const cipherHealthReports: CipherHealthReportDetail[] = [];
|
const cipherHealthReports: LEGACY_CipherHealthReportDetail[] = [];
|
||||||
const passwordUseMap = new Map<string, number>();
|
const passwordUseMap = new Map<string, number>();
|
||||||
const exposedDetails = await this.findExposedPasswords(ciphers);
|
const exposedDetails = await this.findExposedPasswords(ciphers);
|
||||||
for (const cipher of ciphers) {
|
for (const cipher of ciphers) {
|
||||||
@@ -329,7 +333,7 @@ export class RiskInsightsReportService {
|
|||||||
exposedPasswordDetail: exposedPassword,
|
exposedPasswordDetail: exposedPassword,
|
||||||
cipherMembers: cipherMembers,
|
cipherMembers: cipherMembers,
|
||||||
trimmedUris: cipherTrimmedUris,
|
trimmedUris: cipherTrimmedUris,
|
||||||
} as CipherHealthReportDetail;
|
} as LEGACY_CipherHealthReportDetail;
|
||||||
|
|
||||||
cipherHealthReports.push(cipherHealth);
|
cipherHealthReports.push(cipherHealth);
|
||||||
}
|
}
|
||||||
@@ -348,8 +352,8 @@ export class RiskInsightsReportService {
|
|||||||
* @returns Flattened cipher health details to uri
|
* @returns Flattened cipher health details to uri
|
||||||
*/
|
*/
|
||||||
private getCipherUriDetails(
|
private getCipherUriDetails(
|
||||||
cipherHealthReport: CipherHealthReportDetail[],
|
cipherHealthReport: LEGACY_CipherHealthReportDetail[],
|
||||||
): CipherHealthReportUriDetail[] {
|
): LEGACY_CipherHealthReportUriDetail[] {
|
||||||
return cipherHealthReport.flatMap((rpt) =>
|
return cipherHealthReport.flatMap((rpt) =>
|
||||||
rpt.trimmedUris.map((u) => getFlattenedCipherDetails(rpt, u)),
|
rpt.trimmedUris.map((u) => getFlattenedCipherDetails(rpt, u)),
|
||||||
);
|
);
|
||||||
@@ -362,7 +366,7 @@ export class RiskInsightsReportService {
|
|||||||
* @returns Application health reports
|
* @returns Application health reports
|
||||||
*/
|
*/
|
||||||
private getApplicationHealthReport(
|
private getApplicationHealthReport(
|
||||||
cipherHealthUriReport: CipherHealthReportUriDetail[],
|
cipherHealthUriReport: LEGACY_CipherHealthReportUriDetail[],
|
||||||
): ApplicationHealthReportDetail[] {
|
): ApplicationHealthReportDetail[] {
|
||||||
const appReports: ApplicationHealthReportDetail[] = [];
|
const appReports: ApplicationHealthReportDetail[] = [];
|
||||||
cipherHealthUriReport.forEach((uri) => {
|
cipherHealthUriReport.forEach((uri) => {
|
||||||
|
|||||||
@@ -11,11 +11,13 @@ import {
|
|||||||
RiskInsightsReportService,
|
RiskInsightsReportService,
|
||||||
} from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
} from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
||||||
import {
|
import {
|
||||||
ApplicationHealthReportDetail,
|
LEGACY_ApplicationHealthReportDetailWithCriticalFlag,
|
||||||
ApplicationHealthReportDetailWithCriticalFlag,
|
LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher,
|
||||||
ApplicationHealthReportDetailWithCriticalFlagAndCipher,
|
|
||||||
ApplicationHealthReportSummary,
|
|
||||||
} from "@bitwarden/bit-common/dirt/reports/risk-insights/models/password-health";
|
} 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 { RiskInsightsEncryptionService } from "@bitwarden/bit-common/dirt/reports/risk-insights/services/risk-insights-encryption.service";
|
||||||
import {
|
import {
|
||||||
getOrganizationById,
|
getOrganizationById,
|
||||||
@@ -60,7 +62,7 @@ import { ApplicationsLoadingComponent } from "./risk-insights-loading.component"
|
|||||||
})
|
})
|
||||||
export class AllApplicationsComponent implements OnInit {
|
export class AllApplicationsComponent implements OnInit {
|
||||||
protected dataSource =
|
protected dataSource =
|
||||||
new TableDataSource<ApplicationHealthReportDetailWithCriticalFlagAndCipher>();
|
new TableDataSource<LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher>();
|
||||||
protected selectedUrls: Set<string> = new Set<string>();
|
protected selectedUrls: Set<string> = new Set<string>();
|
||||||
protected searchControl = new FormControl("", { nonNullable: true });
|
protected searchControl = new FormControl("", { nonNullable: true });
|
||||||
protected loading = true;
|
protected loading = true;
|
||||||
@@ -99,7 +101,7 @@ export class AllApplicationsComponent implements OnInit {
|
|||||||
const data = applications?.map((app) => ({
|
const data = applications?.map((app) => ({
|
||||||
...app,
|
...app,
|
||||||
isMarkedAsCritical: criticalUrls.includes(app.applicationName),
|
isMarkedAsCritical: criticalUrls.includes(app.applicationName),
|
||||||
})) as ApplicationHealthReportDetailWithCriticalFlag[];
|
})) as LEGACY_ApplicationHealthReportDetailWithCriticalFlag[];
|
||||||
return { data, organization };
|
return { data, organization };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { CommonModule } from "@angular/common";
|
|||||||
import { Component, Input } from "@angular/core";
|
import { Component, Input } from "@angular/core";
|
||||||
|
|
||||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
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 { MenuModule, TableDataSource, TableModule } from "@bitwarden/components";
|
||||||
import { SharedModule } from "@bitwarden/web-vault/app/shared";
|
import { SharedModule } from "@bitwarden/web-vault/app/shared";
|
||||||
import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pipes/pipes.module";
|
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",
|
templateUrl: "./app-table-row-scrollable.component.html",
|
||||||
})
|
})
|
||||||
export class AppTableRowScrollableComponent {
|
export class AppTableRowScrollableComponent {
|
||||||
@Input() dataSource!: TableDataSource<ApplicationHealthReportDetailWithCriticalFlagAndCipher>;
|
@Input()
|
||||||
|
dataSource!: TableDataSource<LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher>;
|
||||||
@Input() showRowMenuForCriticalApps: boolean = false;
|
@Input() showRowMenuForCriticalApps: boolean = false;
|
||||||
@Input() showRowCheckBox: boolean = false;
|
@Input() showRowCheckBox: boolean = false;
|
||||||
@Input() selectedUrls: Set<string> = new Set<string>();
|
@Input() selectedUrls: Set<string> = new Set<string>();
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ import {
|
|||||||
RiskInsightsReportService,
|
RiskInsightsReportService,
|
||||||
} from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
} from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
||||||
import {
|
import {
|
||||||
ApplicationHealthReportDetailWithCriticalFlag,
|
LEGACY_ApplicationHealthReportDetailWithCriticalFlag,
|
||||||
ApplicationHealthReportDetailWithCriticalFlagAndCipher,
|
LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher,
|
||||||
ApplicationHealthReportSummary,
|
|
||||||
} from "@bitwarden/bit-common/dirt/reports/risk-insights/models/password-health";
|
} 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 { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.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 {
|
export class CriticalApplicationsComponent implements OnInit {
|
||||||
protected dataSource =
|
protected dataSource =
|
||||||
new TableDataSource<ApplicationHealthReportDetailWithCriticalFlagAndCipher>();
|
new TableDataSource<LEGACY_ApplicationHealthReportDetailWithCriticalFlagAndCipher>();
|
||||||
protected selectedIds: Set<number> = new Set<number>();
|
protected selectedIds: Set<number> = new Set<number>();
|
||||||
protected searchControl = new FormControl("", { nonNullable: true });
|
protected searchControl = new FormControl("", { nonNullable: true });
|
||||||
private destroyRef = inject(DestroyRef);
|
private destroyRef = inject(DestroyRef);
|
||||||
@@ -79,7 +79,7 @@ export class CriticalApplicationsComponent implements OnInit {
|
|||||||
const data = applications?.map((app) => ({
|
const data = applications?.map((app) => ({
|
||||||
...app,
|
...app,
|
||||||
isMarkedAsCritical: criticalUrls.includes(app.applicationName),
|
isMarkedAsCritical: criticalUrls.includes(app.applicationName),
|
||||||
})) as ApplicationHealthReportDetailWithCriticalFlag[];
|
})) as LEGACY_ApplicationHealthReportDetailWithCriticalFlag[];
|
||||||
return data?.filter((app) => app.isMarkedAsCritical);
|
return data?.filter((app) => app.isMarkedAsCritical);
|
||||||
}),
|
}),
|
||||||
switchMap(async (data) => {
|
switchMap(async (data) => {
|
||||||
@@ -200,7 +200,7 @@ export class CriticalApplicationsComponent implements OnInit {
|
|||||||
this.dataService.setDrawerForOrgAtRiskApps(data, invokerId);
|
this.dataService.setDrawerForOrgAtRiskApps(data, invokerId);
|
||||||
};
|
};
|
||||||
|
|
||||||
trackByFunction(_: number, item: ApplicationHealthReportDetailWithCriticalFlag) {
|
trackByFunction(_: number, item: LEGACY_ApplicationHealthReportDetailWithCriticalFlag) {
|
||||||
return item.applicationName;
|
return item.applicationName;
|
||||||
}
|
}
|
||||||
isDrawerOpenForTableRow = (applicationName: string) => {
|
isDrawerOpenForTableRow = (applicationName: string) => {
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ import {
|
|||||||
CriticalAppsService,
|
CriticalAppsService,
|
||||||
RiskInsightsDataService,
|
RiskInsightsDataService,
|
||||||
} from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
} from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
||||||
|
import { PasswordHealthReportApplicationsResponse } from "@bitwarden/bit-common/dirt/reports/risk-insights/models/api-models.types";
|
||||||
import {
|
import {
|
||||||
ApplicationHealthReportDetail,
|
ApplicationHealthReportDetail,
|
||||||
DrawerType,
|
DrawerType,
|
||||||
PasswordHealthReportApplicationsResponse,
|
} from "@bitwarden/bit-common/dirt/reports/risk-insights/models/report-models";
|
||||||
} from "@bitwarden/bit-common/dirt/reports/risk-insights/models/password-health";
|
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
|
|||||||
Reference in New Issue
Block a user