@@ -48,15 +48,15 @@ function createService(serviceName) {
4848/**
4949 * Returns the redirect URI that will be used for a given script. Often this URI
5050 * needs to be entered into a configuration screen of your OAuth provider.
51- * @param {string } [ optScriptId] The script ID of your script, which can be
51+ * @param {string= } optScriptId The script ID of your script, which can be
5252 * found in the Script Editor UI under "File > Project properties". Defaults
5353 * to the script ID of the script being executed.
5454 * @return {string } The redirect URI.
5555 */
5656function getRedirectUri ( optScriptId ) {
5757 var scriptId = optScriptId || ScriptApp . getScriptId ( ) ;
5858 return 'https://script.google.com/macros/d/' + encodeURIComponent ( scriptId ) +
59- '/usercallback' ;
59+ '/usercallback' ;
6060}
6161
6262/**
@@ -228,7 +228,7 @@ Service_.prototype.setCodeVerififer = function(codeVerifier) {
228228} ;
229229
230230/**
231- * Sets teh code verifier to a randomly generated challenge string.
231+ * Sets the code verifier to a randomly generated challenge string.
232232 * @return {!Service_ } This service, for chaining
233233 */
234234Service_ . prototype . generateCodeVerifier = function ( ) {
@@ -724,10 +724,35 @@ Service_.prototype.parseToken_ = function(content) {
724724 } else {
725725 throw new Error ( 'Unknown token format: ' + this . tokenFormat_ ) ;
726726 }
727- token . granted_time = getTimeInSeconds_ ( new Date ( ) ) ;
727+ this . ensureExpiresAtSet_ ( token ) ;
728728 return token ;
729729} ;
730730
731+ /**
732+ * Adds expiresAt annotations on the token if not set.
733+ * @param {string } token A token.
734+ * @private
735+ */
736+ Service_ . prototype . ensureExpiresAtSet_ = function ( token ) {
737+ // handle prior migrations
738+ if ( token . expiresAt !== undefined ) {
739+ return ;
740+ }
741+
742+ // granted_time was added in prior versions of this library
743+ var grantedTime = token . granted_time || getTimeInSeconds_ ( new Date ( ) ) ;
744+ var expiresIn = token . expires_in_sec || token . expires_in || token . expires ;
745+ if ( expiresIn ) {
746+ var expiresAt = grantedTime + Number ( expiresIn ) ;
747+ token . expiresAt = expiresAt ;
748+ }
749+ var refreshTokenExpiresIn = token . refresh_token_expires_in ;
750+ if ( refreshTokenExpiresIn ) {
751+ var refreshTokenExpiresAt = grantedTime + Number ( refreshTokenExpiresIn ) ;
752+ token . refreshTokenExpiresAt = refreshTokenExpiresAt ;
753+ }
754+ } ;
755+
731756/**
732757 * Refreshes a token that has expired. This is only possible if offline access
733758 * was requested when the token was authorized.
@@ -754,6 +779,11 @@ Service_.prototype.refresh = function() {
754779 if ( ! newToken . refresh_token ) {
755780 newToken . refresh_token = token . refresh_token ;
756781 }
782+ this . ensureExpiresAtSet_ ( token ) ;
783+ // Propagate refresh token expiry if new token omits it
784+ if ( newToken . refreshTokenExpiresAt === undefined ) {
785+ newToken . refreshTokenExpiresAt = token . refreshTokenExpiresAt ;
786+ }
757787 this . saveToken_ ( newToken ) ;
758788 } ) ;
759789} ;
@@ -805,6 +835,13 @@ Service_.prototype.isExpired_ = function(token) {
805835 var now = getTimeInSeconds_ ( new Date ( ) ) ;
806836
807837 // Check the authorization token's expiration.
838+ if ( token . expiresAt ) {
839+ if ( token . expiresAt - now < Service_ . EXPIRATION_BUFFER_SECONDS_ ) {
840+ expired = true ;
841+ }
842+ }
843+
844+ // Previous code path, provided for migration purpose, can be removed later
808845 var expiresIn = token . expires_in_sec || token . expires_in || token . expires ;
809846 if ( expiresIn ) {
810847 var expiresTime = token . granted_time + Number ( expiresIn ) ;
@@ -833,13 +870,14 @@ Service_.prototype.isExpired_ = function(token) {
833870 */
834871Service_ . prototype . canRefresh_ = function ( token ) {
835872 if ( ! token . refresh_token ) return false ;
836- var expiresIn = token . refresh_token_expires_in ;
837- if ( ! expiresIn ) {
873+ this . ensureExpiresAtSet_ ( token ) ;
874+ if ( token . refreshTokenExpiresAt === undefined ) {
838875 return true ;
839876 } else {
840- var expiresTime = token . granted_time + Number ( expiresIn ) ;
841877 var now = getTimeInSeconds_ ( new Date ( ) ) ;
842- return expiresTime - now > Service_ . EXPIRATION_BUFFER_SECONDS_ ;
878+ return (
879+ token . refreshTokenExpiresAt - now > Service_ . EXPIRATION_BUFFER_SECONDS_
880+ ) ;
843881 }
844882} ;
845883
0 commit comments