@@ -5,6 +5,7 @@ var Parse = require('parse/node').Parse;
5
5
6
6
const https = require ( 'https' ) ;
7
7
const jwt = require ( 'jsonwebtoken' ) ;
8
+ const httpsRequest = require ( './httpsRequest' ) ;
8
9
9
10
const TOKEN_ISSUER = 'accounts.google.com' ;
10
11
const HTTPS_TOKEN_ISSUER = 'https://accounts.google.com' ;
@@ -25,7 +26,7 @@ function getGoogleKeyByKeyId(keyId) {
25
26
data += chunk . toString ( 'utf8' ) ;
26
27
} ) ;
27
28
res . on ( 'end' , ( ) => {
28
- const { keys } = JSON . parse ( data ) ;
29
+ const { keys} = JSON . parse ( data ) ;
29
30
const pems = keys . reduce (
30
31
( pems , { n : modulus , e : exposant , kid } ) =>
31
32
Object . assign ( pems , {
@@ -52,7 +53,7 @@ function getGoogleKeyByKeyId(keyId) {
52
53
}
53
54
54
55
function getHeaderFromToken ( token ) {
55
- const decodedToken = jwt . decode ( token , { complete : true } ) ;
56
+ const decodedToken = jwt . decode ( token , { complete : true } ) ;
56
57
57
58
if ( ! decodedToken ) {
58
59
throw new Parse . Error ( Parse . Error . OBJECT_NOT_FOUND , `provided token does not decode as JWT` ) ;
@@ -61,7 +62,7 @@ function getHeaderFromToken(token) {
61
62
return decodedToken . header ;
62
63
}
63
64
64
- async function verifyIdToken ( { id_token : token , id } , { clientId } ) {
65
+ async function verifyIdToken ( { id_token : token , id} , { clientId} ) {
65
66
if ( ! token ) {
66
67
throw new Parse . Error ( Parse . Error . OBJECT_NOT_FOUND , `id token is invalid for this user.` ) ;
67
68
}
@@ -101,9 +102,34 @@ async function verifyIdToken({ id_token: token, id }, { clientId }) {
101
102
return jwtClaims ;
102
103
}
103
104
105
+ // Old way to validate an auth_token, only used for development purpose
106
+ function validateAuthToken ( { id, access_token} ) {
107
+ return googleRequest ( 'tokeninfo?access_token=' + access_token ) . then ( response => {
108
+ if ( response && ( response . sub == id || response . user_id == id ) ) {
109
+ return ;
110
+ }
111
+ throw new Parse . Error (
112
+ Parse . Error . OBJECT_NOT_FOUND , 'Google auth is invalid for this user.' ) ;
113
+ } ) ;
114
+ }
115
+
104
116
// Returns a promise that fulfills if this user id is valid.
105
- function validateAuthData ( authData , options = { } ) {
106
- return verifyIdToken ( authData , options ) ;
117
+ function validateAuthData ( { id, id_token, access_token} , options ) {
118
+ // Returns a promise that fulfills if this user id is valid.
119
+ if ( id_token ) {
120
+ return verifyIdToken ( { id, id_token} , options ) ;
121
+ } else {
122
+ return validateAuthToken ( { id, access_token} ) . then (
123
+ ( ) => {
124
+ // Validation with auth token worked
125
+ return ;
126
+ } ,
127
+ ( ) => {
128
+ // Try with the id_token param
129
+ return verifyIdToken ( { id, id_token : access_token } , options ) ;
130
+ }
131
+ ) ;
132
+ }
107
133
}
108
134
109
135
// Returns a promise that fulfills if this app id is valid.
@@ -113,9 +139,10 @@ function validateAppId() {
113
139
114
140
module . exports = {
115
141
validateAppId : validateAppId ,
116
- validateAuthData : validateAuthData ,
142
+ validateAuthData : validateAuthData
117
143
} ;
118
144
145
+
119
146
// Helpers functions to convert the RSA certs to PEM (from jwks-rsa)
120
147
function rsaPublicKeyToPEM ( modulusB64 , exponentB64 ) {
121
148
const modulus = new Buffer ( modulusB64 , 'base64' ) ;
@@ -169,3 +196,8 @@ function encodeLengthHex(n) {
169
196
const lengthOfLengthByte = 128 + nHex . length / 2 ;
170
197
return toHex ( lengthOfLengthByte ) + nHex ;
171
198
}
199
+
200
+ // A promisey wrapper for api requests
201
+ function googleRequest ( path ) {
202
+ return httpsRequest . get ( 'https://www.googleapis.com/oauth2/v3/' + path ) ;
203
+ }
0 commit comments