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

mozilla / blurts-server / fc5fd966-32ac-4dce-a653-c3228ccbd2bc

pending completion
fc5fd966-32ac-4dce-a653-c3228ccbd2bc

Pull #2762

circleci

GitHub
Merge pull request #2751 from mozilla/MNTOR-1025
Pull Request #2762: Merge `main` into `localization`

282 of 1122 branches covered (25.13%)

Branch coverage included in aggregate %.

203 of 203 new or added lines in 19 files covered. (100.0%)

959 of 3014 relevant lines covered (31.82%)

5.13 hits per line

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

0.0
/src/utils/fxa.js
1
import ClientOAuth2 from 'client-oauth2'
2
import crypto from 'crypto'
3
import { URL } from 'url'
4

5
import AppConstants from '../app-constants.js'
6

7
// This object exists instead of inlining the env vars to make it easy
8
// to abstract fetching API endpoints from the OAuth server (instead
9
// of specifying them in the environment) in the future.
10
const FxAOAuthUtils = {
×
11
  get authorizationUri () { return AppConstants.OAUTH_AUTHORIZATION_URI },
×
12
  get tokenUri () { return AppConstants.OAUTH_TOKEN_URI },
×
13
  get profileUri () { return AppConstants.OAUTH_PROFILE_URI }
×
14
}
15

16
const FxAOAuthClient = new ClientOAuth2({
×
17
  clientId: AppConstants.OAUTH_CLIENT_ID,
18
  clientSecret: AppConstants.OAUTH_CLIENT_SECRET,
19
  accessTokenUri: FxAOAuthUtils.tokenUri,
20
  authorizationUri: FxAOAuthUtils.authorizationUri,
21
  redirectUri: AppConstants.SERVER_URL + '/oauth/confirmed',
22
  scopes: ['profile']
23
})
24

25
async function postTokenRequest (path, token) {
26
  const fxaTokenOrigin = new URL(AppConstants.OAUTH_TOKEN_URI).origin
×
27
  const tokenUrl = `${fxaTokenOrigin}${path}`
×
28
  const tokenBody = (typeof token === 'object') ? token : { token }
×
29
  const tokenOptions = {
×
30
    method: 'POST',
31
    headers: {
32
      'Content-Type': 'application/json'
33
    },
34
    body: JSON.stringify(tokenBody)
35
  }
36

37
  try {
×
38
    const response = await fetch(tokenUrl, tokenOptions)
×
39
    if (!response.ok) throw new Error(`bad response: ${response.status}`)
×
40
    return await response.json()
×
41
  } catch (e) {
42
    console.error('postTokenRequest', { stack: e.stack })
×
43
    return e
×
44
  }
45
}
46

47
async function verifyOAuthToken (token) {
48
  try {
×
49
    const response = await postTokenRequest('/v1/verify', token)
×
50
    return response
×
51
  } catch (e) {
52
    console.error('verifyOAuthToken', { stack: e.stack })
×
53
  }
54
}
55

56
async function destroyOAuthToken (token) {
57
  try {
×
58
    const response = await postTokenRequest('/v1/destroy', token)
×
59
    return response
×
60
  } catch (e) {
61
    console.error('destroyOAuthToken', { stack: e.stack })
×
62
  }
63
}
64

65
async function revokeOAuthTokens (subscriber) {
66
  await destroyOAuthToken({ token: subscriber.fxa_access_token })
×
67
  await destroyOAuthToken({ refresh_token: subscriber.fxa_refresh_token })
×
68
}
69

70
async function getProfileData (accessToken) {
71
  try {
×
72
    const response = await fetch(FxAOAuthUtils.profileUri, {
×
73
      headers: { Authorization: `Bearer ${accessToken}` }
74
    })
75
    if (!response.ok) throw new Error(`bad response: ${response.status}`)
×
76
    return await response.text()
×
77
  } catch (e) {
78
    console.warn('getProfileData', { stack: e.stack })
×
79
    return e
×
80
  }
81
}
82

83
async function sendMetricsFlowPing (path) {
84
  const fxaMetricsFlowUrl = new URL(path, AppConstants.FXA_SETTINGS_URL)
×
85
  try {
×
86
    const response = await fetch(fxaMetricsFlowUrl, {
×
87
      headers: { Origin: AppConstants.SERVER_URL }
88
    })
89
    if (!response.ok) throw new Error(`bad response: ${response.status}`)
×
90
    console.info('pinged FXA metrics flow.')
×
91
    return response
×
92
  } catch (e) {
93
    console.error('sendMetricsFlowPing', { stack: e.stack })
×
94
    return false
×
95
  }
96
}
97

98
function getSha1 (email) {
99
  return crypto.createHash('sha1').update(email).digest('hex')
×
100
}
101

102
export {
103
  FxAOAuthClient,
104
  verifyOAuthToken,
105
  destroyOAuthToken,
106
  revokeOAuthTokens,
107
  getProfileData,
108
  sendMetricsFlowPing,
109
  getSha1
110
}
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

© 2026 Coveralls, Inc