1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-18 09:13:33 +00:00

WIP - migrate exposed passwords report components

This commit is contained in:
jordan-bite
2024-07-02 17:18:09 -07:00
parent a3514001c0
commit 170021491e
4 changed files with 40 additions and 34 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 { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type"; import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import { TableDataSource } from "@bitwarden/components";
import { PasswordRepromptService } from "@bitwarden/vault"; import { PasswordRepromptService } from "@bitwarden/vault";
import { AddEditComponent } from "../../../vault/individual-vault/add-edit.component"; import { AddEditComponent } from "../../../vault/individual-vault/add-edit.component";
@@ -24,6 +25,7 @@ export class CipherReportComponent implements OnDestroy {
hasLoaded = false; hasLoaded = false;
ciphers: CipherView[] = []; ciphers: CipherView[] = [];
allCiphers: CipherView[] = []; allCiphers: CipherView[] = [];
dataSource = new TableDataSource<CipherView>();
organization: Organization; organization: Organization;
organizations: Organization[]; organizations: Organization[];
organizations$: Observable<Organization[]>; organizations$: Observable<Organization[]>;
@@ -104,6 +106,7 @@ export class CipherReportComponent implements OnDestroy {
} else { } else {
this.ciphers = this.ciphers.filter((c: any) => c.orgFilterStatus === status); this.ciphers = this.ciphers.filter((c: any) => c.orgFilterStatus === status);
} }
this.dataSource.data = this.ciphers;
} }
async load() { async load() {
@@ -193,6 +196,8 @@ export class CipherReportComponent implements OnDestroy {
return ciph; return ciph;
}); });
this.dataSource.data = this.ciphers;
if (this.filterStatus.length > 2) { if (this.filterStatus.length > 2) {
this.showFilterToggle = true; this.showFilterToggle = true;
this.vaultMsg = "vaults"; this.vaultMsg = "vaults";

View File

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

View File

@@ -11,6 +11,8 @@ import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import { PasswordRepromptService } from "@bitwarden/vault"; import { PasswordRepromptService } from "@bitwarden/vault";
import { CipherReportComponent } from "./cipher-report.component"; import { CipherReportComponent } from "./cipher-report.component";
import { cipherData } from "./reports-ciphers.mock";
@Component({ @Component({
selector: "app-exposed-passwords-report", selector: "app-exposed-passwords-report",
@@ -44,7 +46,9 @@ export class ExposedPasswordsReportComponent extends CipherReportComponent imple
} }
async setCiphers() { async setCiphers() {
const allCiphers = await this.getAllCiphers(); const allCiphers = cipherData;
// const allCiphers = await this.getAllCiphers();
this.dataSource.data = allCiphers;
const exposedPasswordCiphers: CipherView[] = []; const exposedPasswordCiphers: CipherView[] = [];
const promises: Promise<void>[] = []; const promises: Promise<void>[] = [];
this.filterStatus = [0]; this.filterStatus = [0];

View File

@@ -3,7 +3,7 @@ import { RouterModule, Routes } from "@angular/router";
import { AuthGuard } from "@bitwarden/angular/auth/guards"; import { AuthGuard } from "@bitwarden/angular/auth/guards";
import { hasPremiumGuard } from "../../core/guards/has-premium.guard"; // import { hasPremiumGuard } from "../../core/guards/has-premium.guard";
import { BreachReportComponent } from "./pages/breach-report.component"; import { BreachReportComponent } from "./pages/breach-report.component";
import { ExposedPasswordsReportComponent } from "./pages/exposed-passwords-report.component"; import { ExposedPasswordsReportComponent } from "./pages/exposed-passwords-report.component";
@@ -35,31 +35,31 @@ const routes: Routes = [
path: "reused-passwords-report", path: "reused-passwords-report",
component: ReusedPasswordsReportComponent, component: ReusedPasswordsReportComponent,
data: { titleId: "reusedPasswordsReport" }, data: { titleId: "reusedPasswordsReport" },
canActivate: [hasPremiumGuard()], // canActivate: [hasPremiumGuard()],
}, },
{ {
path: "unsecured-websites-report", path: "unsecured-websites-report",
component: UnsecuredWebsitesReportComponent, component: UnsecuredWebsitesReportComponent,
data: { titleId: "unsecuredWebsitesReport" }, data: { titleId: "unsecuredWebsitesReport" },
canActivate: [hasPremiumGuard()], // canActivate: [hasPremiumGuard()],
}, },
{ {
path: "weak-passwords-report", path: "weak-passwords-report",
component: WeakPasswordsReportComponent, component: WeakPasswordsReportComponent,
data: { titleId: "weakPasswordsReport" }, data: { titleId: "weakPasswordsReport" },
canActivate: [hasPremiumGuard()], // canActivate: [hasPremiumGuard()],
}, },
{ {
path: "exposed-passwords-report", path: "exposed-passwords-report",
component: ExposedPasswordsReportComponent, component: ExposedPasswordsReportComponent,
data: { titleId: "exposedPasswordsReport" }, data: { titleId: "exposedPasswordsReport" },
canActivate: [hasPremiumGuard()], // canActivate: [hasPremiumGuard()],
}, },
{ {
path: "inactive-two-factor-report", path: "inactive-two-factor-report",
component: InactiveTwoFactorReportComponent, component: InactiveTwoFactorReportComponent,
data: { titleId: "inactive2faReport" }, data: { titleId: "inactive2faReport" },
canActivate: [hasPremiumGuard()], // canActivate: [hasPremiumGuard()],
}, },
], ],
}, },