1
1
const axios = require ( 'axios' ) ;
2
+ const qs = require ( 'qs' ) ;
2
3
const {
3
- GITHUB_CLIENT_ID ,
4
- GITHUB_CLIENT_SECRET ,
4
+ LINKEDIN_CLIENT_ID ,
5
+ LINKEDIN_CLIENT_SECRET ,
5
6
COGNITO_REDIRECT_URI ,
6
- GITHUB_API_URL ,
7
- GITHUB_LOGIN_URL
7
+ LINKEDIN_API_URL ,
8
+ LINKEDIN_LOGIN_URL ,
9
+ LINKEDIN_SCOPE ,
8
10
} = require ( './config' ) ;
9
11
const logger = require ( './connectors/logger' ) ;
10
12
11
13
const getApiEndpoints = (
12
- apiBaseUrl = GITHUB_API_URL ,
13
- loginBaseUrl = GITHUB_LOGIN_URL
14
+ apiBaseUrl = LINKEDIN_API_URL ,
15
+ loginBaseUrl = LINKEDIN_LOGIN_URL
14
16
) => ( {
15
- userDetails : `${ apiBaseUrl } /user ` ,
16
- userEmails : `${ apiBaseUrl } /user/emails ` ,
17
- oauthToken : `${ loginBaseUrl } /login/ oauth/access_token ` ,
18
- oauthAuthorize : `${ loginBaseUrl } /login/ oauth/authorize`
17
+ userDetails : `${ apiBaseUrl } /v2/me ` ,
18
+ userEmails : `${ apiBaseUrl } /v2/clientAwareMemberHandles?q=members&projection=(elements*(primary,type,handle~)) ` ,
19
+ oauthToken : `${ apiBaseUrl } / oauth/v2/accessToken ` ,
20
+ oauthAuthorize : `${ loginBaseUrl } /oauth/v2/authorization` ,
19
21
} ) ;
20
22
21
23
const check = response => {
22
24
logger . debug ( 'Checking response: %j' , response , { } ) ;
23
25
if ( response . data ) {
24
26
if ( response . data . error ) {
25
27
throw new Error (
26
- `GitHub API responded with a failure: ${ response . data . error } , ${
28
+ `LinkedIn API responded with a failure: ${ response . data . error } , ${
27
29
response . data . error_description
28
30
} `
29
31
) ;
@@ -32,42 +34,42 @@ const check = response => {
32
34
}
33
35
}
34
36
throw new Error (
35
- `GitHub API responded with a failure: ${ response . status } (${
37
+ `LinkedIn API responded with a failure: ${ response . status } (${
36
38
response . statusText
37
39
} )`
38
40
) ;
39
41
} ;
40
42
41
- const gitHubGet = ( url , accessToken ) =>
43
+ const linkedinGet = ( url , accessToken ) =>
42
44
axios ( {
43
45
method : 'get' ,
44
46
url,
45
47
headers : {
46
- Accept : 'application/vnd.github.v3+json' ,
47
- Authorization : `token ${ accessToken } `
48
+ Authorization : `Bearer ${ accessToken } `
48
49
}
49
50
} ) ;
50
51
51
52
module . exports = ( apiBaseUrl , loginBaseUrl ) => {
52
53
const urls = getApiEndpoints ( apiBaseUrl , loginBaseUrl || apiBaseUrl ) ;
53
54
return {
54
- getAuthorizeUrl : ( client_id , scope , state , response_type ) =>
55
- `${ urls . oauthAuthorize } ?client_id=${ client_id } &scope=${ encodeURIComponent (
56
- scope
57
- ) } &state=${ state } &response_type=${ response_type } `,
55
+ getAuthorizeUrl : ( client_id , scope , state , response_type ) => {
56
+ const scopesToSend = scope . split ( ' ' ) . filter ( s => s !== 'openid' ) . join ( ' ' ) ;
57
+ return `${ urls . oauthAuthorize } ?client_id=${ client_id } &scope=${ encodeURIComponent (
58
+ scopesToSend
59
+ ) } &state=${ state } &response_type=${ response_type } &redirect_uri=${ COGNITO_REDIRECT_URI } `;
60
+ } ,
58
61
getUserDetails : accessToken =>
59
- gitHubGet ( urls . userDetails , accessToken ) . then ( check ) ,
62
+ linkedinGet ( urls . userDetails , accessToken ) . then ( check ) ,
60
63
getUserEmails : accessToken =>
61
- gitHubGet ( urls . userEmails , accessToken ) . then ( check ) ,
64
+ linkedinGet ( urls . userEmails , accessToken ) . then ( check ) ,
62
65
getToken : ( code , state ) => {
63
66
const data = {
64
67
// OAuth required fields
65
68
grant_type : 'authorization_code' ,
66
69
redirect_uri : COGNITO_REDIRECT_URI ,
67
- client_id : GITHUB_CLIENT_ID ,
68
- // GitHub Specific
70
+ client_id : LINKEDIN_CLIENT_ID ,
69
71
response_type : 'code' ,
70
- client_secret : GITHUB_CLIENT_SECRET ,
72
+ client_secret : LINKEDIN_CLIENT_SECRET ,
71
73
code,
72
74
// State may not be present, so we conditionally include it
73
75
...( state && { state } )
@@ -79,15 +81,22 @@ module.exports = (apiBaseUrl, loginBaseUrl) => {
79
81
data ,
80
82
{ }
81
83
) ;
82
- return axios ( {
83
- method : 'post' ,
84
- url : urls . oauthToken ,
85
- headers : {
86
- Accept : 'application/json' ,
87
- 'Content-Type' : 'application/json'
88
- } ,
89
- data
90
- } ) . then ( check ) ;
84
+ return axios . post (
85
+ urls . oauthToken ,
86
+ qs . stringify ( data ) ,
87
+ {
88
+ headers : {
89
+ Accept : 'application/json' ,
90
+ // 'Content-Type': 'application/json'
91
+ } ,
92
+ }
93
+ ) . then ( check )
94
+ . then ( data => {
95
+ // Because LinkedIn doesn't return the scopes
96
+ data . scope = LINKEDIN_SCOPE ;
97
+ data . token_type = 'bearer' ;
98
+ return data ;
99
+ } )
91
100
}
92
101
} ;
93
102
} ;
0 commit comments