mirror of
https://github.com/bitwarden/browser
synced 2026-02-12 06:23:38 +00:00
[PM-15929] - add at risk member dialog (#12410)
* add at risk member dialog * fix types * rename at-risk-member-details to org-at-risk-members
This commit is contained in:
@@ -131,6 +131,24 @@
|
||||
"atRiskMembers": {
|
||||
"message": "At-risk members"
|
||||
},
|
||||
"atRiskMembersWithCount": {
|
||||
"message": "At-risk members ($COUNT$)",
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"content": "$1",
|
||||
"example": "3"
|
||||
}
|
||||
}
|
||||
},
|
||||
"atRiskMembersDescriptionWithApp": {
|
||||
"message": "These members are logging into $APPNAME$ with weak, exposed, or reused passwords.",
|
||||
"placeholders": {
|
||||
"appname": {
|
||||
"content": "$1",
|
||||
"example": "Salesforce"
|
||||
}
|
||||
}
|
||||
},
|
||||
"totalMembers": {
|
||||
"message": "Total members"
|
||||
},
|
||||
|
||||
@@ -90,3 +90,11 @@ export type MemberDetailsFlat = {
|
||||
email: string;
|
||||
cipherId: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Member email with the number of at risk passwords
|
||||
*/
|
||||
export type AtRiskMemberDetail = {
|
||||
email: string;
|
||||
atRiskPasswordCount: number;
|
||||
};
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
(change)="onCheckboxChange(r.id, $event)"
|
||||
/>
|
||||
</td>
|
||||
<td bitCell>
|
||||
<td class="tw-cursor-pointer" (click)="showAppAtRiskMembers(r.applicationName)" bitCell>
|
||||
<span>{{ r.applicationName }}</span>
|
||||
</td>
|
||||
<td bitCell>
|
||||
|
||||
@@ -19,6 +19,7 @@ import { ConfigService } from "@bitwarden/common/platform/abstractions/config/co
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import {
|
||||
DialogService,
|
||||
Icons,
|
||||
NoItemsModule,
|
||||
SearchModule,
|
||||
@@ -30,6 +31,7 @@ import { HeaderModule } from "@bitwarden/web-vault/app/layouts/header/header.mod
|
||||
import { SharedModule } from "@bitwarden/web-vault/app/shared";
|
||||
import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pipes/pipes.module";
|
||||
|
||||
import { openAppAtRiskMembersDialog } from "./app-at-risk-members-dialog.component";
|
||||
import { ApplicationsLoadingComponent } from "./risk-insights-loading.component";
|
||||
|
||||
@Component({
|
||||
@@ -100,6 +102,7 @@ export class AllApplicationsComponent implements OnInit, OnDestroy {
|
||||
protected dataService: RiskInsightsDataService,
|
||||
protected organizationService: OrganizationService,
|
||||
protected reportService: RiskInsightsReportService,
|
||||
protected dialogService: DialogService,
|
||||
) {
|
||||
this.searchControl.valueChanges
|
||||
.pipe(debounceTime(200), takeUntilDestroyed())
|
||||
@@ -136,6 +139,15 @@ export class AllApplicationsComponent implements OnInit, OnDestroy {
|
||||
return item.applicationName;
|
||||
}
|
||||
|
||||
showAppAtRiskMembers = async (applicationName: string) => {
|
||||
openAppAtRiskMembersDialog(this.dialogService, {
|
||||
members:
|
||||
this.dataSource.data.find((app) => app.applicationName === applicationName)
|
||||
?.atRiskMemberDetails ?? [],
|
||||
applicationName,
|
||||
});
|
||||
};
|
||||
|
||||
onCheckboxChange(id: number, event: Event) {
|
||||
const isChecked = (event.target as HTMLInputElement).checked;
|
||||
if (isChecked) {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<bit-dialog>
|
||||
<span bitDialogTitle>{{ applicationName }}</span>
|
||||
<ng-container bitDialogContent>
|
||||
<div class="tw-flex tw-flex-col tw-gap-2">
|
||||
<span bitDialogTitle>{{ "atRiskMembersWithCount" | i18n: members.length }} </span>
|
||||
<span class="tw-text-muted">{{
|
||||
"atRiskMembersDescriptionWithApp" | i18n: applicationName
|
||||
}}</span>
|
||||
<div class="tw-mt-1">
|
||||
<ng-container *ngFor="let member of members">
|
||||
<div>{{ member.email }}</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container bitDialogFooter>
|
||||
<button bitButton bitDialogClose buttonType="secondary" type="button">
|
||||
{{ "ok" | i18n }}
|
||||
</button>
|
||||
</ng-container>
|
||||
</bit-dialog>
|
||||
@@ -0,0 +1,35 @@
|
||||
import { DIALOG_DATA } from "@angular/cdk/dialog";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component, Inject } from "@angular/core";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { MemberDetailsFlat } from "@bitwarden/bit-common/tools/reports/risk-insights/models/password-health";
|
||||
import { ButtonModule, DialogModule, DialogService } from "@bitwarden/components";
|
||||
|
||||
type AppAtRiskMembersDialogParams = {
|
||||
members: MemberDetailsFlat[];
|
||||
applicationName: string;
|
||||
};
|
||||
|
||||
export const openAppAtRiskMembersDialog = (
|
||||
dialogService: DialogService,
|
||||
dialogConfig: AppAtRiskMembersDialogParams,
|
||||
) =>
|
||||
dialogService.open<boolean, AppAtRiskMembersDialogParams>(AppAtRiskMembersDialogComponent, {
|
||||
data: dialogConfig,
|
||||
});
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
templateUrl: "./app-at-risk-members-dialog.component.html",
|
||||
imports: [ButtonModule, CommonModule, JslibModule, DialogModule],
|
||||
})
|
||||
export class AppAtRiskMembersDialogComponent {
|
||||
protected members: MemberDetailsFlat[];
|
||||
protected applicationName: string;
|
||||
|
||||
constructor(@Inject(DIALOG_DATA) private params: AppAtRiskMembersDialogParams) {
|
||||
this.members = params.members;
|
||||
this.applicationName = params.applicationName;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user