mirror of
https://github.com/bitwarden/browser
synced 2026-02-11 22:13:32 +00:00
Moving to observables
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { TestBed } from "@angular/core/testing";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
|
||||
import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength";
|
||||
@@ -50,11 +51,13 @@ describe("RiskInsightsReportService", () => {
|
||||
});
|
||||
|
||||
it("should generate the raw data report correctly", async () => {
|
||||
const result = await service.generateRawDataReport("orgId");
|
||||
const result = await firstValueFrom(service.generateRawDataReport$("orgId"));
|
||||
|
||||
expect(result).toHaveLength(6);
|
||||
|
||||
let testCase = result.filter((x) => x.id === "cbea34a8-bde4-46ad-9d19-b05001228ab1")[0];
|
||||
let testCaseResults = result.filter((x) => x.id === "cbea34a8-bde4-46ad-9d19-b05001228ab1");
|
||||
expect(testCaseResults).toHaveLength(1);
|
||||
let testCase = testCaseResults[0];
|
||||
expect(testCase).toBeTruthy();
|
||||
expect(testCase.cipherMembers).toHaveLength(2);
|
||||
expect(testCase.trimmedUris).toHaveLength(3);
|
||||
@@ -62,7 +65,9 @@ describe("RiskInsightsReportService", () => {
|
||||
expect(testCase.exposedPasswordDetail).toBeTruthy();
|
||||
expect(testCase.reusedPasswordCount).toEqual(2);
|
||||
|
||||
testCase = result.filter((x) => x.id === "cbea34a8-bde4-46ad-9d19-b05001227tt1")[0];
|
||||
testCaseResults = result.filter((x) => x.id === "cbea34a8-bde4-46ad-9d19-b05001227tt1");
|
||||
expect(testCaseResults).toHaveLength(1);
|
||||
testCase = testCaseResults[0];
|
||||
expect(testCase).toBeTruthy();
|
||||
expect(testCase.cipherMembers).toHaveLength(1);
|
||||
expect(testCase.trimmedUris).toHaveLength(1);
|
||||
@@ -72,7 +77,7 @@ describe("RiskInsightsReportService", () => {
|
||||
});
|
||||
|
||||
it("should generate the raw data + uri report correctly", async () => {
|
||||
const result = await service.generateRawDataUriReport("orgId");
|
||||
const result = await firstValueFrom(service.generateRawDataUriReport$("orgId"));
|
||||
|
||||
expect(result).toHaveLength(9);
|
||||
|
||||
@@ -91,7 +96,7 @@ describe("RiskInsightsReportService", () => {
|
||||
});
|
||||
|
||||
it("should generate applications health report data correctly", async () => {
|
||||
const result = await service.generateApplicationsReport("orgId");
|
||||
const result = await firstValueFrom(service.generateApplicationsReport$("orgId"));
|
||||
|
||||
expect(result).toHaveLength(6);
|
||||
|
||||
@@ -99,7 +104,9 @@ describe("RiskInsightsReportService", () => {
|
||||
// has 2 members and the second has 4. However, the 2 members in the first
|
||||
// cipher are also associated with the second. The total amount of members
|
||||
// should be 4 not 6
|
||||
const googleTest = result.filter((x) => x.applicationName === "google.com")[0];
|
||||
const googleTestResults = result.filter((x) => x.applicationName === "google.com");
|
||||
expect(googleTestResults).toHaveLength(1);
|
||||
const googleTest = googleTestResults[0];
|
||||
expect(googleTest.memberCount).toEqual(4);
|
||||
|
||||
// Both ciphers have at risk passwords
|
||||
@@ -110,25 +117,27 @@ describe("RiskInsightsReportService", () => {
|
||||
expect(googleTest.atRiskPasswordCount).toEqual(2);
|
||||
|
||||
// There are 2 ciphers associated with 101domain.com
|
||||
const doman101Test = result.filter((x) => x.applicationName === "101domain.com")[0];
|
||||
expect(doman101Test.passwordCount).toEqual(2);
|
||||
const domain101TestResults = result.filter((x) => x.applicationName === "101domain.com");
|
||||
expect(domain101TestResults).toHaveLength(1);
|
||||
const domain101Test = domain101TestResults[0];
|
||||
expect(domain101Test.passwordCount).toEqual(2);
|
||||
|
||||
// The first cipher is at risk. The second cipher is not at risk
|
||||
expect(doman101Test.atRiskPasswordCount).toEqual(1);
|
||||
expect(domain101Test.atRiskPasswordCount).toEqual(1);
|
||||
|
||||
// The first cipher has 2 members. The second cipher the second
|
||||
// cipher has 4. One of the members in the first cipher is associated
|
||||
// with the second. So there should be 5 members total.
|
||||
expect(doman101Test.memberCount).toEqual(5);
|
||||
expect(domain101Test.memberCount).toEqual(5);
|
||||
|
||||
// The first cipher is at risk. The total at risk members is 2 and
|
||||
// at risk password count is 1.
|
||||
expect(doman101Test.atRiskMemberDetails).toHaveLength(2);
|
||||
expect(doman101Test.atRiskPasswordCount).toEqual(1);
|
||||
expect(domain101Test.atRiskMemberDetails).toHaveLength(2);
|
||||
expect(domain101Test.atRiskPasswordCount).toEqual(1);
|
||||
});
|
||||
|
||||
it("should generate applications summary data correctly", async () => {
|
||||
const reportResult = await service.generateApplicationsReport("orgId");
|
||||
const reportResult = await firstValueFrom(service.generateApplicationsReport$("orgId"));
|
||||
const reportSummary = service.generateApplicationsSummary(reportResult);
|
||||
|
||||
expect(reportSummary.totalMemberCount).toEqual(7);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { concatMap, first, from, map, Observable, zip } from "rxjs";
|
||||
|
||||
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
@@ -36,15 +37,25 @@ export class RiskInsightsReportService {
|
||||
* @param organizationId
|
||||
* @returns Cipher health report data with members and trimmed uris
|
||||
*/
|
||||
async generateRawDataReport(organizationId: string): Promise<CipherHealthReportDetail[]> {
|
||||
const allCiphers = await this.cipherService.getAllFromApiForOrganization(organizationId);
|
||||
const memberCipherDetails =
|
||||
await this.memberCipherDetailsApiService.getMemberCipherDetails(organizationId);
|
||||
const flattenedDetails: MemberDetailsFlat[] = memberCipherDetails.flatMap((dtl) =>
|
||||
dtl.cipherIds.map((c) => this.getMemberDetailsFlat(dtl.userName, dtl.email, c)),
|
||||
generateRawDataReport$(organizationId: string): Observable<CipherHealthReportDetail[]> {
|
||||
const allCiphers$ = from(this.cipherService.getAllFromApiForOrganization(organizationId));
|
||||
const memberCiphers$ = from(
|
||||
this.memberCipherDetailsApiService.getMemberCipherDetails(organizationId),
|
||||
);
|
||||
|
||||
return await this.getCipherDetails(allCiphers, flattenedDetails);
|
||||
const results$ = zip(allCiphers$, memberCiphers$).pipe(
|
||||
map(([allCiphers, memberCiphers]) => {
|
||||
const details: MemberDetailsFlat[] = memberCiphers.flatMap((dtl) =>
|
||||
dtl.cipherIds.map((c) => this.getMemberDetailsFlat(dtl.userName, dtl.email, c)),
|
||||
);
|
||||
return [allCiphers, details] as const;
|
||||
}),
|
||||
concatMap(([ciphers, flattenedDetails]) => this.getCipherDetails(ciphers, flattenedDetails)),
|
||||
// timeout(TIMEOUT_IN_MS),
|
||||
first(),
|
||||
);
|
||||
|
||||
return results$;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,10 +64,14 @@ export class RiskInsightsReportService {
|
||||
* @param organizationId Id of the organization
|
||||
* @returns Cipher health report data flattened to the uris
|
||||
*/
|
||||
async generateRawDataUriReport(organizationId: string): Promise<CipherHealthReportUriDetail[]> {
|
||||
const cipherHealthDetails = await this.generateRawDataReport(organizationId);
|
||||
generateRawDataUriReport$(organizationId: string): Observable<CipherHealthReportUriDetail[]> {
|
||||
const cipherHealthDetails$ = this.generateRawDataReport$(organizationId);
|
||||
const results$ = cipherHealthDetails$.pipe(
|
||||
map((healthDetails) => this.getCipherUriDetails(healthDetails)),
|
||||
first(),
|
||||
);
|
||||
|
||||
return this.getCipherUriDetails(cipherHealthDetails);
|
||||
return results$;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,11 +80,16 @@ export class RiskInsightsReportService {
|
||||
* @param organizationId Id of the organization
|
||||
* @returns The all applications health report data
|
||||
*/
|
||||
async generateApplicationsReport(
|
||||
organizationId: string,
|
||||
): Promise<ApplicationHealthReportDetail[]> {
|
||||
const cipherHealthUriReport = await this.generateRawDataUriReport(organizationId);
|
||||
return this.getApplicationHealthReport(cipherHealthUriReport);
|
||||
generateApplicationsReport$(organizationId: string): Observable<ApplicationHealthReportDetail[]> {
|
||||
const cipherHealthUriReport$ = this.generateRawDataUriReport$(organizationId);
|
||||
const results$ = cipherHealthUriReport$.pipe(
|
||||
map((uriDetails) => this.getApplicationHealthReport(uriDetails)),
|
||||
first(),
|
||||
);
|
||||
|
||||
return results$;
|
||||
// const cipherHealthUriReport = await this.generateRawDataUriReport(organizationId);
|
||||
// return this.getApplicationHealthReport(cipherHealthUriReport);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user