diff --git a/jslib b/jslib
index 569ad25208d..a097ef9beab 160000
--- a/jslib
+++ b/jslib
@@ -1 +1 @@
-Subproject commit 569ad25208d63928c604fdcda8ed1899c183495a
+Subproject commit a097ef9beabe7da67c4c338e85a15bf3ad02a7f1
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index e4bf23c4f21..65eb5068a16 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -20,6 +20,7 @@ import { OptionsComponent } from './settings/options.component';
import { SettingsComponent } from './settings/settings.component';
import { TwoFactorSetupComponent } from './settings/two-factor-setup.component';
+import { BreachReportComponent } from './tools/breach-report.component';
import { ExportComponent } from './tools/export.component';
import { ImportComponent } from './tools/import.component';
import { PasswordGeneratorComponent } from './tools/password-generator.component';
@@ -67,6 +68,7 @@ const routes: Routes = [
{ path: 'import', component: ImportComponent, canActivate: [AuthGuardService] },
{ path: 'export', component: ExportComponent, canActivate: [AuthGuardService] },
{ path: 'generator', component: PasswordGeneratorComponent, canActivate: [AuthGuardService] },
+ { path: 'breach-report', component: BreachReportComponent, canActivate: [AuthGuardService] },
],
},
],
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index c5c68916fcb..8c6b69e4ca5 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -51,6 +51,7 @@ import { TwoFactorU2fComponent } from './settings/two-factor-u2f.component';
import { TwoFactorVerifyComponent } from './settings/two-factor-verify.component';
import { TwoFactorYubiKeyComponent } from './settings/two-factor-yubikey.component';
+import { BreachReportComponent } from './tools/breach-report.component';
import { ExportComponent } from './tools/export.component';
import { ImportComponent } from './tools/import.component';
import { PasswordGeneratorHistoryComponent } from './tools/password-generator-history.component';
@@ -109,6 +110,7 @@ import { SearchCiphersPipe } from 'jslib/angular/pipes/search-ciphers.pipe';
AvatarComponent,
BlurClickDirective,
BoxRowDirective,
+ BreachReportComponent,
BulkDeleteComponent,
BulkMoveComponent,
BulkShareComponent,
diff --git a/src/app/tools/breach-report.component.html b/src/app/tools/breach-report.component.html
new file mode 100644
index 00000000000..8f56e4d284a
--- /dev/null
+++ b/src/app/tools/breach-report.component.html
@@ -0,0 +1,45 @@
+
+{{'breachDesc' | i18n}}
+
+
+ {{'reportError' | i18n}}...
+
+
+ {{'breachEmailNotFound' | i18n : email}}
+
+
+ {{'breachEmailFound' | i18n : email : breachedAccounts.length}}
+
+
+ -
+
+
+
![]()
+
+
+
{{a.title}}
+
+
{{'compromisedData' | i18n}}:
+
+
+
+
+ - {{'website' | i18n}}
+ - {{a.domain}}
+ - {{'affectedUsers' | i18n}}
+ - {{a.pwnCount | number}}
+ - {{'breachOccurred' | i18n}}
+ - {{a.breachDate | date: 'mediumDate'}}
+ - {{'breachReported' | i18n}}
+ - {{a.addedDate | date: 'mediumDate'}}
+
+
+
+
+
+
+
diff --git a/src/app/tools/breach-report.component.ts b/src/app/tools/breach-report.component.ts
new file mode 100644
index 00000000000..f04bbf4e87e
--- /dev/null
+++ b/src/app/tools/breach-report.component.ts
@@ -0,0 +1,32 @@
+import {
+ Component,
+ OnInit,
+} from '@angular/core';
+
+import { AuditService } from 'jslib/abstractions/audit.service';
+import { UserService } from 'jslib/abstractions/user.service';
+import { BreachAccountResponse } from 'jslib/models/response/breachAccountResponse';
+
+@Component({
+ selector: 'app-breach-report',
+ templateUrl: 'breach-report.component.html',
+})
+export class BreachReportComponent implements OnInit {
+ loading = true;
+ error = false;
+ email: string;
+ breachedAccounts: BreachAccountResponse[] = [];
+
+ constructor(private auditService: AuditService, private userService: UserService) { }
+
+ async ngOnInit() {
+ this.loading = true;
+ try {
+ this.email = await this.userService.getEmail();
+ this.breachedAccounts = await this.auditService.breachedAccounts(this.email);
+ } catch {
+ this.error = true;
+ }
+ this.loading = false;
+ }
+}
diff --git a/src/app/tools/tools.component.html b/src/app/tools/tools.component.html
index a6de0c7abcb..b4faf2b97ba 100644
--- a/src/app/tools/tools.component.html
+++ b/src/app/tools/tools.component.html
@@ -1,20 +1,28 @@
-
diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json
index 52e423316a4..1d7a7a472b5 100644
--- a/src/locales/en/messages.json
+++ b/src/locales/en/messages.json
@@ -1132,5 +1132,61 @@
"printCode": {
"message": "Print Code",
"description": "Print 2FA recovery code"
+ },
+ "reports": {
+ "message": "Reports"
+ },
+ "dataBreachReport": {
+ "message": "Data Breach Report"
+ },
+ "breachDesc": {
+ "message": "A \"breach\" is an incident where a site's data has been illegally accessed by hackers and then released publicly. Review the types of data that were compromised (email addresses, passwords, credit cards etc.) and take appropriate action, such as changing passwords."
+ },
+ "breachEmailNotFound": {
+ "message": "Your email ($EMAIL$) was not found in any known data breaches.",
+ "placeholders": {
+ "email": {
+ "content": "$1",
+ "example": "user@example.com"
+ }
+ }
+ },
+ "goodNews": {
+ "message": "Good News",
+ "description": "ex. Good News, No Breached Accounts Found!"
+ },
+ "breachEmailFound": {
+ "message": "Your email ($EMAIL$) was found in $COUNT$ different data breaches online.",
+ "placeholders": {
+ "email": {
+ "content": "$1",
+ "example": "user@example.com"
+ },
+ "count": {
+ "content": "$2",
+ "example": "7"
+ }
+ }
+ },
+ "breachFound": {
+ "message": "Breached Accounts Found"
+ },
+ "compromisedData": {
+ "message": "Compromised data"
+ },
+ "website": {
+ "message": "Website"
+ },
+ "affectedUsers": {
+ "message": "Affected Users"
+ },
+ "breachOccurred": {
+ "message": "Breach Occurred"
+ },
+ "breachReported": {
+ "message": "Breach Reported"
+ },
+ "reportError": {
+ "message": "An error occurred trying to load the report. Try again"
}
}