diff --git a/src/abstractions/audit.service.ts b/src/abstractions/audit.service.ts index 0ea1e1fe89..e324d08c4b 100644 --- a/src/abstractions/audit.service.ts +++ b/src/abstractions/audit.service.ts @@ -1,3 +1,6 @@ +import { BreachAccountResponse } from '../models/response/breachAccountResponse'; + export abstract class AuditService { passwordLeaked: (password: string) => Promise; + breachedAccounts: (email: string) => Promise; } diff --git a/src/models/response/breachAccountResponse.ts b/src/models/response/breachAccountResponse.ts new file mode 100644 index 0000000000..cc5f748232 --- /dev/null +++ b/src/models/response/breachAccountResponse.ts @@ -0,0 +1,29 @@ +export class BreachAccountResponse { + addedDate: Date; + breachDate: Date; + dataClasses: string[]; + description: string; + domain: string; + isActive: boolean; + isVerified: boolean; + logoType: string; + modifiedDate: Date; + name: string; + pwnCount: number; + title: string; + + constructor(response: any) { + this.addedDate = response.AddedDate; + this.breachDate = response.BreachDate; + this.dataClasses = response.DataClasses; + this.description = response.Description; + this.domain = response.Domain; + this.isActive = response.IsActive; + this.isVerified = response.IsVerified; + this.logoType = response.LogoType; + this.modifiedDate = response.ModifiedDate; + this.name = response.Name; + this.pwnCount = response.PwnCount; + this.title = response.Title; + } +} diff --git a/src/services/audit.service.ts b/src/services/audit.service.ts index d18ccbe219..6226386016 100644 --- a/src/services/audit.service.ts +++ b/src/services/audit.service.ts @@ -1,8 +1,12 @@ import { AuditService as AuditServiceAbstraction } from '../abstractions/audit.service'; import { CryptoFunctionService } from '../abstractions/cryptoFunction.service'; + import { Utils } from '../misc/utils'; +import { BreachAccountResponse } from '../models/response/breachAccountResponse'; + const PwnedPasswordsApi = 'https://api.pwnedpasswords.com/range/'; +const HibpBreachApi = 'https://haveibeenpwned.com/api/v2/breachedaccount/'; export class AuditService implements AuditServiceAbstraction { constructor(private cryptoFunctionService: CryptoFunctionService) { } @@ -21,4 +25,15 @@ export class AuditService implements AuditServiceAbstraction { return match != null ? parseInt(match.split(':')[1], 10) : 0; } + + async breachedAccounts(email: string): Promise { + const response = await fetch(HibpBreachApi + email); + if (response.status === 404) { + return []; + } else if (response.status !== 200) { + throw new Error(); + } + const responseJson = await response.json(); + return responseJson.map((a) => new BreachAccountResponse(a)); + } }