in src/utils/hibp.ts [342:417]
async function getBreachesForEmail(
sha1: string,
allBreaches: HibpLikeDbBreach[],
includeSensitive = false,
filterBreaches = true,
): Promise<HibpLikeDbBreach[]> {
let foundBreaches: HibpLikeDbBreach[] = [];
const sha1Prefix = sha1.slice(0, 6).toUpperCase();
const path = `/range/search/${sha1Prefix}`;
const qaToggles = await getQaToggleRow(sha1);
let showCustomBreaches = false;
let showRealBreaches = true;
if (qaToggles) {
showCustomBreaches = qaToggles.show_custom_breaches;
showRealBreaches = qaToggles.show_real_breaches;
}
const qaBreaches = !showCustomBreaches
? []
: await getAllQaCustomBreaches(sha1Prefix);
if (!showRealBreaches) return qaBreaches as HibpLikeDbBreach[];
const response = (await kAnonReq(path)) as
| BreachedAccountResponse
| undefined;
if (!response || (response && response.length < 1)) {
logger.error("failed_kAnonReq_call: no response or empty response");
return [...qaBreaches] as HibpLikeDbBreach[];
}
if (isUsingMockHIBPEndpoint()) {
const mockDataBreaches = response[0];
return [
...(qaBreaches as HibpLikeDbBreach[]),
...allBreaches
.filter((breach) => mockDataBreaches.websites.includes(breach.Name))
.sort((a, b) => {
// @ts-ignore TODO: Turn dates into a number
return new Date(b.AddedDate) - new Date(a.AddedDate);
}),
];
}
// Parse response body, format:
// [
// {"hashSuffix":<suffix>,"websites":[<breach1Name>,...]},
// {"hashSuffix":<suffix>,"websites":[<breach1Name>,...]},
// ]
for (const breachedAccount of response) {
if (sha1.toUpperCase() === sha1Prefix + breachedAccount.hashSuffix) {
foundBreaches = allBreaches.filter((breach) =>
breachedAccount.websites.includes(breach.Name),
);
if (filterBreaches) {
foundBreaches = getFilteredBreaches(foundBreaches);
}
// NOTE: DO NOT CHANGE THIS SORT LOGIC
// We store breach resolutions by recency indices,
// so that our DB does not contain any part of any user's list of accounts
foundBreaches.sort((a, b) => {
// @ts-ignore TODO: Turn dates into a number
return new Date(b.AddedDate) - new Date(a.AddedDate);
});
break;
}
}
if (includeSensitive) {
return [...foundBreaches, ...(qaBreaches as HibpLikeDbBreach[])];
}
return [
...(qaBreaches as HibpLikeDbBreach[]),
...foundBreaches.filter((breach) => !breach.IsSensitive),
];
}