@@ -5,15 +5,29 @@ var MockProperties = require('./mocks/properties');
55var MockCache = require ( './mocks/cache' ) ;
66var MockLock = require ( './mocks/lock' ) ;
77var MockScriptApp = require ( './mocks/script' ) ;
8+ var MockBlob = require ( './mocks/blob' ) ;
89var Future = require ( 'fibers/future' ) ;
10+ var URLSafeBase64 = require ( 'urlsafe-base64' ) ;
911
1012var mocks = {
1113 ScriptApp : new MockScriptApp ( ) ,
1214 UrlFetchApp : new MockUrlFetchApp ( ) ,
1315 Utilities : {
1416 base64Encode : function ( data ) {
1517 return Buffer . from ( data ) . toString ( 'base64' ) ;
16- }
18+ } ,
19+ base64EncodeWebSafe : function ( data ) {
20+ return URLSafeBase64 . encode ( Buffer . from ( data ) ) ;
21+ } ,
22+ base64DecodeWebSafe : function ( data ) {
23+ return URLSafeBase64 . decode ( data ) ;
24+ } ,
25+ computeRsaSha256Signature : function ( data , key ) {
26+ return Math . random ( ) . toString ( 36 ) ;
27+ } ,
28+ newBlob : function ( data ) {
29+ return new MockBlob ( data ) ;
30+ } ,
1731 } ,
1832 __proto__ : gas . globalMockDefault
1933} ;
@@ -483,6 +497,155 @@ describe('Service', function() {
483497 assert . equal ( state . arguments . foo , 'bar' ) ;
484498 } ) ;
485499 } ) ;
500+
501+ describe ( '#isExpired_()' , function ( ) {
502+ const NOW_SECONDS = OAuth2 . getTimeInSeconds_ ( new Date ( ) ) ;
503+ const ONE_HOUR_AGO_SECONDS = NOW_SECONDS - 360 ;
504+
505+
506+ it ( 'should return false if there is no expiration time in the token' ,
507+ function ( ) {
508+ var service = OAuth2 . createService ( 'test' )
509+ . setPropertyStore ( new MockProperties ( ) )
510+ . setCache ( new MockCache ( ) ) ;
511+ var token = { } ;
512+
513+ assert . isFalse ( service . isExpired_ ( token ) ) ;
514+ } ) ;
515+
516+ it ( 'should return false if before the time in expires_in' , function ( ) {
517+ var service = OAuth2 . createService ( 'test' )
518+ . setPropertyStore ( new MockProperties ( ) )
519+ . setCache ( new MockCache ( ) ) ;
520+ var token = {
521+ expires_in : 360 , // One hour.
522+ granted_time : NOW_SECONDS ,
523+ } ;
524+
525+ assert . isFalse ( service . isExpired_ ( token ) ) ;
526+ } ) ;
527+
528+ it ( 'should return true if past the time in "expires_in"' , function ( ) {
529+ var service = OAuth2 . createService ( 'test' )
530+ . setPropertyStore ( new MockProperties ( ) )
531+ . setCache ( new MockCache ( ) ) ;
532+ var token = {
533+ expires_in : 60 , // One minute.
534+ granted_time : ONE_HOUR_AGO_SECONDS ,
535+ } ;
536+
537+ assert . isTrue ( service . isExpired_ ( token ) ) ;
538+ } ) ;
539+
540+ it ( 'should return false if before the time in "expires"' , function ( ) {
541+ var service = OAuth2 . createService ( 'test' )
542+ . setPropertyStore ( new MockProperties ( ) )
543+ . setCache ( new MockCache ( ) ) ;
544+ var token = {
545+ expires_in : 360 , // One hour.
546+ granted_time : NOW_SECONDS ,
547+ } ;
548+
549+ assert . isFalse ( service . isExpired_ ( token ) ) ;
550+ } ) ;
551+
552+ it ( 'should return true if past the time in "expires"' , function ( ) {
553+ var service = OAuth2 . createService ( 'test' )
554+ . setPropertyStore ( new MockProperties ( ) )
555+ . setCache ( new MockCache ( ) ) ;
556+ var token = {
557+ expires_in : 60 , // One minute.
558+ granted_time : ONE_HOUR_AGO_SECONDS ,
559+ } ;
560+
561+ assert . isTrue ( service . isExpired_ ( token ) ) ;
562+ } ) ;
563+
564+ it ( 'should return false if before the time in "expires_in_sec"' ,
565+ function ( ) {
566+ var service = OAuth2 . createService ( 'test' )
567+ . setPropertyStore ( new MockProperties ( ) )
568+ . setCache ( new MockCache ( ) ) ;
569+ var token = {
570+ expires_in : 360 , // One hour.
571+ granted_time : NOW_SECONDS ,
572+ } ;
573+
574+ assert . isFalse ( service . isExpired_ ( token ) ) ;
575+ } ) ;
576+
577+ it ( 'should return true if past the time in "expires_in_sec"' , function ( ) {
578+ var service = OAuth2 . createService ( 'test' )
579+ . setPropertyStore ( new MockProperties ( ) )
580+ . setCache ( new MockCache ( ) ) ;
581+ var token = {
582+ expires_in : 60 , // One minute.
583+ granted_time : ONE_HOUR_AGO_SECONDS ,
584+ } ;
585+
586+ assert . isTrue ( service . isExpired_ ( token ) ) ;
587+ } ) ;
588+
589+ it ( 'should return true if within the buffer' , function ( ) {
590+ var service = OAuth2 . createService ( 'test' )
591+ . setPropertyStore ( new MockProperties ( ) )
592+ . setCache ( new MockCache ( ) ) ;
593+ var token = {
594+ expires_in : 30 , // 30 seconds.
595+ granted_time : NOW_SECONDS ,
596+ } ;
597+
598+ assert . isTrue ( service . isExpired_ ( token ) ) ;
599+ } ) ;
600+
601+ it ( 'should return true if past the JWT expiration' , function ( ) {
602+ var service = OAuth2 . createService ( 'test' )
603+ . setPropertyStore ( new MockProperties ( ) )
604+ . setCache ( new MockCache ( ) ) ;
605+ var idToken = OAuth2 . encodeJwt_ ( {
606+ exp : NOW_SECONDS - 60 , // One minute ago.
607+ } , 'key' ) ;
608+ var token = {
609+ id_token : idToken ,
610+ } ;
611+
612+ assert . isTrue ( service . isExpired_ ( token ) ) ;
613+ } ) ;
614+
615+ it ( 'should return false if the JWT is expired but the token is not' ,
616+ function ( ) {
617+ var service = OAuth2 . createService ( 'test' )
618+ . setPropertyStore ( new MockProperties ( ) )
619+ . setCache ( new MockCache ( ) ) ;
620+ var idToken = OAuth2 . encodeJwt_ ( {
621+ exp : NOW_SECONDS - 60 , // One minute ago.
622+ } , 'key' ) ;
623+ var token = {
624+ id_token : idToken ,
625+ expires_in : 360 , // One hour.
626+ granted_time : NOW_SECONDS ,
627+ } ;
628+
629+ assert . isTrue ( service . isExpired_ ( token ) ) ;
630+ } ) ;
631+
632+ it ( 'should return false if the token expired but the JWT is not' ,
633+ function ( ) {
634+ var service = OAuth2 . createService ( 'test' )
635+ . setPropertyStore ( new MockProperties ( ) )
636+ . setCache ( new MockCache ( ) ) ;
637+ var idToken = OAuth2 . encodeJwt_ ( {
638+ exp : NOW_SECONDS + 360 , // One hour from now.
639+ } , 'key' ) ;
640+ var token = {
641+ id_token : idToken ,
642+ expires_in : 60 , // One minute.
643+ granted_time : ONE_HOUR_AGO_SECONDS ,
644+ } ;
645+
646+ assert . isTrue ( service . isExpired_ ( token ) ) ;
647+ } ) ;
648+ } ) ;
486649} ) ;
487650
488651describe ( 'Utilities' , function ( ) {
@@ -531,4 +694,33 @@ describe('Utilities', function() {
531694 assert . isEmpty ( toLowerCaseKeys_ ( { } ) ) ;
532695 } ) ;
533696 } ) ;
697+
698+ describe ( '#encodeJwt_()' , function ( ) {
699+ var encodeJwt_ = OAuth2 . encodeJwt_ ;
700+
701+ it ( 'should encode correctly' , function ( ) {
702+ var payload = {
703+ 'foo' : 'bar'
704+ } ;
705+
706+ var jwt = encodeJwt_ ( payload , 'key' ) ;
707+ var parts = jwt . split ( '.' ) ;
708+
709+ // Expexted values from jwt.io.
710+ assert . equal ( parts [ 0 ] , 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9' ) ;
711+ assert . equal ( parts [ 1 ] , 'eyJmb28iOiJiYXIifQ' ) ;
712+ } ) ;
713+ } ) ;
714+
715+ describe ( '#decodeJwt_()' , function ( ) {
716+ var decodeJwt_ = OAuth2 . decodeJwt_ ;
717+
718+ it ( 'should decode correctly' , function ( ) {
719+ var jwt = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.sig' ;
720+
721+ var payload = decodeJwt_ ( jwt ) ;
722+
723+ assert . deepEqual ( payload , { 'foo' : 'bar' } ) ;
724+ } ) ;
725+ } ) ;
534726} ) ;
0 commit comments