@@ -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 , {
@@ -54,7 +55,7 @@ function getGoogleKeyByKeyId(keyId) {
54
55
}
55
56
56
57
function getHeaderFromToken ( token ) {
57
- const decodedToken = jwt . decode ( token , { complete : true } ) ;
58
+ const decodedToken = jwt . decode ( token , { complete : true } ) ;
58
59
59
60
if ( ! decodedToken ) {
60
61
throw new Parse . Error (
@@ -66,7 +67,7 @@ function getHeaderFromToken(token) {
66
67
return decodedToken . header ;
67
68
}
68
69
69
- async function verifyIdToken ( { id_token : token , id } , { clientId } ) {
70
+ async function verifyIdToken ( { id_token : token , id} , { clientId} ) {
70
71
if ( ! token ) {
71
72
throw new Parse . Error (
72
73
Parse . Error . OBJECT_NOT_FOUND ,
@@ -112,9 +113,34 @@ async function verifyIdToken({ id_token: token, id }, { clientId }) {
112
113
return jwtClaims ;
113
114
}
114
115
116
+ // Old way to validate an auth_token, only used for development purpose
117
+ function validateAuthToken ( { id, access_token} ) {
118
+ return googleRequest ( 'tokeninfo?access_token=' + access_token ) . then ( response => {
119
+ if ( response && ( response . sub == id || response . user_id == id ) ) {
120
+ return ;
121
+ }
122
+ throw new Parse . Error (
123
+ Parse . Error . OBJECT_NOT_FOUND , 'Google auth is invalid for this user.' ) ;
124
+ } ) ;
125
+ }
126
+
115
127
// Returns a promise that fulfills if this user id is valid.
116
- function validateAuthData ( authData , options = { } ) {
117
- return verifyIdToken ( authData , options ) ;
128
+ function validateAuthData ( { id, id_token, access_token} , options ) {
129
+ // Returns a promise that fulfills if this user id is valid.
130
+ if ( id_token ) {
131
+ return verifyIdToken ( { id, id_token} , options ) ;
132
+ } else {
133
+ return validateAuthToken ( { id, access_token} ) . then (
134
+ ( ) => {
135
+ // Validation with auth token worked
136
+ return ;
137
+ } ,
138
+ ( ) => {
139
+ // Try with the id_token param
140
+ return verifyIdToken ( { id, id_token : access_token } , options ) ;
141
+ }
142
+ ) ;
143
+ }
118
144
}
119
145
120
146
// Returns a promise that fulfills if this app id is valid.
@@ -124,9 +150,10 @@ function validateAppId() {
124
150
125
151
module . exports = {
126
152
validateAppId : validateAppId ,
127
- validateAuthData : validateAuthData ,
153
+ validateAuthData : validateAuthData
128
154
} ;
129
155
156
+
130
157
// Helpers functions to convert the RSA certs to PEM (from jwks-rsa)
131
158
function rsaPublicKeyToPEM ( modulusB64 , exponentB64 ) {
132
159
const modulus = new Buffer ( modulusB64 , 'base64' ) ;
@@ -182,3 +209,8 @@ function encodeLengthHex(n) {
182
209
const lengthOfLengthByte = 128 + nHex . length / 2 ;
183
210
return toHex ( lengthOfLengthByte ) + nHex ;
184
211
}
212
+
213
+ // A promisey wrapper for api requests
214
+ function googleRequest ( path ) {
215
+ return httpsRequest . get ( 'https://www.googleapis.com/oauth2/v3/' + path ) ;
216
+ }
0 commit comments