@@ -60,7 +60,7 @@ if (module) {
60
60
module . exports = {
61
61
createService : createService ,
62
62
getRedirectUri : getRedirectUri
63
- }
63
+ } ;
64
64
}
65
65
66
66
// Copyright 2014 Google Inc. All Rights Reserved.
@@ -81,6 +81,10 @@ if (module) {
81
81
* @fileoverview Contains the Service_ class.
82
82
*/
83
83
84
+ // Disable JSHint warnings for the use of eval(), since it's required to prevent
85
+ // scope issues in Apps Script.
86
+ // jshint evil:true
87
+
84
88
/**
85
89
* Creates a new OAuth2 service.
86
90
* @param {string } serviceName The name of the service.
@@ -148,6 +152,16 @@ Service_.prototype.setTokenHeaders = function(tokenHeaders) {
148
152
return this ;
149
153
} ;
150
154
155
+ /**
156
+ * Sets an additional function to invoke on the payload of the access token request.
157
+ * @param Object tokenHandler A function to invoke on the payload of the request for an access token.
158
+ * @return {Service_ } This service, for chaining.
159
+ */
160
+ Service_ . prototype . setTokenPayloadHandler = function ( tokenHandler ) {
161
+ this . tokenPayloadHandler_ = tokenHandler ;
162
+ return this ;
163
+ } ;
164
+
151
165
/**
152
166
* Sets the project key of the script that contains the authorization callback function (required).
153
167
* The project key can be found in the Script Editor UI under "File > Project properties".
@@ -235,7 +249,7 @@ Service_.prototype.setCache = function(cache) {
235
249
*/
236
250
Service_ . prototype . setScope = function ( scope , opt_separator ) {
237
251
var separator = opt_separator || ' ' ;
238
- this . params_ [ ' scope' ] = _ . isArray ( scope ) ? scope . join ( separator ) : scope ;
252
+ this . params_ . scope = _ . isArray ( scope ) ? scope . join ( separator ) : scope ;
239
253
return this ;
240
254
} ;
241
255
@@ -352,16 +366,21 @@ Service_.prototype.handleCallback = function(callbackRequest) {
352
366
if ( this . tokenHeaders_ ) {
353
367
headers = _ . extend ( headers , this . tokenHeaders_ ) ;
354
368
}
369
+ var tokenPayload = {
370
+ code : code ,
371
+ client_id : this . clientId_ ,
372
+ client_secret : this . clientSecret_ ,
373
+ redirect_uri : redirectUri ,
374
+ grant_type : 'authorization_code'
375
+ } ;
376
+ if ( this . tokenPayloadHandler_ ) {
377
+ tokenPayload = this . tokenPayloadHandler_ ( tokenPayload ) ;
378
+ Logger . log ( 'Token payload from tokenPayloadHandler: %s' , JSON . stringify ( tokenPayload ) ) ;
379
+ }
355
380
var response = UrlFetchApp . fetch ( this . tokenUrl_ , {
356
381
method : 'post' ,
357
382
headers : headers ,
358
- payload : {
359
- code : code ,
360
- client_id : this . clientId_ ,
361
- client_secret : this . clientSecret_ ,
362
- redirect_uri : redirectUri ,
363
- grant_type : 'authorization_code'
364
- } ,
383
+ payload : tokenPayload ,
365
384
muteHttpExceptions : true
366
385
} ) ;
367
386
var token = this . getTokenFromResponse_ ( response ) ;
@@ -441,7 +460,7 @@ Service_.prototype.getLastError = function() {
441
460
Service_ . prototype . getTokenFromResponse_ = function ( response ) {
442
461
var token = this . parseToken_ ( response . getContentText ( ) ) ;
443
462
if ( response . getResponseCode ( ) != 200 || token . error ) {
444
- var reason = [ token . error , token . error_description , token . error_uri ] . filter ( Boolean ) . join ( ', ' ) ;
463
+ var reason = [ token . error , token . message , token . error_description , token . error_uri ] . filter ( Boolean ) . join ( ', ' ) ;
445
464
if ( ! reason ) {
446
465
reason = response . getResponseCode ( ) + ': ' + JSON . stringify ( token ) ;
447
466
}
@@ -464,7 +483,7 @@ Service_.prototype.parseToken_ = function(content) {
464
483
} catch ( e ) {
465
484
throw 'Token response not valid JSON: ' + e ;
466
485
}
467
- } else if ( this . tokenFormat_ = TOKEN_FORMAT . FORM_URL_ENCODED ) {
486
+ } else if ( this . tokenFormat_ == TOKEN_FORMAT . FORM_URL_ENCODED ) {
468
487
token = content . split ( '&' ) . reduce ( function ( result , pair ) {
469
488
var parts = pair . split ( '=' ) ;
470
489
result [ decodeURIComponent ( parts [ 0 ] ) ] = decodeURIComponent ( parts [ 1 ] ) ;
@@ -497,15 +516,20 @@ Service_.prototype.refresh = function() {
497
516
if ( this . tokenHeaders_ ) {
498
517
headers = _ . extend ( headers , this . tokenHeaders_ ) ;
499
518
}
500
- var response = UrlFetchApp . fetch ( this . tokenUrl_ , {
501
- method : 'post' ,
502
- headers : headers ,
503
- payload : {
519
+ var tokenPayload = {
504
520
refresh_token : token . refresh_token ,
505
521
client_id : this . clientId_ ,
506
522
client_secret : this . clientSecret_ ,
507
523
grant_type : 'refresh_token'
508
- } ,
524
+ } ;
525
+ if ( this . tokenPayloadHandler_ ) {
526
+ tokenPayload = this . tokenPayloadHandler_ ( tokenPayload ) ;
527
+ Logger . log ( 'Token payload from tokenPayloadHandler (refresh): %s' , JSON . stringify ( tokenPayload ) ) ;
528
+ }
529
+ var response = UrlFetchApp . fetch ( this . tokenUrl_ , {
530
+ method : 'post' ,
531
+ headers : headers ,
532
+ payload : tokenPayload ,
509
533
muteHttpExceptions : true
510
534
} ) ;
511
535
var newToken = this . getTokenFromResponse_ ( response ) ;
@@ -639,10 +663,10 @@ Service_.prototype.createJwt_ = function() {
639
663
iat : Math . round ( now . getTime ( ) / 1000 )
640
664
} ;
641
665
if ( this . subject_ ) {
642
- claimSet [ ' sub' ] = this . subject_ ;
666
+ claimSet . sub = this . subject_ ;
643
667
}
644
- if ( this . params_ [ ' scope' ] ) {
645
- claimSet [ ' scope' ] = this . params_ [ ' scope' ] ;
668
+ if ( this . params_ . scope ) {
669
+ claimSet . scope = this . params_ . scope ;
646
670
}
647
671
var toSign = Utilities . base64EncodeWebSafe ( JSON . stringify ( header ) ) + '.' + Utilities . base64EncodeWebSafe ( JSON . stringify ( claimSet ) ) ;
648
672
var signatureBytes = Utilities . computeRsaSha256Signature ( toSign , this . privateKey_ ) ;
@@ -705,7 +729,7 @@ function validate_(params) {
705
729
* @private
706
730
*/
707
731
function isEmpty_ ( value ) {
708
- return value == null || value == undefined ||
732
+ return value === null || value = == undefined ||
709
733
( ( _ . isObject ( value ) || _ . isString ( value ) ) && _ . isEmpty ( value ) ) ;
710
734
}
711
735
0 commit comments