[PM-4964] migrate exposed passwords report components (#9952)

* WIP - migrate exposed passwords report components

* lint fix

* migrate components in reports

* migrate breach and unsecured websites reports

* undo change routing

* revert changes to reports

* revert changes

* fix icon and padding in exposed passwords report

* fix icon and padding in exposed passwords report

* fix exposed passwords report cipher state

* [PM-4965] Migrate inactive two factor report (#10043)

* migrate inactive two factor report

* fix icon and padding in inactive two factor report

* [PM-4967] Migrate reused passwords report components (#10044)

* migrate components in reused passwords report

* fix icon and padding in reused passwords report

* [PM-4969] Migrate weak passwords report components (#10048)

* migrate weak passwords report component

* migrate weak passwords report component

* Revert "migrate weak passwords report component"

This reverts commit 0e453aafc1.

* Revert "migrate weak passwords report component"

This reverts commit e8e9b01997.

* Revert "Revert "migrate weak passwords report component""

This reverts commit 8cd2421cb0.

* fix padding and icon size in weak passwords report

---------

Co-authored-by: jordan-bite <jordan@bite-interactive.com>
This commit is contained in:
Jordan Aasen 2024-07-15 03:26:11 -07:00 committed by GitHub
parent 739cd8d25b
commit fb311bfb4b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 139 additions and 141 deletions

View File

@ -9,6 +9,7 @@ import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.servi
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import { TableDataSource } from "@bitwarden/components";
import { PasswordRepromptService } from "@bitwarden/vault";
import { AddEditComponent } from "../../../vault/individual-vault/add-edit.component";
@ -24,6 +25,7 @@ export class CipherReportComponent implements OnDestroy {
hasLoaded = false;
ciphers: CipherView[] = [];
allCiphers: CipherView[] = [];
dataSource = new TableDataSource<CipherView>();
organization: Organization;
organizations: Organization[];
organizations$: Observable<Organization[]>;
@ -104,6 +106,7 @@ export class CipherReportComponent implements OnDestroy {
} else {
this.ciphers = this.ciphers.filter((c: any) => c.orgFilterStatus === status);
}
this.dataSource.data = this.ciphers;
}
async load() {
@ -193,6 +196,8 @@ export class CipherReportComponent implements OnDestroy {
return ciph;
});
this.dataSource.data = this.ciphers;
if (this.filterStatus.length > 2) {
this.showFilterToggle = true;
this.vaultMsg = "vaults";

View File

@ -6,13 +6,13 @@
{{ "checkExposedPasswords" | i18n }}
</button>
<div class="mt-4" *ngIf="hasLoaded">
<app-callout type="success" title="{{ 'goodNews' | i18n }}" *ngIf="!ciphers.length">
<bit-callout type="success" title="{{ 'goodNews' | i18n }}" *ngIf="!ciphers.length">
{{ "noExposedPasswords" | i18n }}
</app-callout>
</bit-callout>
<ng-container *ngIf="ciphers.length">
<app-callout type="danger" title="{{ 'exposedPasswordsFound' | i18n }}" [useAlertRole]="true">
<bit-callout type="danger" title="{{ 'exposedPasswordsFound' | i18n }}" [useAlertRole]="true">
{{ "exposedPasswordsFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
</app-callout>
</bit-callout>
<bit-toggle-group
*ngIf="showFilterToggle && !isAdminConsoleActive"
[selected]="filterOrgStatus$ | async"
@ -26,36 +26,33 @@
</bit-toggle>
</ng-container>
</bit-toggle-group>
<table class="table table-hover table-list table-ciphers">
<thead
class="tw-border-0 tw-border-b-2 tw-border-solid tw-border-secondary-300 tw-font-bold tw-text-muted"
*ngIf="!isAdminConsoleActive"
>
<bit-table [dataSource]="dataSource" class="table">
<ng-container header *ngIf="!isAdminConsoleActive">
<tr>
<th></th>
<th>{{ "name" | i18n }}</th>
<th>{{ "owner" | i18n }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let c of ciphers">
</ng-container>
<ng-template body let-rows$>
<tr bitRow *ngFor="let r of rows$ | async">
<td class="table-list-icon">
<app-vault-icon [cipher]="c"></app-vault-icon>
<app-vault-icon [cipher]="r"></app-vault-icon>
</td>
<td class="reduced-lh wrap">
<ng-container *ngIf="!organization || canManageCipher(c); else cantManage">
<td>
<ng-container *ngIf="!organization || canManageCipher(r); else cantManage">
<a
href="#"
appStopClick
(click)="selectCipher(c)"
(click)="selectCipher(r)"
title="{{ 'editItem' | i18n }}"
>{{ c.name }}</a
>{{ r.name }}</a
>
</ng-container>
<ng-template #cantManage>
<span>{{ c.name }}</span>
<span>{{ r.name }}</span>
</ng-template>
<ng-container *ngIf="!organization && c.organizationId">
<ng-container *ngIf="!organization && r.organizationId">
<i
class="bwi bwi-collection"
appStopProp
@ -64,7 +61,7 @@
></i>
<span class="sr-only">{{ "shared" | i18n }}</span>
</ng-container>
<ng-container *ngIf="c.hasAttachments">
<ng-container *ngIf="r.hasAttachments">
<i
class="bwi bwi-paperclip"
appStopProp
@ -74,26 +71,26 @@
<span class="sr-only">{{ "attachments" | i18n }}</span>
</ng-container>
<br />
<small>{{ c.subTitle }}</small>
<small>{{ r.subTitle }}</small>
</td>
<td>
<app-org-badge
*ngIf="!organization"
[disabled]="disabled"
[organizationId]="c.organizationId"
[organizationName]="c.organizationId | orgNameFromId: (organizations$ | async)"
[organizationId]="r.organizationId"
[organizationName]="r.organizationId | orgNameFromId: (organizations$ | async)"
appStopProp
>
</app-org-badge>
</td>
<td class="text-right">
<span bitBadge variant="warning">
{{ "exposedXTimes" | i18n: (exposedPasswordMap.get(c.id) | number) }}
{{ "exposedXTimes" | i18n: (exposedPasswordMap.get(r.id) | number) }}
</span>
</td>
</tr>
</tbody>
</table>
</ng-template>
</bit-table>
</ng-container>
</div>
<ng-template #cipherAddEdit></ng-template>

View File

@ -11,7 +11,6 @@ import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import { PasswordRepromptService } from "@bitwarden/vault";
import { CipherReportComponent } from "./cipher-report.component";
@Component({
selector: "app-exposed-passwords-report",
templateUrl: "exposed-passwords-report.component.html",

View File

@ -11,13 +11,13 @@
<span class="sr-only">{{ "loading" | i18n }}</span>
</div>
<div class="mt-4" *ngIf="hasLoaded">
<app-callout type="success" title="{{ 'goodNews' | i18n }}" *ngIf="!ciphers.length">
<bit-callout type="success" title="{{ 'goodNews' | i18n }}" *ngIf="!ciphers.length">
{{ "noInactive2fa" | i18n }}
</app-callout>
</bit-callout>
<ng-container *ngIf="ciphers.length">
<app-callout type="danger" title="{{ 'inactive2faFound' | i18n }}">
<bit-callout type="danger" title="{{ 'inactive2faFound' | i18n }}">
{{ "inactive2faFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
</app-callout>
</bit-callout>
<bit-toggle-group
*ngIf="showFilterToggle && !isAdminConsoleActive"
[selected]="filterOrgStatus$ | async"
@ -31,71 +31,74 @@
</bit-toggle>
</ng-container>
</bit-toggle-group>
<table class="table table-hover table-list table-ciphers">
<thead
class="tw-border-0 tw-border-b-2 tw-border-solid tw-border-secondary-300 tw-font-bold tw-text-muted"
*ngIf="!isAdminConsoleActive"
>
<bit-table [dataSource]="dataSource" class="table">
<ng-container header *ngIf="!isAdminConsoleActive">
<tr>
<th></th>
<th>{{ "name" | i18n }}</th>
<th>{{ "owner" | i18n }}</th>
</tr>
</thead>
</ng-container>
<tbody>
<tr *ngFor="let c of ciphers">
<td class="table-list-icon">
<app-vault-icon [cipher]="c"></app-vault-icon>
</td>
<td class="reduced-lh wrap">
<a href="#" appStopClick (click)="selectCipher(c)" title="{{ 'editItem' | i18n }}">{{
c.name
}}</a>
<ng-container *ngIf="!organization && c.organizationId">
<i
class="bwi bwi-collection"
<ng-template body let-rows$>
<tr bitRow *ngFor="let r of rows$ | async">
<td class="table-list-icon">
<app-vault-icon [cipher]="r"></app-vault-icon>
</td>
<td class="reduced-lh wrap">
<a
href="#"
appStopClick
(click)="selectCipher(r)"
title="{{ 'editItem' | i18n }}"
>{{ r.name }}</a
>
<ng-container *ngIf="!organization && r.organizationId">
<i
class="bwi bwi-collection"
appStopProp
title="{{ 'shared' | i18n }}"
aria-hidden="true"
></i>
<span class="sr-only">{{ "shared" | i18n }}</span>
</ng-container>
<ng-container *ngIf="r.hasAttachments">
<i
class="bwi bwi-paperclip"
appStopProp
title="{{ 'attachments' | i18n }}"
aria-hidden="true"
></i>
<span class="sr-only">{{ "attachments" | i18n }}</span>
</ng-container>
<br />
<small>{{ r.subTitle }}</small>
</td>
<td>
<app-org-badge
*ngIf="!organization"
[disabled]="disabled"
[organizationId]="r.organizationId"
[organizationName]="r.organizationId | orgNameFromId: (organizations$ | async)"
appStopProp
title="{{ 'shared' | i18n }}"
aria-hidden="true"
></i>
<span class="sr-only">{{ "shared" | i18n }}</span>
</ng-container>
<ng-container *ngIf="c.hasAttachments">
<i
class="bwi bwi-paperclip"
appStopProp
title="{{ 'attachments' | i18n }}"
aria-hidden="true"
></i>
<span class="sr-only">{{ "attachments" | i18n }}</span>
</ng-container>
<br />
<small>{{ c.subTitle }}</small>
</td>
<td>
<app-org-badge
*ngIf="!organization"
[disabled]="disabled"
[organizationId]="c.organizationId"
[organizationName]="c.organizationId | orgNameFromId: (organizations$ | async)"
appStopProp
>
</app-org-badge>
</td>
<td class="text-right">
<a
bitBadge
href="{{ cipherDocs.get(c.id) }}"
target="_blank"
rel="noreferrer"
*ngIf="cipherDocs.has(c.id)"
>
{{ "instructions" | i18n }}</a
>
</td>
</tr>
</tbody>
</table>
>
</app-org-badge>
</td>
<td class="text-right">
<a
bitBadge
href="{{ cipherDocs.get(r.id) }}"
target="_blank"
rel="noreferrer"
*ngIf="cipherDocs.has(r.id)"
>
{{ "instructions" | i18n }}</a
>
</td>
</tr>
</ng-template>
</tbody></bit-table
>
</ng-container>
</div>
<ng-template #cipherAddEdit></ng-template>

View File

@ -11,13 +11,13 @@
<span class="sr-only">{{ "loading" | i18n }}</span>
</div>
<div class="mt-4" *ngIf="hasLoaded">
<app-callout type="success" title="{{ 'goodNews' | i18n }}" *ngIf="!ciphers.length">
<bit-callout type="success" title="{{ 'goodNews' | i18n }}" *ngIf="!ciphers.length">
{{ "noReusedPasswords" | i18n }}
</app-callout>
</bit-callout>
<ng-container *ngIf="ciphers.length">
<app-callout type="danger" title="{{ 'reusedPasswordsFound' | i18n }}">
<bit-callout type="danger" title="{{ 'reusedPasswordsFound' | i18n }}">
{{ "reusedPasswordsFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
</app-callout>
</bit-callout>
<bit-toggle-group
*ngIf="showFilterToggle && !isAdminConsoleActive"
@ -33,36 +33,33 @@
</ng-container>
</bit-toggle-group>
<table class="table table-hover table-list table-ciphers">
<thead
class="tw-border-0 tw-border-b-2 tw-border-solid tw-border-secondary-300 tw-font-bold tw-text-muted"
*ngIf="!isAdminConsoleActive"
>
<bit-table [dataSource]="dataSource" class="table">
<ng-container header *ngIf="!isAdminConsoleActive">
<tr>
<th></th>
<th>{{ "name" | i18n }}</th>
<th>{{ "owner" | i18n }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let c of ciphers">
</ng-container>
<ng-template body let-rows$>
<tr bitRow *ngFor="let r of rows$ | async">
<td class="table-list-icon">
<app-vault-icon [cipher]="c"></app-vault-icon>
<app-vault-icon [cipher]="r"></app-vault-icon>
</td>
<td class="reduced-lh wrap">
<ng-container *ngIf="!organization || canManageCipher(c); else cantManage">
<td>
<ng-container *ngIf="!organization || canManageCipher(r); else cantManage">
<a
href="#"
appStopClick
(click)="selectCipher(c)"
(click)="selectCipher(r)"
title="{{ 'editItem' | i18n }}"
>{{ c.name }}</a
>{{ r.name }}</a
>
</ng-container>
<ng-template #cantManage>
<span>{{ c.name }}</span>
<span>{{ r.name }}</span>
</ng-template>
<ng-container *ngIf="!organization && c.organizationId">
<ng-container *ngIf="!organization && r.organizationId">
<i
class="bwi bwi-collection"
appStopProp
@ -71,7 +68,7 @@
></i>
<span class="sr-only">{{ "shared" | i18n }}</span>
</ng-container>
<ng-container *ngIf="c.hasAttachments">
<ng-container *ngIf="r.hasAttachments">
<i
class="bwi bwi-paperclip"
appStopProp
@ -81,26 +78,26 @@
<span class="sr-only">{{ "attachments" | i18n }}</span>
</ng-container>
<br />
<small>{{ c.subTitle }}</small>
<small>{{ r.subTitle }}</small>
</td>
<td>
<app-org-badge
*ngIf="!organization"
[disabled]="disabled"
[organizationId]="c.organizationId"
[organizationName]="c.organizationId | orgNameFromId: (organizations$ | async)"
[organizationId]="r.organizationId"
[organizationName]="r.organizationId | orgNameFromId: (organizations$ | async)"
appStopProp
>
</app-org-badge>
</td>
<td class="text-right">
<span bitBadge variant="warning">
{{ "reusedXTimes" | i18n: passwordUseMap.get(c.login.password) }}
{{ "reusedXTimes" | i18n: passwordUseMap.get(r.login.password) }}
</span>
</td>
</tr>
</tbody>
</table>
</ng-template>
</bit-table>
</ng-container>
</div>
<ng-template #cipherAddEdit></ng-template>

View File

@ -11,13 +11,13 @@
<span class="sr-only">{{ "loading" | i18n }}</span>
</div>
<div class="mt-4" *ngIf="hasLoaded">
<app-callout type="success" title="{{ 'goodNews' | i18n }}" *ngIf="!ciphers.length">
<bit-callout type="success" title="{{ 'goodNews' | i18n }}" *ngIf="!ciphers.length">
{{ "noWeakPasswords" | i18n }}
</app-callout>
</bit-callout>
<ng-container *ngIf="ciphers.length">
<app-callout type="danger" title="{{ 'weakPasswordsFound' | i18n }}">
<bit-callout type="danger" title="{{ 'weakPasswordsFound' | i18n }}">
{{ "weakPasswordsFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
</app-callout>
</bit-callout>
<bit-toggle-group
*ngIf="showFilterToggle && !isAdminConsoleActive"
[selected]="filterOrgStatus$ | async"
@ -31,36 +31,33 @@
</bit-toggle>
</ng-container>
</bit-toggle-group>
<table class="table table-hover table-list table-ciphers">
<thead
class="tw-border-0 tw-border-b-2 tw-border-solid tw-border-secondary-300 tw-font-bold tw-text-muted"
*ngIf="!isAdminConsoleActive"
>
<bit-table [dataSource]="dataSource" class="table">
<ng-container header *ngIf="!isAdminConsoleActive">
<tr>
<th></th>
<th>{{ "name" | i18n }}</th>
<th>{{ "owner" | i18n }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let c of ciphers">
</ng-container>
<ng-template body let-rows$>
<tr bitRow *ngFor="let r of rows$ | async">
<td class="table-list-icon">
<app-vault-icon [cipher]="c"></app-vault-icon>
<app-vault-icon [cipher]="r"></app-vault-icon>
</td>
<td class="reduced-lh wrap">
<ng-container *ngIf="!organization || canManageCipher(c); else cantManage">
<ng-container *ngIf="!organization || canManageCipher(r); else cantManage">
<a
href="#"
appStopClick
(click)="selectCipher(c)"
(click)="selectCipher(r)"
title="{{ 'editItem' | i18n }}"
>{{ c.name }}</a
>{{ r.name }}</a
>
</ng-container>
<ng-template #cantManage>
<span>{{ c.name }}</span>
<span>{{ r.name }}</span>
</ng-template>
<ng-container *ngIf="!organization && c.organizationId">
<ng-container *ngIf="!organization && r.organizationId">
<i
class="bwi bwi-collection"
appStopProp
@ -69,7 +66,7 @@
></i>
<span class="sr-only">{{ "shared" | i18n }}</span>
</ng-container>
<ng-container *ngIf="c.hasAttachments">
<ng-container *ngIf="r.hasAttachments">
<i
class="bwi bwi-paperclip"
appStopProp
@ -79,26 +76,26 @@
<span class="sr-only">{{ "attachments" | i18n }}</span>
</ng-container>
<br />
<small>{{ c.subTitle }}</small>
<small>{{ r.subTitle }}</small>
</td>
<td>
<app-org-badge
*ngIf="!organization"
[disabled]="disabled"
[organizationId]="c.organizationId"
[organizationName]="c.organizationId | orgNameFromId: (organizations$ | async)"
[organizationId]="r.organizationId"
[organizationName]="r.organizationId | orgNameFromId: (organizations$ | async)"
appStopProp
>
</app-org-badge>
</td>
<td class="text-right">
<span bitBadge [variant]="passwordStrengthMap.get(c.id)[1]">
{{ passwordStrengthMap.get(c.id)[0] | i18n }}
<span bitBadge [variant]="passwordStrengthMap.get(r.id)[1]">
{{ passwordStrengthMap.get(r.id)[0] | i18n }}
</span>
</td>
</tr>
</tbody>
</table>
</ng-template>
</bit-table>
</ng-container>
</div>
<ng-template #cipherAddEdit></ng-template>