import { Component, OnInit } from "@angular/core"; import { ModalService } from "@bitwarden/angular/services/modal.service"; import { CipherService } from "@bitwarden/common/abstractions/cipher.service"; import { MessagingService } from "@bitwarden/common/abstractions/messaging.service"; import { PasswordRepromptService } from "@bitwarden/common/abstractions/passwordReprompt.service"; import { StateService } from "@bitwarden/common/abstractions/state.service"; import { CipherType } from "@bitwarden/common/enums/cipherType"; import { CipherView } from "@bitwarden/common/models/view/cipherView"; import { CipherReportComponent } from "./cipher-report.component"; @Component({ selector: "app-reused-passwords-report", templateUrl: "reused-passwords-report.component.html", }) export class ReusedPasswordsReportComponent extends CipherReportComponent implements OnInit { passwordUseMap: Map; constructor( protected cipherService: CipherService, modalService: ModalService, messagingService: MessagingService, stateService: StateService, passwordRepromptService: PasswordRepromptService ) { super(modalService, messagingService, true, stateService, passwordRepromptService); } async ngOnInit() { if (await this.checkAccess()) { await super.load(); } } async setCiphers() { const allCiphers = await this.getAllCiphers(); const ciphersWithPasswords: CipherView[] = []; this.passwordUseMap = new Map(); allCiphers.forEach((c) => { if ( c.type !== CipherType.Login || c.login.password == null || c.login.password === "" || c.isDeleted ) { return; } ciphersWithPasswords.push(c); if (this.passwordUseMap.has(c.login.password)) { this.passwordUseMap.set(c.login.password, this.passwordUseMap.get(c.login.password) + 1); } else { this.passwordUseMap.set(c.login.password, 1); } }); const reusedPasswordCiphers = ciphersWithPasswords.filter( (c) => this.passwordUseMap.has(c.login.password) && this.passwordUseMap.get(c.login.password) > 1 ); this.ciphers = reusedPasswordCiphers; } protected getAllCiphers(): Promise { return this.cipherService.getAllDecrypted(); } protected canManageCipher(c: CipherView): boolean { // this will only ever be false from an organization view return true; } }