-
Notifications
You must be signed in to change notification settings - Fork 2
/
lea_server.js
106 lines (90 loc) · 2.93 KB
/
lea_server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* global ServiceConfiguration, Lea */
import { Meteor } from 'meteor/meteor'
import { OAuth } from 'meteor/oauth'
import { HTTP } from 'meteor/http'
// eslint-disable-next-line
Lea = Lea || {}
let userAgent = 'Meteor'
if (Meteor.release) {
userAgent += `/${Meteor.release}`
}
OAuth.registerService('lea', 2, null, query => {
const config = ServiceConfiguration.configurations.findOne({ service: 'lea' })
if (!config) {
throw new ServiceConfiguration.ConfigError()
}
const accessToken = getAccessToken(query)
const identity = getIdentity(accessToken)
const sealedToken = OAuth.sealSecret(accessToken)
const profile = {}
;(config.identity || []).forEach(key => {
profile[key] = identity[key]
})
// we can now define in ServiceConfig additional fields that will not be saved
// in user.profile but directly in the service data!
const extraFields = {}
;(config.extraFields || []).forEach(key => {
extraFields[key] = identity[key]
})
return {
serviceData: {
id: identity.id,
accessToken: sealedToken,
email: identity.email || '',
username: identity.login,
...extraFields
},
options: { profile }
}
})
const getAccessToken = query => {
const config = ServiceConfiguration.configurations.findOne({ service: 'lea' })
if (!config) {
throw new ServiceConfiguration.ConfigError()
}
let response
const options = {
headers: {
Accept: 'application/json',
'User-Agent': userAgent
},
params: {
code: query.code,
client_id: config.clientId,
client_secret: OAuth.openSecret(config.secret),
redirect_uri: OAuth._redirectUri('lea', config),
state: query.state,
grant_type: 'authorization_code'
}
}
try {
response = HTTP.post(config.accessTokenUrl, options)
} catch (err) {
throw Object.assign(new Error(`Failed to complete OAuth handshake with lea. ${err.message}`), { response: err.response })
}
// if the http response was a json object with an error attribute
if (response.data && response.data.error) {
throw new Error(`Failed to complete OAuth handshake with lea. ${response.data.error}`)
} else {
return response.data.access_token
}
}
const getIdentity = (accessToken) => {
const config = ServiceConfiguration.configurations.findOne({ service: 'lea' })
if (!config) {
throw new ServiceConfiguration.ConfigError()
}
let response
const options = {
headers: { Accept: 'application/json', 'User-Agent': userAgent, Authorization: `Bearer ${accessToken}` }
}
try {
response = HTTP.get(config.identityUrl, options)
} catch (err) {
const errorResponse = err.response
console.error(errorResponse.data)
throw new Meteor.Error(errorResponse.statusCode || '500', 'lea.oauth.getIdentity.failed', errorResponse)
}
return response && response.data
}
Lea.retrieveCredential = (credentialToken, credentialSecret) => OAuth.retrieveCredential(credentialToken, credentialSecret)