1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-10 05:13:29 +00:00

[PM-20112] Update Member Access report to use new server model (#15155)

This commit is contained in:
Vijay Oommen
2025-06-16 16:33:07 -05:00
committed by GitHub
parent fcd24a4d60
commit a9548f519e
5 changed files with 396 additions and 339 deletions

View File

@@ -36,7 +36,7 @@
</ng-container>
<bit-table-scroll *ngIf="!(isLoading$ | async)" [dataSource]="dataSource" [rowSize]="53">
<ng-container header>
<th bitCell bitSortable="name" default>{{ "members" | i18n }}</th>
<th bitCell bitSortable="email" default>{{ "members" | i18n }}</th>
<th bitCell bitSortable="groupsCount" class="tw-w-[278px]">{{ "groups" | i18n }}</th>
<th bitCell bitSortable="collectionsCount" class="tw-w-[278px]">{{ "collections" | i18n }}</th>
<th bitCell bitSortable="itemsCount" class="tw-w-[278px]">{{ "items" | i18n }}</th>

View File

@@ -2,7 +2,15 @@ import { BaseResponse } from "@bitwarden/common/models/response/base.response";
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { Guid } from "@bitwarden/common/types/guid";
export class MemberAccessDetails extends BaseResponse {
export class MemberAccessResponse extends BaseResponse {
userName: string;
email: string;
twoFactorEnabled: boolean;
accountRecoveryEnabled: boolean;
userGuid: Guid;
usesKeyConnector: boolean;
cipherIds: Guid[] = [];
collectionId: string;
groupId: string;
groupName: string;
@@ -14,6 +22,14 @@ export class MemberAccessDetails extends BaseResponse {
constructor(response: any) {
super(response);
this.userName = this.getResponseProperty("UserName");
this.email = this.getResponseProperty("Email");
this.twoFactorEnabled = this.getResponseProperty("TwoFactorEnabled");
this.accountRecoveryEnabled = this.getResponseProperty("AccountRecoveryEnabled");
this.userGuid = this.getResponseProperty("UserGuid");
this.usesKeyConnector = this.getResponseProperty("UsesKeyConnector");
this.cipherIds = this.getResponseProperty("CipherIds") || [];
this.groupId = this.getResponseProperty("GroupId");
this.collectionId = this.getResponseProperty("CollectionId");
this.groupName = this.getResponseProperty("GroupName");
@@ -24,34 +40,3 @@ export class MemberAccessDetails extends BaseResponse {
this.manage = this.getResponseProperty("Manage");
}
}
export class MemberAccessResponse extends BaseResponse {
userName: string;
email: string;
twoFactorEnabled: boolean;
accountRecoveryEnabled: boolean;
collectionsCount: number;
groupsCount: number;
totalItemCount: number;
accessDetails: MemberAccessDetails[] = [];
userGuid: Guid;
usesKeyConnector: boolean;
constructor(response: any) {
super(response);
this.userName = this.getResponseProperty("UserName");
this.email = this.getResponseProperty("Email");
this.twoFactorEnabled = this.getResponseProperty("TwoFactorEnabled");
this.accountRecoveryEnabled = this.getResponseProperty("AccountRecoveryEnabled");
this.collectionsCount = this.getResponseProperty("CollectionsCount");
this.groupsCount = this.getResponseProperty("GroupsCount");
this.totalItemCount = this.getResponseProperty("TotalItemCount");
this.userGuid = this.getResponseProperty("UserGuid");
this.usesKeyConnector = this.getResponseProperty("UsesKeyConnector");
const details = this.getResponseProperty("AccessDetails");
if (details != null) {
this.accessDetails = details.map((o: any) => new MemberAccessDetails(o));
}
}
}

View File

@@ -1,9 +1,7 @@
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { Guid } from "@bitwarden/common/types/guid";
import {
MemberAccessDetails,
MemberAccessResponse,
} from "../response/member-access-report.response";
import { MemberAccessResponse } from "../response/member-access-report.response";
export const memberAccessReportsMock: MemberAccessResponse[] = [
{
@@ -11,223 +9,290 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
email: "sjohnson@email.com",
twoFactorEnabled: true,
accountRecoveryEnabled: true,
groupsCount: 2,
collectionsCount: 4,
totalItemCount: 20,
userGuid: "1234",
userGuid: "1001" as Guid,
usesKeyConnector: false,
accessDetails: [
{
groupId: "",
collectionId: "c1",
collectionName: new EncString("Collection 1"),
groupName: "",
itemCount: 10,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
{
groupId: "",
collectionId: "c2",
collectionName: new EncString("Collection 2"),
groupName: "",
itemCount: 20,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
{
groupId: "",
collectionId: "c3",
collectionName: new EncString("Collection 3"),
groupName: "",
itemCount: 30,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
{
groupId: "g1",
collectionId: "c1",
collectionName: new EncString("Collection 1"),
groupName: "Group 1",
itemCount: 30,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
{
groupId: "g1",
collectionId: "c2",
collectionName: new EncString("Collection 2"),
groupName: "Group 1",
itemCount: 20,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
],
} as MemberAccessResponse,
groupId: "",
collectionId: "c1",
collectionName: new EncString("Collection 1"),
groupName: "",
itemCount: 10,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
{
userName: "Sarah Johnson",
email: "sjohnson@email.com",
twoFactorEnabled: true,
accountRecoveryEnabled: true,
userGuid: "1001" as Guid,
usesKeyConnector: false,
groupId: "",
collectionId: "c2",
collectionName: new EncString("Collection 2"),
groupName: "",
itemCount: 20,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
{
userName: "Sarah Johnson",
email: "sjohnson@email.com",
twoFactorEnabled: true,
accountRecoveryEnabled: true,
userGuid: "1001" as Guid,
usesKeyConnector: false,
groupId: "",
collectionId: "c3",
collectionName: new EncString("Collection 3"),
groupName: "",
itemCount: 30,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
{
userName: "Sarah Johnson",
email: "sjohnson@email.com",
twoFactorEnabled: true,
accountRecoveryEnabled: true,
userGuid: "1001",
usesKeyConnector: false,
groupId: "g1",
collectionId: "c1",
collectionName: new EncString("Collection 1"),
groupName: "Group 1",
itemCount: 30,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
{
userName: "Sarah Johnson",
email: "sjohnson@email.com",
twoFactorEnabled: true,
accountRecoveryEnabled: true,
userGuid: "1001",
usesKeyConnector: false,
groupId: "g1",
collectionId: "c2",
collectionName: new EncString("Collection 2"),
groupName: "Group 1",
itemCount: 20,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
{
userName: "James Lull",
email: "jlull@email.com",
twoFactorEnabled: false,
accountRecoveryEnabled: false,
groupsCount: 2,
collectionsCount: 4,
totalItemCount: 20,
userGuid: "1234",
userGuid: "2001",
usesKeyConnector: false,
accessDetails: [
{
groupId: "g4",
collectionId: "c4",
groupName: "Group 4",
collectionName: new EncString("Collection 4"),
itemCount: 5,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
{
groupId: "g4",
collectionId: "c5",
groupName: "Group 4",
collectionName: new EncString("Collection 5"),
itemCount: 15,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
{
groupId: "",
collectionId: "c4",
groupName: "",
collectionName: new EncString("Collection 4"),
itemCount: 5,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
{
groupId: "",
collectionId: "c5",
groupName: "",
collectionName: new EncString("Collection 5"),
itemCount: 15,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
],
} as MemberAccessResponse,
groupId: "g4",
collectionId: "c4",
groupName: "Group 4",
collectionName: new EncString("Collection 4"),
itemCount: 5,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
{
userName: "James Lull",
email: "jlull@email.com",
twoFactorEnabled: false,
accountRecoveryEnabled: false,
userGuid: "2001",
usesKeyConnector: false,
groupId: "g4",
collectionId: "c5",
groupName: "Group 4",
collectionName: new EncString("Collection 5"),
itemCount: 15,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
{
userName: "James Lull",
email: "jlull@email.com",
twoFactorEnabled: false,
accountRecoveryEnabled: false,
userGuid: "2001",
usesKeyConnector: false,
groupId: "",
collectionId: "c4",
groupName: "",
collectionName: new EncString("Collection 4"),
itemCount: 5,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
{
userName: "James Lull",
email: "jlull@email.com",
twoFactorEnabled: false,
accountRecoveryEnabled: false,
userGuid: "2001",
usesKeyConnector: false,
groupId: "",
collectionId: "c5",
groupName: "",
collectionName: new EncString("Collection 5"),
itemCount: 15,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
{
userName: "Beth Williams",
email: "bwilliams@email.com",
twoFactorEnabled: true,
accountRecoveryEnabled: true,
groupsCount: 2,
collectionsCount: 4,
totalItemCount: 20,
userGuid: "1234",
userGuid: "3001",
usesKeyConnector: false,
accessDetails: [
{
groupId: "",
collectionId: "c6",
groupName: "",
collectionName: new EncString("Collection 6"),
itemCount: 25,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
{
groupId: "g6",
collectionId: "c4",
groupName: "Group 6",
collectionName: new EncString("Collection 4"),
itemCount: 35,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
],
} as MemberAccessResponse,
groupId: "",
collectionId: "c6",
groupName: "",
collectionName: new EncString("Collection 6"),
itemCount: 25,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
{
userName: "Beth Williams",
email: "bwilliams@email.com",
twoFactorEnabled: true,
accountRecoveryEnabled: true,
userGuid: "3001",
usesKeyConnector: false,
groupId: "g6",
collectionId: "c4",
groupName: "Group 6",
collectionName: new EncString("Collection 4"),
itemCount: 35,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
{
userName: "Ray Williams",
email: "rwilliams@email.com",
twoFactorEnabled: false,
accountRecoveryEnabled: false,
groupsCount: 2,
collectionsCount: 4,
totalItemCount: 20,
userGuid: "1234",
userGuid: "4000",
usesKeyConnector: false,
accessDetails: [
{
groupId: "",
collectionId: "c7",
groupName: "",
collectionName: new EncString("Collection 7"),
itemCount: 8,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
{
groupId: "",
collectionId: "c8",
groupName: "",
collectionName: new EncString("Collection 8"),
itemCount: 12,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
{
groupId: "",
collectionId: "c9",
groupName: "",
collectionName: new EncString("Collection 9"),
itemCount: 16,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
{
groupId: "g9",
collectionId: "c7",
groupName: "Group 9",
collectionName: new EncString("Collection 7"),
itemCount: 8,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
{
groupId: "g10",
collectionId: "c8",
groupName: "Group 10",
collectionName: new EncString("Collection 8"),
itemCount: 12,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
{
groupId: "g11",
collectionId: "c9",
groupName: "Group 11",
collectionName: new EncString("Collection 9"),
itemCount: 16,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
],
} as MemberAccessResponse,
groupId: "",
collectionId: "c7",
groupName: "",
collectionName: new EncString("Collection 7"),
itemCount: 8,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
{
userName: "Ray Williams",
email: "rwilliams@email.com",
twoFactorEnabled: false,
accountRecoveryEnabled: false,
userGuid: "4000",
usesKeyConnector: false,
groupId: "",
collectionId: "c8",
groupName: "",
collectionName: new EncString("Collection 8"),
itemCount: 12,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
{
userName: "Ray Williams",
email: "rwilliams@email.com",
twoFactorEnabled: false,
accountRecoveryEnabled: false,
userGuid: "4000",
usesKeyConnector: false,
groupId: "",
collectionId: "c9",
groupName: "",
collectionName: new EncString("Collection 9"),
itemCount: 16,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
{
userName: "Ray Williams",
email: "rwilliams@email.com",
twoFactorEnabled: false,
accountRecoveryEnabled: false,
userGuid: "4000",
usesKeyConnector: false,
groupId: "g9",
collectionId: "c7",
groupName: "Group 9",
collectionName: new EncString("Collection 7"),
itemCount: 8,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
{
userName: "Ray Williams",
email: "rwilliams@email.com",
twoFactorEnabled: false,
accountRecoveryEnabled: false,
userGuid: "4000",
usesKeyConnector: false,
groupId: "g10",
collectionId: "c8",
groupName: "Group 10",
collectionName: new EncString("Collection 8"),
itemCount: 12,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
{
userName: "Ray Williams",
email: "rwilliams@email.com",
twoFactorEnabled: false,
accountRecoveryEnabled: false,
userGuid: "4000",
usesKeyConnector: false,
groupId: "g11",
collectionId: "c9",
groupName: "Group 11",
collectionName: new EncString("Collection 9"),
itemCount: 16,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
];
export const memberAccessWithoutAccessDetailsReportsMock: MemberAccessResponse[] = [
@@ -236,34 +301,33 @@ export const memberAccessWithoutAccessDetailsReportsMock: MemberAccessResponse[]
email: "asmith@email.com",
twoFactorEnabled: true,
accountRecoveryEnabled: true,
groupsCount: 2,
collectionsCount: 4,
totalItemCount: 20,
userGuid: "1234",
userGuid: "1234" as Guid,
usesKeyConnector: false,
accessDetails: [
{
groupId: "",
collectionId: "c1",
collectionName: new EncString("Collection 1"),
groupName: "Alice Group 1",
itemCount: 10,
readOnly: false,
hidePasswords: false,
manage: false,
} as MemberAccessDetails,
],
} as MemberAccessResponse,
groupId: "",
collectionId: "c1",
collectionName: new EncString("Collection 1"),
groupName: "Alice Group 1",
itemCount: 10,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
{
userName: "Robert Brown",
email: "rbrown@email.com",
twoFactorEnabled: false,
accountRecoveryEnabled: false,
groupsCount: 2,
collectionsCount: 4,
totalItemCount: 20,
userGuid: "5678",
userGuid: "5678" as Guid,
usesKeyConnector: false,
accessDetails: [] as MemberAccessDetails[],
} as MemberAccessResponse,
groupId: "",
collectionId: "c1",
collectionName: new EncString("Collection 1"),
groupName: "",
itemCount: 10,
readOnly: false,
hidePasswords: false,
manage: false,
cipherIds: [],
} as unknown as MemberAccessResponse,
];

View File

@@ -35,36 +35,36 @@ describe("ImportService", () => {
{
name: "Sarah Johnson",
email: "sjohnson@email.com",
collectionsCount: 4,
groupsCount: 2,
itemsCount: 20,
collectionsCount: 3,
groupsCount: 1,
itemsCount: 0,
userGuid: expect.any(String),
usesKeyConnector: expect.any(Boolean),
},
{
name: "James Lull",
email: "jlull@email.com",
collectionsCount: 4,
groupsCount: 2,
itemsCount: 20,
collectionsCount: 2,
groupsCount: 1,
itemsCount: 0,
userGuid: expect.any(String),
usesKeyConnector: expect.any(Boolean),
},
{
name: "Beth Williams",
email: "bwilliams@email.com",
collectionsCount: 4,
groupsCount: 2,
itemsCount: 20,
collectionsCount: 2,
groupsCount: 1,
itemsCount: 0,
userGuid: expect.any(String),
usesKeyConnector: expect.any(Boolean),
},
{
name: "Ray Williams",
email: "rwilliams@email.com",
collectionsCount: 4,
groupsCount: 2,
itemsCount: 20,
collectionsCount: 3,
groupsCount: 3,
itemsCount: 0,
userGuid: expect.any(String),
usesKeyConnector: expect.any(Boolean),
},
@@ -82,8 +82,8 @@ describe("ImportService", () => {
(item) =>
(item.name === "Sarah Johnson" &&
item.group === "Group 1" &&
item.totalItems === "20") ||
(item.name === "James Lull" && item.group === "Group 4" && item.totalItems === "5"),
item.totalItems === "0") ||
(item.name === "James Lull" && item.group === "Group 4" && item.totalItems === "0"),
)
.map((item) => ({
name: item.name,
@@ -102,7 +102,7 @@ describe("ImportService", () => {
twoStepLogin: "memberAccessReportTwoFactorEnabledTrue",
accountRecovery: "memberAccessReportAuthenticationEnabledTrue",
group: "Group 1",
totalItems: "20",
totalItems: "0",
}),
expect.objectContaining({
email: "jlull@email.com",
@@ -110,7 +110,7 @@ describe("ImportService", () => {
twoStepLogin: "memberAccessReportTwoFactorEnabledFalse",
accountRecovery: "memberAccessReportAuthenticationEnabledFalse",
group: "Group 4",
totalItems: "5",
totalItems: "0",
}),
]),
);
@@ -131,7 +131,7 @@ describe("ImportService", () => {
twoStepLogin: "memberAccessReportTwoFactorEnabledTrue",
accountRecovery: "memberAccessReportAuthenticationEnabledTrue",
group: "Alice Group 1",
totalItems: "10",
totalItems: "0",
}),
expect.objectContaining({
email: "rbrown@email.com",

View File

@@ -5,13 +5,13 @@ import { Injectable } from "@angular/core";
import { CollectionAccessSelectionView } from "@bitwarden/admin-console/common";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { OrganizationId } from "@bitwarden/common/types/guid";
import { Guid, OrganizationId } from "@bitwarden/common/types/guid";
import {
getPermissionList,
convertToPermission,
} from "@bitwarden/web-vault/app/admin-console/organizations/shared/components/access-selector";
import { MemberAccessDetails } from "../response/member-access-report.response";
import { MemberAccessResponse } from "../response/member-access-report.response";
import { MemberAccessExportItem } from "../view/member-access-export.view";
import { MemberAccessReportView } from "../view/member-access-report.view";
@@ -34,15 +34,44 @@ export class MemberAccessReportService {
organizationId: OrganizationId,
): Promise<MemberAccessReportView[]> {
const memberAccessData = await this.reportApiService.getMemberAccessData(organizationId);
const memberAccessReportViewCollection = memberAccessData.map((userData) => ({
name: userData.userName,
email: userData.email,
collectionsCount: userData.collectionsCount,
groupsCount: userData.groupsCount,
itemsCount: userData.totalItemCount,
userGuid: userData.userGuid,
usesKeyConnector: userData.usesKeyConnector,
}));
// group member access data by userGuid
const userMap = new Map<Guid, MemberAccessResponse[]>();
memberAccessData.forEach((userData) => {
const userGuid = userData.userGuid;
if (!userMap.has(userGuid)) {
userMap.set(userGuid, []);
}
userMap.get(userGuid)?.push(userData);
});
// aggregate user data
const memberAccessReportViewCollection: MemberAccessReportView[] = [];
userMap.forEach((userDataArray, userGuid) => {
const collectionCount = this.getDistinctCount<string>(
userDataArray.map((data) => data.collectionId).filter((id) => !!id),
);
const groupCount = this.getDistinctCount<string>(
userDataArray.map((data) => data.groupId).filter((id) => !!id),
);
const itemsCount = this.getDistinctCount<Guid>(
userDataArray
.flatMap((data) => data.cipherIds)
.filter((id) => id !== "00000000-0000-0000-0000-000000000000"),
);
const aggregatedData = {
userGuid: userGuid,
name: userDataArray[0].userName,
email: userDataArray[0].email,
collectionsCount: collectionCount,
groupsCount: groupCount,
itemsCount: itemsCount,
usesKeyConnector: userDataArray.some((data) => data.usesKeyConnector),
};
memberAccessReportViewCollection.push(aggregatedData);
});
return memberAccessReportViewCollection;
}
@@ -50,13 +79,8 @@ export class MemberAccessReportService {
organizationId: OrganizationId,
): Promise<MemberAccessExportItem[]> {
const memberAccessReports = await this.reportApiService.getMemberAccessData(organizationId);
const collectionNames = memberAccessReports.flatMap((item) =>
item.accessDetails.map((dtl) => {
if (dtl.collectionName) {
return dtl.collectionName.encryptedString;
}
}),
);
const collectionNames = memberAccessReports.map((item) => item.collectionName.encryptedString);
const collectionNameMap = new Map(collectionNames.map((col) => [col, ""]));
for await (const key of collectionNameMap.keys()) {
const decrypted = new EncString(key);
@@ -64,56 +88,35 @@ export class MemberAccessReportService {
collectionNameMap.set(key, decrypted.decryptedValue);
}
const exportItems = memberAccessReports.flatMap((report) => {
// to include users without access details
// which means a user has no groups, collections or items
if (report.accessDetails.length === 0) {
return [
{
email: report.email,
name: report.userName,
twoStepLogin: report.twoFactorEnabled
? this.i18nService.t("memberAccessReportTwoFactorEnabledTrue")
: this.i18nService.t("memberAccessReportTwoFactorEnabledFalse"),
accountRecovery: report.accountRecoveryEnabled
? this.i18nService.t("memberAccessReportAuthenticationEnabledTrue")
: this.i18nService.t("memberAccessReportAuthenticationEnabledFalse"),
group: this.i18nService.t("memberAccessReportNoGroup"),
collection: this.i18nService.t("memberAccessReportNoCollection"),
collectionPermission: this.i18nService.t("memberAccessReportNoCollectionPermission"),
totalItems: "0",
},
];
}
const userDetails = report.accessDetails.map((detail) => {
const collectionName = collectionNameMap.get(detail.collectionName.encryptedString);
return {
email: report.email,
name: report.userName,
twoStepLogin: report.twoFactorEnabled
? this.i18nService.t("memberAccessReportTwoFactorEnabledTrue")
: this.i18nService.t("memberAccessReportTwoFactorEnabledFalse"),
accountRecovery: report.accountRecoveryEnabled
? this.i18nService.t("memberAccessReportAuthenticationEnabledTrue")
: this.i18nService.t("memberAccessReportAuthenticationEnabledFalse"),
group: detail.groupName
? detail.groupName
: this.i18nService.t("memberAccessReportNoGroup"),
collection: collectionName
? collectionName
: this.i18nService.t("memberAccessReportNoCollection"),
collectionPermission: detail.collectionId
? this.getPermissionText(detail)
: this.i18nService.t("memberAccessReportNoCollectionPermission"),
totalItems: detail.itemCount.toString(),
};
});
return userDetails;
const exportItems = memberAccessReports.map((report) => {
const collectionName = collectionNameMap.get(report.collectionName.encryptedString);
return {
email: report.email,
name: report.userName,
twoStepLogin: report.twoFactorEnabled
? this.i18nService.t("memberAccessReportTwoFactorEnabledTrue")
: this.i18nService.t("memberAccessReportTwoFactorEnabledFalse"),
accountRecovery: report.accountRecoveryEnabled
? this.i18nService.t("memberAccessReportAuthenticationEnabledTrue")
: this.i18nService.t("memberAccessReportAuthenticationEnabledFalse"),
group: report.groupName
? report.groupName
: this.i18nService.t("memberAccessReportNoGroup"),
collection: collectionName
? collectionName
: this.i18nService.t("memberAccessReportNoCollection"),
collectionPermission: report.collectionId
? this.getPermissionText(report)
: this.i18nService.t("memberAccessReportNoCollectionPermission"),
totalItems: report.cipherIds
.filter((_) => _ != "00000000-0000-0000-0000-000000000000")
.length.toString(),
};
});
return exportItems.flat();
}
private getPermissionText(accessDetails: MemberAccessDetails): string {
private getPermissionText(accessDetails: MemberAccessResponse): string {
const permissionList = getPermissionList();
const collectionSelectionView = new CollectionAccessSelectionView({
id: accessDetails.groupId ?? accessDetails.collectionId,
@@ -125,4 +128,9 @@ export class MemberAccessReportService {
permissionList.find((p) => p.perm === convertToPermission(collectionSelectionView))?.labelId,
);
}
private getDistinctCount<T>(items: T[]): number {
const uniqueItems = new Set(items);
return uniqueItems.size;
}
}