@@ -5,6 +5,7 @@ var Parse = require('parse/node').Parse;
55
66const https = require ( 'https' ) ;
77const jwt = require ( 'jsonwebtoken' ) ;
8+ const httpsRequest = require ( './httpsRequest' ) ;
89
910const TOKEN_ISSUER = 'accounts.google.com' ;
1011const HTTPS_TOKEN_ISSUER = 'https://accounts.google.com' ;
@@ -25,7 +26,7 @@ function getGoogleKeyByKeyId(keyId) {
2526 data += chunk . toString ( 'utf8' ) ;
2627 } ) ;
2728 res . on ( 'end' , ( ) => {
28- const { keys } = JSON . parse ( data ) ;
29+ const { keys} = JSON . parse ( data ) ;
2930 const pems = keys . reduce (
3031 ( pems , { n : modulus , e : exposant , kid } ) =>
3132 Object . assign ( pems , {
@@ -52,7 +53,7 @@ function getGoogleKeyByKeyId(keyId) {
5253}
5354
5455function getHeaderFromToken ( token ) {
55- const decodedToken = jwt . decode ( token , { complete : true } ) ;
56+ const decodedToken = jwt . decode ( token , { complete : true } ) ;
5657
5758 if ( ! decodedToken ) {
5859 throw new Parse . Error ( Parse . Error . OBJECT_NOT_FOUND , `provided token does not decode as JWT` ) ;
@@ -61,7 +62,7 @@ function getHeaderFromToken(token) {
6162 return decodedToken . header ;
6263}
6364
64- async function verifyIdToken ( { id_token : token , id } , { clientId } ) {
65+ async function verifyIdToken ( { id_token : token , id} , { clientId} ) {
6566 if ( ! token ) {
6667 throw new Parse . Error ( Parse . Error . OBJECT_NOT_FOUND , `id token is invalid for this user.` ) ;
6768 }
@@ -101,9 +102,34 @@ async function verifyIdToken({ id_token: token, id }, { clientId }) {
101102 return jwtClaims ;
102103}
103104
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+
104116// 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+ }
107133}
108134
109135// Returns a promise that fulfills if this app id is valid.
@@ -113,9 +139,10 @@ function validateAppId() {
113139
114140module . exports = {
115141 validateAppId : validateAppId ,
116- validateAuthData : validateAuthData ,
142+ validateAuthData : validateAuthData
117143} ;
118144
145+
119146// Helpers functions to convert the RSA certs to PEM (from jwks-rsa)
120147function rsaPublicKeyToPEM ( modulusB64 , exponentB64 ) {
121148 const modulus = new Buffer ( modulusB64 , 'base64' ) ;
@@ -169,3 +196,8 @@ function encodeLengthHex(n) {
169196 const lengthOfLengthByte = 128 + nHex . length / 2 ;
170197 return toHex ( lengthOfLengthByte ) + nHex ;
171198}
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