mirror of
https://github.com/bitwarden/browser
synced 2025-12-11 13:53:34 +00:00
[PM-20112] Update Member Access report to use new server model (#15155)
This commit is contained in:
@@ -36,7 +36,7 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
<bit-table-scroll *ngIf="!(isLoading$ | async)" [dataSource]="dataSource" [rowSize]="53">
|
<bit-table-scroll *ngIf="!(isLoading$ | async)" [dataSource]="dataSource" [rowSize]="53">
|
||||||
<ng-container header>
|
<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="groupsCount" class="tw-w-[278px]">{{ "groups" | i18n }}</th>
|
||||||
<th bitCell bitSortable="collectionsCount" class="tw-w-[278px]">{{ "collections" | i18n }}</th>
|
<th bitCell bitSortable="collectionsCount" class="tw-w-[278px]">{{ "collections" | i18n }}</th>
|
||||||
<th bitCell bitSortable="itemsCount" class="tw-w-[278px]">{{ "items" | i18n }}</th>
|
<th bitCell bitSortable="itemsCount" class="tw-w-[278px]">{{ "items" | i18n }}</th>
|
||||||
|
|||||||
@@ -2,7 +2,15 @@ import { BaseResponse } from "@bitwarden/common/models/response/base.response";
|
|||||||
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||||
import { Guid } from "@bitwarden/common/types/guid";
|
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;
|
collectionId: string;
|
||||||
groupId: string;
|
groupId: string;
|
||||||
groupName: string;
|
groupName: string;
|
||||||
@@ -14,6 +22,14 @@ export class MemberAccessDetails extends BaseResponse {
|
|||||||
|
|
||||||
constructor(response: any) {
|
constructor(response: any) {
|
||||||
super(response);
|
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.groupId = this.getResponseProperty("GroupId");
|
||||||
this.collectionId = this.getResponseProperty("CollectionId");
|
this.collectionId = this.getResponseProperty("CollectionId");
|
||||||
this.groupName = this.getResponseProperty("GroupName");
|
this.groupName = this.getResponseProperty("GroupName");
|
||||||
@@ -24,34 +40,3 @@ export class MemberAccessDetails extends BaseResponse {
|
|||||||
this.manage = this.getResponseProperty("Manage");
|
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||||
|
import { Guid } from "@bitwarden/common/types/guid";
|
||||||
|
|
||||||
import {
|
import { MemberAccessResponse } from "../response/member-access-report.response";
|
||||||
MemberAccessDetails,
|
|
||||||
MemberAccessResponse,
|
|
||||||
} from "../response/member-access-report.response";
|
|
||||||
|
|
||||||
export const memberAccessReportsMock: MemberAccessResponse[] = [
|
export const memberAccessReportsMock: MemberAccessResponse[] = [
|
||||||
{
|
{
|
||||||
@@ -11,13 +9,8 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
email: "sjohnson@email.com",
|
email: "sjohnson@email.com",
|
||||||
twoFactorEnabled: true,
|
twoFactorEnabled: true,
|
||||||
accountRecoveryEnabled: true,
|
accountRecoveryEnabled: true,
|
||||||
groupsCount: 2,
|
userGuid: "1001" as Guid,
|
||||||
collectionsCount: 4,
|
|
||||||
totalItemCount: 20,
|
|
||||||
userGuid: "1234",
|
|
||||||
usesKeyConnector: false,
|
usesKeyConnector: false,
|
||||||
accessDetails: [
|
|
||||||
{
|
|
||||||
groupId: "",
|
groupId: "",
|
||||||
collectionId: "c1",
|
collectionId: "c1",
|
||||||
collectionName: new EncString("Collection 1"),
|
collectionName: new EncString("Collection 1"),
|
||||||
@@ -26,8 +19,15 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
|
} as unknown as MemberAccessResponse,
|
||||||
{
|
{
|
||||||
|
userName: "Sarah Johnson",
|
||||||
|
email: "sjohnson@email.com",
|
||||||
|
twoFactorEnabled: true,
|
||||||
|
accountRecoveryEnabled: true,
|
||||||
|
userGuid: "1001" as Guid,
|
||||||
|
usesKeyConnector: false,
|
||||||
groupId: "",
|
groupId: "",
|
||||||
collectionId: "c2",
|
collectionId: "c2",
|
||||||
collectionName: new EncString("Collection 2"),
|
collectionName: new EncString("Collection 2"),
|
||||||
@@ -36,8 +36,15 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
|
} as unknown as MemberAccessResponse,
|
||||||
{
|
{
|
||||||
|
userName: "Sarah Johnson",
|
||||||
|
email: "sjohnson@email.com",
|
||||||
|
twoFactorEnabled: true,
|
||||||
|
accountRecoveryEnabled: true,
|
||||||
|
userGuid: "1001" as Guid,
|
||||||
|
usesKeyConnector: false,
|
||||||
groupId: "",
|
groupId: "",
|
||||||
collectionId: "c3",
|
collectionId: "c3",
|
||||||
collectionName: new EncString("Collection 3"),
|
collectionName: new EncString("Collection 3"),
|
||||||
@@ -46,8 +53,15 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
|
} as unknown as MemberAccessResponse,
|
||||||
{
|
{
|
||||||
|
userName: "Sarah Johnson",
|
||||||
|
email: "sjohnson@email.com",
|
||||||
|
twoFactorEnabled: true,
|
||||||
|
accountRecoveryEnabled: true,
|
||||||
|
userGuid: "1001",
|
||||||
|
usesKeyConnector: false,
|
||||||
groupId: "g1",
|
groupId: "g1",
|
||||||
collectionId: "c1",
|
collectionId: "c1",
|
||||||
collectionName: new EncString("Collection 1"),
|
collectionName: new EncString("Collection 1"),
|
||||||
@@ -56,8 +70,15 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
|
} as unknown as MemberAccessResponse,
|
||||||
{
|
{
|
||||||
|
userName: "Sarah Johnson",
|
||||||
|
email: "sjohnson@email.com",
|
||||||
|
twoFactorEnabled: true,
|
||||||
|
accountRecoveryEnabled: true,
|
||||||
|
userGuid: "1001",
|
||||||
|
usesKeyConnector: false,
|
||||||
groupId: "g1",
|
groupId: "g1",
|
||||||
collectionId: "c2",
|
collectionId: "c2",
|
||||||
collectionName: new EncString("Collection 2"),
|
collectionName: new EncString("Collection 2"),
|
||||||
@@ -66,21 +87,15 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
],
|
} as unknown as MemberAccessResponse,
|
||||||
} as MemberAccessResponse,
|
|
||||||
{
|
{
|
||||||
userName: "James Lull",
|
userName: "James Lull",
|
||||||
email: "jlull@email.com",
|
email: "jlull@email.com",
|
||||||
twoFactorEnabled: false,
|
twoFactorEnabled: false,
|
||||||
accountRecoveryEnabled: false,
|
accountRecoveryEnabled: false,
|
||||||
groupsCount: 2,
|
userGuid: "2001",
|
||||||
collectionsCount: 4,
|
|
||||||
totalItemCount: 20,
|
|
||||||
userGuid: "1234",
|
|
||||||
usesKeyConnector: false,
|
usesKeyConnector: false,
|
||||||
accessDetails: [
|
|
||||||
{
|
|
||||||
groupId: "g4",
|
groupId: "g4",
|
||||||
collectionId: "c4",
|
collectionId: "c4",
|
||||||
groupName: "Group 4",
|
groupName: "Group 4",
|
||||||
@@ -89,8 +104,15 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
|
} as unknown as MemberAccessResponse,
|
||||||
{
|
{
|
||||||
|
userName: "James Lull",
|
||||||
|
email: "jlull@email.com",
|
||||||
|
twoFactorEnabled: false,
|
||||||
|
accountRecoveryEnabled: false,
|
||||||
|
userGuid: "2001",
|
||||||
|
usesKeyConnector: false,
|
||||||
groupId: "g4",
|
groupId: "g4",
|
||||||
collectionId: "c5",
|
collectionId: "c5",
|
||||||
groupName: "Group 4",
|
groupName: "Group 4",
|
||||||
@@ -99,8 +121,15 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
|
} as unknown as MemberAccessResponse,
|
||||||
{
|
{
|
||||||
|
userName: "James Lull",
|
||||||
|
email: "jlull@email.com",
|
||||||
|
twoFactorEnabled: false,
|
||||||
|
accountRecoveryEnabled: false,
|
||||||
|
userGuid: "2001",
|
||||||
|
usesKeyConnector: false,
|
||||||
groupId: "",
|
groupId: "",
|
||||||
collectionId: "c4",
|
collectionId: "c4",
|
||||||
groupName: "",
|
groupName: "",
|
||||||
@@ -109,8 +138,15 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
|
} as unknown as MemberAccessResponse,
|
||||||
{
|
{
|
||||||
|
userName: "James Lull",
|
||||||
|
email: "jlull@email.com",
|
||||||
|
twoFactorEnabled: false,
|
||||||
|
accountRecoveryEnabled: false,
|
||||||
|
userGuid: "2001",
|
||||||
|
usesKeyConnector: false,
|
||||||
groupId: "",
|
groupId: "",
|
||||||
collectionId: "c5",
|
collectionId: "c5",
|
||||||
groupName: "",
|
groupName: "",
|
||||||
@@ -119,21 +155,15 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
],
|
} as unknown as MemberAccessResponse,
|
||||||
} as MemberAccessResponse,
|
|
||||||
{
|
{
|
||||||
userName: "Beth Williams",
|
userName: "Beth Williams",
|
||||||
email: "bwilliams@email.com",
|
email: "bwilliams@email.com",
|
||||||
twoFactorEnabled: true,
|
twoFactorEnabled: true,
|
||||||
accountRecoveryEnabled: true,
|
accountRecoveryEnabled: true,
|
||||||
groupsCount: 2,
|
userGuid: "3001",
|
||||||
collectionsCount: 4,
|
|
||||||
totalItemCount: 20,
|
|
||||||
userGuid: "1234",
|
|
||||||
usesKeyConnector: false,
|
usesKeyConnector: false,
|
||||||
accessDetails: [
|
|
||||||
{
|
|
||||||
groupId: "",
|
groupId: "",
|
||||||
collectionId: "c6",
|
collectionId: "c6",
|
||||||
groupName: "",
|
groupName: "",
|
||||||
@@ -142,8 +172,15 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
|
} as unknown as MemberAccessResponse,
|
||||||
{
|
{
|
||||||
|
userName: "Beth Williams",
|
||||||
|
email: "bwilliams@email.com",
|
||||||
|
twoFactorEnabled: true,
|
||||||
|
accountRecoveryEnabled: true,
|
||||||
|
userGuid: "3001",
|
||||||
|
usesKeyConnector: false,
|
||||||
groupId: "g6",
|
groupId: "g6",
|
||||||
collectionId: "c4",
|
collectionId: "c4",
|
||||||
groupName: "Group 6",
|
groupName: "Group 6",
|
||||||
@@ -152,21 +189,15 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
],
|
} as unknown as MemberAccessResponse,
|
||||||
} as MemberAccessResponse,
|
|
||||||
{
|
{
|
||||||
userName: "Ray Williams",
|
userName: "Ray Williams",
|
||||||
email: "rwilliams@email.com",
|
email: "rwilliams@email.com",
|
||||||
twoFactorEnabled: false,
|
twoFactorEnabled: false,
|
||||||
accountRecoveryEnabled: false,
|
accountRecoveryEnabled: false,
|
||||||
groupsCount: 2,
|
userGuid: "4000",
|
||||||
collectionsCount: 4,
|
|
||||||
totalItemCount: 20,
|
|
||||||
userGuid: "1234",
|
|
||||||
usesKeyConnector: false,
|
usesKeyConnector: false,
|
||||||
accessDetails: [
|
|
||||||
{
|
|
||||||
groupId: "",
|
groupId: "",
|
||||||
collectionId: "c7",
|
collectionId: "c7",
|
||||||
groupName: "",
|
groupName: "",
|
||||||
@@ -175,8 +206,15 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
|
} as unknown as MemberAccessResponse,
|
||||||
{
|
{
|
||||||
|
userName: "Ray Williams",
|
||||||
|
email: "rwilliams@email.com",
|
||||||
|
twoFactorEnabled: false,
|
||||||
|
accountRecoveryEnabled: false,
|
||||||
|
userGuid: "4000",
|
||||||
|
usesKeyConnector: false,
|
||||||
groupId: "",
|
groupId: "",
|
||||||
collectionId: "c8",
|
collectionId: "c8",
|
||||||
groupName: "",
|
groupName: "",
|
||||||
@@ -185,8 +223,15 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
|
} as unknown as MemberAccessResponse,
|
||||||
{
|
{
|
||||||
|
userName: "Ray Williams",
|
||||||
|
email: "rwilliams@email.com",
|
||||||
|
twoFactorEnabled: false,
|
||||||
|
accountRecoveryEnabled: false,
|
||||||
|
userGuid: "4000",
|
||||||
|
usesKeyConnector: false,
|
||||||
groupId: "",
|
groupId: "",
|
||||||
collectionId: "c9",
|
collectionId: "c9",
|
||||||
groupName: "",
|
groupName: "",
|
||||||
@@ -195,8 +240,15 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
|
} as unknown as MemberAccessResponse,
|
||||||
{
|
{
|
||||||
|
userName: "Ray Williams",
|
||||||
|
email: "rwilliams@email.com",
|
||||||
|
twoFactorEnabled: false,
|
||||||
|
accountRecoveryEnabled: false,
|
||||||
|
userGuid: "4000",
|
||||||
|
usesKeyConnector: false,
|
||||||
groupId: "g9",
|
groupId: "g9",
|
||||||
collectionId: "c7",
|
collectionId: "c7",
|
||||||
groupName: "Group 9",
|
groupName: "Group 9",
|
||||||
@@ -205,8 +257,15 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
|
} as unknown as MemberAccessResponse,
|
||||||
{
|
{
|
||||||
|
userName: "Ray Williams",
|
||||||
|
email: "rwilliams@email.com",
|
||||||
|
twoFactorEnabled: false,
|
||||||
|
accountRecoveryEnabled: false,
|
||||||
|
userGuid: "4000",
|
||||||
|
usesKeyConnector: false,
|
||||||
groupId: "g10",
|
groupId: "g10",
|
||||||
collectionId: "c8",
|
collectionId: "c8",
|
||||||
groupName: "Group 10",
|
groupName: "Group 10",
|
||||||
@@ -215,8 +274,15 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
|
} as unknown as MemberAccessResponse,
|
||||||
{
|
{
|
||||||
|
userName: "Ray Williams",
|
||||||
|
email: "rwilliams@email.com",
|
||||||
|
twoFactorEnabled: false,
|
||||||
|
accountRecoveryEnabled: false,
|
||||||
|
userGuid: "4000",
|
||||||
|
usesKeyConnector: false,
|
||||||
groupId: "g11",
|
groupId: "g11",
|
||||||
collectionId: "c9",
|
collectionId: "c9",
|
||||||
groupName: "Group 11",
|
groupName: "Group 11",
|
||||||
@@ -225,9 +291,8 @@ export const memberAccessReportsMock: MemberAccessResponse[] = [
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
],
|
} as unknown as MemberAccessResponse,
|
||||||
} as MemberAccessResponse,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export const memberAccessWithoutAccessDetailsReportsMock: MemberAccessResponse[] = [
|
export const memberAccessWithoutAccessDetailsReportsMock: MemberAccessResponse[] = [
|
||||||
@@ -236,13 +301,8 @@ export const memberAccessWithoutAccessDetailsReportsMock: MemberAccessResponse[]
|
|||||||
email: "asmith@email.com",
|
email: "asmith@email.com",
|
||||||
twoFactorEnabled: true,
|
twoFactorEnabled: true,
|
||||||
accountRecoveryEnabled: true,
|
accountRecoveryEnabled: true,
|
||||||
groupsCount: 2,
|
userGuid: "1234" as Guid,
|
||||||
collectionsCount: 4,
|
|
||||||
totalItemCount: 20,
|
|
||||||
userGuid: "1234",
|
|
||||||
usesKeyConnector: false,
|
usesKeyConnector: false,
|
||||||
accessDetails: [
|
|
||||||
{
|
|
||||||
groupId: "",
|
groupId: "",
|
||||||
collectionId: "c1",
|
collectionId: "c1",
|
||||||
collectionName: new EncString("Collection 1"),
|
collectionName: new EncString("Collection 1"),
|
||||||
@@ -251,19 +311,23 @@ export const memberAccessWithoutAccessDetailsReportsMock: MemberAccessResponse[]
|
|||||||
readOnly: false,
|
readOnly: false,
|
||||||
hidePasswords: false,
|
hidePasswords: false,
|
||||||
manage: false,
|
manage: false,
|
||||||
} as MemberAccessDetails,
|
cipherIds: [],
|
||||||
],
|
} as unknown as MemberAccessResponse,
|
||||||
} as MemberAccessResponse,
|
|
||||||
{
|
{
|
||||||
userName: "Robert Brown",
|
userName: "Robert Brown",
|
||||||
email: "rbrown@email.com",
|
email: "rbrown@email.com",
|
||||||
twoFactorEnabled: false,
|
twoFactorEnabled: false,
|
||||||
accountRecoveryEnabled: false,
|
accountRecoveryEnabled: false,
|
||||||
groupsCount: 2,
|
userGuid: "5678" as Guid,
|
||||||
collectionsCount: 4,
|
|
||||||
totalItemCount: 20,
|
|
||||||
userGuid: "5678",
|
|
||||||
usesKeyConnector: false,
|
usesKeyConnector: false,
|
||||||
accessDetails: [] as MemberAccessDetails[],
|
groupId: "",
|
||||||
} as MemberAccessResponse,
|
collectionId: "c1",
|
||||||
|
collectionName: new EncString("Collection 1"),
|
||||||
|
groupName: "",
|
||||||
|
itemCount: 10,
|
||||||
|
readOnly: false,
|
||||||
|
hidePasswords: false,
|
||||||
|
manage: false,
|
||||||
|
cipherIds: [],
|
||||||
|
} as unknown as MemberAccessResponse,
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -35,36 +35,36 @@ describe("ImportService", () => {
|
|||||||
{
|
{
|
||||||
name: "Sarah Johnson",
|
name: "Sarah Johnson",
|
||||||
email: "sjohnson@email.com",
|
email: "sjohnson@email.com",
|
||||||
collectionsCount: 4,
|
collectionsCount: 3,
|
||||||
groupsCount: 2,
|
groupsCount: 1,
|
||||||
itemsCount: 20,
|
itemsCount: 0,
|
||||||
userGuid: expect.any(String),
|
userGuid: expect.any(String),
|
||||||
usesKeyConnector: expect.any(Boolean),
|
usesKeyConnector: expect.any(Boolean),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "James Lull",
|
name: "James Lull",
|
||||||
email: "jlull@email.com",
|
email: "jlull@email.com",
|
||||||
collectionsCount: 4,
|
collectionsCount: 2,
|
||||||
groupsCount: 2,
|
groupsCount: 1,
|
||||||
itemsCount: 20,
|
itemsCount: 0,
|
||||||
userGuid: expect.any(String),
|
userGuid: expect.any(String),
|
||||||
usesKeyConnector: expect.any(Boolean),
|
usesKeyConnector: expect.any(Boolean),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Beth Williams",
|
name: "Beth Williams",
|
||||||
email: "bwilliams@email.com",
|
email: "bwilliams@email.com",
|
||||||
collectionsCount: 4,
|
collectionsCount: 2,
|
||||||
groupsCount: 2,
|
groupsCount: 1,
|
||||||
itemsCount: 20,
|
itemsCount: 0,
|
||||||
userGuid: expect.any(String),
|
userGuid: expect.any(String),
|
||||||
usesKeyConnector: expect.any(Boolean),
|
usesKeyConnector: expect.any(Boolean),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Ray Williams",
|
name: "Ray Williams",
|
||||||
email: "rwilliams@email.com",
|
email: "rwilliams@email.com",
|
||||||
collectionsCount: 4,
|
collectionsCount: 3,
|
||||||
groupsCount: 2,
|
groupsCount: 3,
|
||||||
itemsCount: 20,
|
itemsCount: 0,
|
||||||
userGuid: expect.any(String),
|
userGuid: expect.any(String),
|
||||||
usesKeyConnector: expect.any(Boolean),
|
usesKeyConnector: expect.any(Boolean),
|
||||||
},
|
},
|
||||||
@@ -82,8 +82,8 @@ describe("ImportService", () => {
|
|||||||
(item) =>
|
(item) =>
|
||||||
(item.name === "Sarah Johnson" &&
|
(item.name === "Sarah Johnson" &&
|
||||||
item.group === "Group 1" &&
|
item.group === "Group 1" &&
|
||||||
item.totalItems === "20") ||
|
item.totalItems === "0") ||
|
||||||
(item.name === "James Lull" && item.group === "Group 4" && item.totalItems === "5"),
|
(item.name === "James Lull" && item.group === "Group 4" && item.totalItems === "0"),
|
||||||
)
|
)
|
||||||
.map((item) => ({
|
.map((item) => ({
|
||||||
name: item.name,
|
name: item.name,
|
||||||
@@ -102,7 +102,7 @@ describe("ImportService", () => {
|
|||||||
twoStepLogin: "memberAccessReportTwoFactorEnabledTrue",
|
twoStepLogin: "memberAccessReportTwoFactorEnabledTrue",
|
||||||
accountRecovery: "memberAccessReportAuthenticationEnabledTrue",
|
accountRecovery: "memberAccessReportAuthenticationEnabledTrue",
|
||||||
group: "Group 1",
|
group: "Group 1",
|
||||||
totalItems: "20",
|
totalItems: "0",
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
email: "jlull@email.com",
|
email: "jlull@email.com",
|
||||||
@@ -110,7 +110,7 @@ describe("ImportService", () => {
|
|||||||
twoStepLogin: "memberAccessReportTwoFactorEnabledFalse",
|
twoStepLogin: "memberAccessReportTwoFactorEnabledFalse",
|
||||||
accountRecovery: "memberAccessReportAuthenticationEnabledFalse",
|
accountRecovery: "memberAccessReportAuthenticationEnabledFalse",
|
||||||
group: "Group 4",
|
group: "Group 4",
|
||||||
totalItems: "5",
|
totalItems: "0",
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
@@ -131,7 +131,7 @@ describe("ImportService", () => {
|
|||||||
twoStepLogin: "memberAccessReportTwoFactorEnabledTrue",
|
twoStepLogin: "memberAccessReportTwoFactorEnabledTrue",
|
||||||
accountRecovery: "memberAccessReportAuthenticationEnabledTrue",
|
accountRecovery: "memberAccessReportAuthenticationEnabledTrue",
|
||||||
group: "Alice Group 1",
|
group: "Alice Group 1",
|
||||||
totalItems: "10",
|
totalItems: "0",
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
email: "rbrown@email.com",
|
email: "rbrown@email.com",
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import { Injectable } from "@angular/core";
|
|||||||
import { CollectionAccessSelectionView } from "@bitwarden/admin-console/common";
|
import { CollectionAccessSelectionView } from "@bitwarden/admin-console/common";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
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 {
|
import {
|
||||||
getPermissionList,
|
getPermissionList,
|
||||||
convertToPermission,
|
convertToPermission,
|
||||||
} from "@bitwarden/web-vault/app/admin-console/organizations/shared/components/access-selector";
|
} 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 { MemberAccessExportItem } from "../view/member-access-export.view";
|
||||||
import { MemberAccessReportView } from "../view/member-access-report.view";
|
import { MemberAccessReportView } from "../view/member-access-report.view";
|
||||||
|
|
||||||
@@ -34,15 +34,44 @@ export class MemberAccessReportService {
|
|||||||
organizationId: OrganizationId,
|
organizationId: OrganizationId,
|
||||||
): Promise<MemberAccessReportView[]> {
|
): Promise<MemberAccessReportView[]> {
|
||||||
const memberAccessData = await this.reportApiService.getMemberAccessData(organizationId);
|
const memberAccessData = await this.reportApiService.getMemberAccessData(organizationId);
|
||||||
const memberAccessReportViewCollection = memberAccessData.map((userData) => ({
|
|
||||||
name: userData.userName,
|
// group member access data by userGuid
|
||||||
email: userData.email,
|
const userMap = new Map<Guid, MemberAccessResponse[]>();
|
||||||
collectionsCount: userData.collectionsCount,
|
memberAccessData.forEach((userData) => {
|
||||||
groupsCount: userData.groupsCount,
|
const userGuid = userData.userGuid;
|
||||||
itemsCount: userData.totalItemCount,
|
if (!userMap.has(userGuid)) {
|
||||||
userGuid: userData.userGuid,
|
userMap.set(userGuid, []);
|
||||||
usesKeyConnector: userData.usesKeyConnector,
|
}
|
||||||
}));
|
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;
|
return memberAccessReportViewCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,13 +79,8 @@ export class MemberAccessReportService {
|
|||||||
organizationId: OrganizationId,
|
organizationId: OrganizationId,
|
||||||
): Promise<MemberAccessExportItem[]> {
|
): Promise<MemberAccessExportItem[]> {
|
||||||
const memberAccessReports = await this.reportApiService.getMemberAccessData(organizationId);
|
const memberAccessReports = await this.reportApiService.getMemberAccessData(organizationId);
|
||||||
const collectionNames = memberAccessReports.flatMap((item) =>
|
const collectionNames = memberAccessReports.map((item) => item.collectionName.encryptedString);
|
||||||
item.accessDetails.map((dtl) => {
|
|
||||||
if (dtl.collectionName) {
|
|
||||||
return dtl.collectionName.encryptedString;
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
const collectionNameMap = new Map(collectionNames.map((col) => [col, ""]));
|
const collectionNameMap = new Map(collectionNames.map((col) => [col, ""]));
|
||||||
for await (const key of collectionNameMap.keys()) {
|
for await (const key of collectionNameMap.keys()) {
|
||||||
const decrypted = new EncString(key);
|
const decrypted = new EncString(key);
|
||||||
@@ -64,29 +88,8 @@ export class MemberAccessReportService {
|
|||||||
collectionNameMap.set(key, decrypted.decryptedValue);
|
collectionNameMap.set(key, decrypted.decryptedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
const exportItems = memberAccessReports.flatMap((report) => {
|
const exportItems = memberAccessReports.map((report) => {
|
||||||
// to include users without access details
|
const collectionName = collectionNameMap.get(report.collectionName.encryptedString);
|
||||||
// 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 {
|
return {
|
||||||
email: report.email,
|
email: report.email,
|
||||||
name: report.userName,
|
name: report.userName,
|
||||||
@@ -96,24 +99,24 @@ export class MemberAccessReportService {
|
|||||||
accountRecovery: report.accountRecoveryEnabled
|
accountRecovery: report.accountRecoveryEnabled
|
||||||
? this.i18nService.t("memberAccessReportAuthenticationEnabledTrue")
|
? this.i18nService.t("memberAccessReportAuthenticationEnabledTrue")
|
||||||
: this.i18nService.t("memberAccessReportAuthenticationEnabledFalse"),
|
: this.i18nService.t("memberAccessReportAuthenticationEnabledFalse"),
|
||||||
group: detail.groupName
|
group: report.groupName
|
||||||
? detail.groupName
|
? report.groupName
|
||||||
: this.i18nService.t("memberAccessReportNoGroup"),
|
: this.i18nService.t("memberAccessReportNoGroup"),
|
||||||
collection: collectionName
|
collection: collectionName
|
||||||
? collectionName
|
? collectionName
|
||||||
: this.i18nService.t("memberAccessReportNoCollection"),
|
: this.i18nService.t("memberAccessReportNoCollection"),
|
||||||
collectionPermission: detail.collectionId
|
collectionPermission: report.collectionId
|
||||||
? this.getPermissionText(detail)
|
? this.getPermissionText(report)
|
||||||
: this.i18nService.t("memberAccessReportNoCollectionPermission"),
|
: this.i18nService.t("memberAccessReportNoCollectionPermission"),
|
||||||
totalItems: detail.itemCount.toString(),
|
totalItems: report.cipherIds
|
||||||
|
.filter((_) => _ != "00000000-0000-0000-0000-000000000000")
|
||||||
|
.length.toString(),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
return userDetails;
|
|
||||||
});
|
|
||||||
return exportItems.flat();
|
return exportItems.flat();
|
||||||
}
|
}
|
||||||
|
|
||||||
private getPermissionText(accessDetails: MemberAccessDetails): string {
|
private getPermissionText(accessDetails: MemberAccessResponse): string {
|
||||||
const permissionList = getPermissionList();
|
const permissionList = getPermissionList();
|
||||||
const collectionSelectionView = new CollectionAccessSelectionView({
|
const collectionSelectionView = new CollectionAccessSelectionView({
|
||||||
id: accessDetails.groupId ?? accessDetails.collectionId,
|
id: accessDetails.groupId ?? accessDetails.collectionId,
|
||||||
@@ -125,4 +128,9 @@ export class MemberAccessReportService {
|
|||||||
permissionList.find((p) => p.perm === convertToPermission(collectionSelectionView))?.labelId,
|
permissionList.find((p) => p.perm === convertToPermission(collectionSelectionView))?.labelId,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getDistinctCount<T>(items: T[]): number {
|
||||||
|
const uniqueItems = new Set(items);
|
||||||
|
return uniqueItems.size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user