mirror of
https://github.com/bitwarden/browser
synced 2026-02-05 03:03:26 +00:00
Update index files, separate models, add file for map functions
This commit is contained in:
@@ -75,7 +75,7 @@
|
||||
}
|
||||
},
|
||||
"noAppsInOrgTitle": {
|
||||
"message": "No applications found in $ORG NAME$",
|
||||
"message": "No application reports found in $ORG NAME$",
|
||||
"placeholders": {
|
||||
"org name": {
|
||||
"content": "$1",
|
||||
@@ -101,6 +101,9 @@
|
||||
"applicationsMarkedAsCriticalSuccess": {
|
||||
"message": "Applications marked as critical"
|
||||
},
|
||||
"applicationsMarkedAsCriticalFail": {
|
||||
"message": "Failed to mark applications as critical"
|
||||
},
|
||||
"application": {
|
||||
"message": "Application"
|
||||
},
|
||||
@@ -10850,5 +10853,8 @@
|
||||
"example": "12-3456789"
|
||||
}
|
||||
}
|
||||
},
|
||||
"runRiskInsightsReport": {
|
||||
"message": "Run Report"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./risk-insights-data-mappers";
|
||||
@@ -0,0 +1,51 @@
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
|
||||
import { MemberDetails } from "../models/report-models";
|
||||
import { MemberCipherDetailsResponse } from "../response/member-cipher-details.response";
|
||||
|
||||
export function flattenMemberDetails(
|
||||
memberCiphers: MemberCipherDetailsResponse[],
|
||||
): MemberDetails[] {
|
||||
return memberCiphers.flatMap((member) =>
|
||||
member.cipherIds.map((cipherId) => ({
|
||||
userGuid: member.userGuid,
|
||||
userName: member.userName,
|
||||
email: member.email,
|
||||
cipherId,
|
||||
})),
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Trim the cipher uris down to get the password health application.
|
||||
* The uri should only exist once after being trimmed. No duplication.
|
||||
* Example:
|
||||
* - Untrimmed Uris: https://gmail.com, gmail.com/login
|
||||
* - Both would trim to gmail.com
|
||||
* - The cipher trimmed uri list should only return on instance in the list
|
||||
* @param cipher
|
||||
* @returns distinct list of trimmed cipher uris
|
||||
*/
|
||||
export function getTrimmedCipherUris(cipher: CipherView): string[] {
|
||||
const uris = cipher.login?.uris ?? [];
|
||||
|
||||
const uniqueDomains = new Set<string>();
|
||||
|
||||
uris.forEach((u: { uri: string }) => {
|
||||
const domain = Utils.getDomain(u.uri) ?? u.uri;
|
||||
uniqueDomains.add(domain);
|
||||
});
|
||||
return Array.from(uniqueDomains);
|
||||
}
|
||||
|
||||
// Returns a deduplicated array of members by email
|
||||
export function getUniqueMembers(orgMembers: MemberDetails[]): MemberDetails[] {
|
||||
const existingEmails = new Set<string>();
|
||||
return orgMembers.filter((member) => {
|
||||
if (existingEmails.has(member.email)) {
|
||||
return false;
|
||||
}
|
||||
existingEmails.add(member.email);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
export * from "./services";
|
||||
export * from "./helpers";
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import { EncryptedString } from "@bitwarden/common/platform/models/domain/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,76 +1,9 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Opaque } from "type-fest";
|
||||
|
||||
import { EncryptedString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
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;
|
||||
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
|
||||
* and the score type for the label and badge
|
||||
@@ -97,41 +30,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.
|
||||
@@ -139,70 +37,5 @@ export type AppAtRiskMembersDialogParams = {
|
||||
export interface EncryptedDataWithKey {
|
||||
organizationId: OrganizationId;
|
||||
encryptedData: EncryptedString;
|
||||
encryptionKey: EncryptedString;
|
||||
contentEncryptionKey: EncryptedString;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
// 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: EncryptedString;
|
||||
reportKey: EncryptedString;
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
Reference in New Issue
Block a user