• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mozilla / blurts-server / b86637bb-ffe8-4e59-ade8-c8caf0aa8efc

pending completion
b86637bb-ffe8-4e59-ade8-c8caf0aa8efc

push

circleci

GitHub
Merge pull request #2757 from mozilla/MNTOR-977

282 of 1160 branches covered (24.31%)

Branch coverage included in aggregate %.

75 of 75 new or added lines in 2 files covered. (100.0%)

959 of 3091 relevant lines covered (31.03%)

5.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/utils/breaches.js
1
import { getUserEmails } from '../db/tables/email_addresses.js'
2
import { getBreachesForEmail, filterBreaches } from './hibp.js'
3
import { getSha1 } from './fxa.js'
4
import { filterBreachDataTypes } from './breach-resolution.js'
5

6
/**
7
 * TODO: deprecate
8
 * Get all emails and breaches for a user via app.locals
9
 * This function will be replaced after 'breaches" table is created
10
 * and all records can be retrieved from the one table
11
 * @param {*} user
12
 * @param {*} allBreaches
13
 * @returns
14
 */
15
async function getAllEmailsAndBreaches (user, allBreaches) {
16
  const monitoredEmails = await getUserEmails(user.id)
×
17
  const verifiedEmails = []
×
18
  const unverifiedEmails = []
×
19
  verifiedEmails.push(await bundleVerifiedEmails({ user, email: user.primary_email, recordId: user.id, recordVerified: user.primary_verified, allBreaches }))
×
20
  for (const email of monitoredEmails) {
×
21
    if (email.verified) {
×
22
      verifiedEmails.push(await bundleVerifiedEmails({ user, email: email.email, recordId: email.id, recordVerified: email.verified, allBreaches }))
×
23
    } else {
24
      unverifiedEmails.push(email)
×
25
    }
26
  }
27

28
  // get new breaches since last shown
29
  for (const emailEntry of verifiedEmails) {
×
30
    const newBreachesForEmail = emailEntry.breaches.filter(breach => breach.AddedDate >= user.breaches_last_shown)
×
31

32
    for (const newBreachForEmail of newBreachesForEmail) {
×
33
      newBreachForEmail.NewBreach = true // add "NewBreach" property to the new breach.
×
34
      emailEntry.hasNewBreaches = newBreachesForEmail.length // add the number of new breaches to the email
×
35
    }
36
  }
37

38
  return { verifiedEmails, unverifiedEmails }
×
39
}
40

41
function addRecencyIndex (foundBreaches) {
42
  const annotatedBreaches = []
×
43
  // slice() the array to make a copy so before reversing so we don't
44
  // reverse foundBreaches in-place
45
  const oldestToNewestFoundBreaches = foundBreaches.slice().reverse()
×
46
  oldestToNewestFoundBreaches.forEach((annotatingBreach, index) => {
×
47
    const foundBreach = foundBreaches.find(foundBreach => foundBreach.Name === annotatingBreach.Name)
×
48
    annotatedBreaches.push(Object.assign({ recencyIndex: index }, foundBreach))
×
49
  })
50
  return annotatedBreaches.reverse()
×
51
}
52

53
async function bundleVerifiedEmails (options) {
54
  const { user, email, recordId, recordVerified, allBreaches } = options
×
55
  const lowerCaseEmailSha = getSha1(email.toLowerCase())
×
56

57
  // find all breaches relevant to the current email
58
  const foundBreaches = await getBreachesForEmail(lowerCaseEmailSha, allBreaches, true, false)
×
59

60
  // adding index to breaches based on recency
61
  const foundBreachesWithRecency = addRecencyIndex(foundBreaches)
×
62

63
  // get v1 "breaches_resolved" object
64
  const resolvedBreachesV1 = user.breaches_resolved
×
65
    ? user.breaches_resolved[email] ? user.breaches_resolved[email] : []
×
66
    : []
67

68
  // get v2 "breach_resolution" object
69
  const breachResolutionV2 = user.breach_resolution
×
70
    ? user.breach_resolution[email] ? user.breach_resolution[email] : {}
×
71
    : []
72

73
  for (const breach of foundBreachesWithRecency) {
×
74
    // if either v1 or v2 is marked as resolved, breach is resolved
75
    breach.IsResolved = !!resolvedBreachesV1.includes(breach.recencyIndex) || !!breachResolutionV2[breach.recencyIndex]?.isResolved
×
76
    breach.ResolutionsChecked = breachResolutionV2[breach.recencyIndex]?.resolutionsChecked || []
×
77

78
    // filter breach types based on the 13 types we care about
79
    breach.DataClasses = filterBreachDataTypes(breach.DataClasses)
×
80
  }
81

82
  // filter out irrelevant breaches based on HIBP
83
  const filteredAnnotatedFoundBreaches = filterBreaches(foundBreachesWithRecency)
×
84

85
  const emailEntry = {
×
86
    email,
87
    breaches: filteredAnnotatedFoundBreaches,
88
    primary: email === user.primary_email,
89
    id: recordId,
90
    verified: recordVerified
91
  }
92

93
  return emailEntry
×
94
}
95

96
export { getAllEmailsAndBreaches }
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc