Skip to content

Commit 15ebf8a

Browse files
author
Eric Koleda
committed
Release version 29.
1 parent 0ce0910 commit 15ebf8a

File tree

3 files changed

+78
-64
lines changed

3 files changed

+78
-64
lines changed

dist/OAuth2.gs

Lines changed: 76 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,20 @@ Service_.prototype.setExpirationMinutes = function(expirationMinutes) {
370370
return this;
371371
};
372372

373+
/**
374+
* Sets the OAuth2 grant_type to use when obtaining an access token. This does
375+
* not need to be set when using either the authorization code flow (AKA
376+
* 3-legged OAuth) or the service account flow. The most common usage is to set
377+
* it to "client_credentials" and then also set the token headers to include
378+
* the Authorization header required by the OAuth2 provider.
379+
* @param {string} grantType The OAuth2 grant_type value.
380+
* @return {Service_} This service, for chaining.
381+
*/
382+
Service_.prototype.setGrantType = function(grantType) {
383+
this.grantType_ = grantType;
384+
return this;
385+
};
386+
373387
/**
374388
* Gets the authorization URL. The first step in getting an OAuth2 token is to
375389
* have the user visit this URL and approve the authorization request. The
@@ -425,29 +439,14 @@ Service_.prototype.handleCallback = function(callbackRequest) {
425439
'Token URL': this.tokenUrl_
426440
});
427441
var redirectUri = getRedirectUri(this.scriptId_);
428-
var headers = {
429-
'Accept': this.tokenFormat_
430-
};
431-
if (this.tokenHeaders_) {
432-
headers = extend_(headers, this.tokenHeaders_);
433-
}
434-
var tokenPayload = {
442+
var payload = {
435443
code: code,
436444
client_id: this.clientId_,
437445
client_secret: this.clientSecret_,
438446
redirect_uri: redirectUri,
439447
grant_type: 'authorization_code'
440448
};
441-
if (this.tokenPayloadHandler_) {
442-
tokenPayload = this.tokenPayloadHandler_(tokenPayload);
443-
}
444-
var response = UrlFetchApp.fetch(this.tokenUrl_, {
445-
method: 'post',
446-
headers: headers,
447-
payload: tokenPayload,
448-
muteHttpExceptions: true
449-
});
450-
var token = this.getTokenFromResponse_(response);
449+
var token = this.fetchToken_(payload);
451450
this.saveToken_(token);
452451
return true;
453452
};
@@ -463,21 +462,18 @@ Service_.prototype.hasAccess = function() {
463462
return this.lockable_(function() {
464463
var token = this.getToken();
465464
if (!token || this.isExpired_(token)) {
466-
if (token && this.canRefresh_(token)) {
467-
try {
465+
try {
466+
if (token && this.canRefresh_(token)) {
468467
this.refresh();
469-
} catch (e) {
470-
this.lastError_ = e;
471-
return false;
472-
}
473-
} else if (this.privateKey_) {
474-
try {
468+
} else if (this.privateKey_) {
475469
this.exchangeJwt_();
476-
} catch (e) {
477-
this.lastError_ = e;
470+
} else if (this.grantType_) {
471+
this.exchangeGrant_();
472+
} else {
478473
return false;
479474
}
480-
} else {
475+
} catch (e) {
476+
this.lastError_ = e;
481477
return false;
482478
}
483479
}
@@ -525,6 +521,34 @@ Service_.prototype.getRedirectUri = function() {
525521
return getRedirectUri(this.scriptId_);
526522
};
527523

524+
525+
/**
526+
* Fetches a new token from the OAuth server.
527+
* @param {Object} payload The token request payload.
528+
* @param {string} [optUrl] The URL of the token endpoint.
529+
* @return {Object} The parsed token.
530+
*/
531+
Service_.prototype.fetchToken_ = function(payload, optUrl) {
532+
// Use the configured token URL unless one is specified.
533+
var url = optUrl || this.tokenUrl_;
534+
var headers = {
535+
'Accept': this.tokenFormat_
536+
};
537+
if (this.tokenHeaders_) {
538+
headers = extend_(headers, this.tokenHeaders_);
539+
}
540+
if (this.tokenPayloadHandler_) {
541+
tokenPayload = this.tokenPayloadHandler_(payload);
542+
}
543+
var response = UrlFetchApp.fetch(url, {
544+
method: 'post',
545+
headers: headers,
546+
payload: payload,
547+
muteHttpExceptions: true
548+
});
549+
return this.getTokenFromResponse_(response);
550+
};
551+
528552
/**
529553
* Gets the token from a UrlFetchApp response.
530554
* @param {UrlFetchApp.HTTPResponse} response The response object.
@@ -595,30 +619,13 @@ Service_.prototype.refresh = function() {
595619
if (!token.refresh_token) {
596620
throw new Error('Offline access is required.');
597621
}
598-
var headers = {
599-
Accept: this.tokenFormat_
600-
};
601-
if (this.tokenHeaders_) {
602-
headers = extend_(headers, this.tokenHeaders_);
603-
}
604-
var tokenPayload = {
622+
var payload = {
605623
refresh_token: token.refresh_token,
606624
client_id: this.clientId_,
607625
client_secret: this.clientSecret_,
608626
grant_type: 'refresh_token'
609627
};
610-
if (this.tokenPayloadHandler_) {
611-
tokenPayload = this.tokenPayloadHandler_(tokenPayload);
612-
}
613-
// Use the refresh URL if specified, otherwise fallback to the token URL.
614-
var url = this.refreshUrl_ || this.tokenUrl_;
615-
var response = UrlFetchApp.fetch(url, {
616-
method: 'post',
617-
headers: headers,
618-
payload: tokenPayload,
619-
muteHttpExceptions: true
620-
});
621-
var newToken = this.getTokenFromResponse_(response);
628+
var newToken = this.fetchToken_(payload, this.refreshUrl_);
622629
if (!newToken.refresh_token) {
623630
newToken.refresh_token = token.refresh_token;
624631
}
@@ -706,22 +713,11 @@ Service_.prototype.exchangeJwt_ = function() {
706713
'Token URL': this.tokenUrl_
707714
});
708715
var jwt = this.createJwt_();
709-
var headers = {
710-
'Accept': this.tokenFormat_
716+
var payload = {
717+
assertion: jwt,
718+
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer'
711719
};
712-
if (this.tokenHeaders_) {
713-
headers = extend_(headers, this.tokenHeaders_);
714-
}
715-
var response = UrlFetchApp.fetch(this.tokenUrl_, {
716-
method: 'post',
717-
headers: headers,
718-
payload: {
719-
assertion: jwt,
720-
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer'
721-
},
722-
muteHttpExceptions: true
723-
});
724-
var token = this.getTokenFromResponse_(response);
720+
var token = this.fetchToken_(payload);
725721
this.saveToken_(token);
726722
};
727723

@@ -783,6 +779,24 @@ Service_.prototype.lockable_ = function(func) {
783779
return result;
784780
};
785781

782+
/**
783+
* Obtain an access token using the custom grant type specified. Most often
784+
* this will be "client_credentials", in which case make sure to also specify an
785+
* Authorization header if required by your OAuth provider.
786+
*/
787+
Service_.prototype.exchangeGrant_ = function() {
788+
validate_({
789+
'Grant Type': this.grantType_,
790+
'Token URL': this.tokenUrl_
791+
});
792+
var payload = {
793+
grant_type: this.grantType_
794+
};
795+
payload = extend_(payload, this.params_);
796+
var token = this.fetchToken_(payload);
797+
this.saveToken_(token);
798+
};
799+
786800
// Copyright 2017 Google Inc. All Rights Reserved.
787801
//
788802
// Licensed under the Apache License, Version 2.0 (the "License");

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "apps-script-oauth2",
3-
"version": "1.28.0",
3+
"version": "1.29.0",
44
"description": "OAuth2 for Apps Script is a library for Google Apps Script that provides the ability to create and authorize OAuth2 tokens as well as refresh them when they expire.",
55
"repository": {
66
"type": "git",

0 commit comments

Comments
 (0)