2222import android .os .Handler ;
2323import android .util .Log ;
2424
25+ import com .amazonaws .AmazonClientException ;
2526import com .amazonaws .AmazonServiceException ;
27+ import com .amazonaws .SDKGlobalConfiguration ;
2628import com .amazonaws .mobileconnectors .cognitoidentityprovider .continuations .AuthenticationContinuation ;
2729import com .amazonaws .mobileconnectors .cognitoidentityprovider .continuations .AuthenticationDetails ;
2830import com .amazonaws .mobileconnectors .cognitoidentityprovider .continuations .ForgotPasswordContinuation ;
102104 */
103105public class CognitoUser {
104106 private final String TAG = "CognitoUser" ;
107+ /** Default threshold for refreshing session credentials */
108+ public static final int DEFAULT_THRESHOLD_SECONDS = 500 ;
105109
106110 /**
107111 * Application context.
@@ -619,6 +623,24 @@ public void getSession(final AuthenticationHandler callback) {
619623 }
620624 }
621625
626+ /**
627+ * Returns true if a new session needs to be started. A new session
628+ * is needed when no session has been started yet, or if the last session is
629+ * within the configured refresh threshold.
630+ *
631+ * @return True if a new session needs to be started.
632+ */
633+ private boolean needsNewSession (CognitoUserSession userSession ) {
634+ if (userSession == null ) {
635+ return true ;
636+ }
637+ long currentTime = System .currentTimeMillis ()
638+ - SDKGlobalConfiguration .getGlobalTimeOffset () * 1000 ;
639+ long timeRemaining = userSession .getIdToken ().getExpiration ().getTime ()
640+ - currentTime ;
641+ return timeRemaining < (DEFAULT_THRESHOLD_SECONDS * 1000 );
642+ }
643+
622644 /**
623645 * Call this method for valid, cached tokens for this user.
624646 *
@@ -629,33 +651,36 @@ private CognitoUserSession getCachedSession() {
629651 throw new CognitoNotAuthorizedException ("User-ID is null" );
630652 }
631653
632- if (cipSession != null ) {
633- if (cipSession .isValid ()) {
634- return cipSession ;
635- }
654+ if (!needsNewSession (cipSession )) {
655+ return cipSession ;
636656 }
637657
638658 // Read cached tokens
639659 CognitoUserSession cachedTokens = readCachedTokens ();
640660
641- // Return cached tokens if they are still valid
642- if (cachedTokens . isValid ( )) {
661+ // Return cached tokens if they are still valid with some margin
662+ if (! needsNewSession ( cachedTokens )) {
643663 cipSession = cachedTokens ;
644- return cipSession ;
664+ return cipSession ;
645665 }
646666
647- // Clear any cached tokens, since none of them are valid.
648- clearCachedTokens ();
649-
650667 if (cachedTokens .getRefreshToken () != null ) {
651668 // Use Refresh token to get new tokens
652669 try {
653670 cipSession = refreshSessionInternal (cachedTokens .getRefreshToken ());
654671 cacheTokens (cipSession );
655672 return cipSession ;
656- } catch (Exception e ) {
673+ } catch (CognitoNotAuthorizedException e ) {
674+ // Clear any cached tokens, since none of them are valid.
675+ clearCachedTokens ();
657676 // Could not get new tokens from refresh. Should authenticate user.
658- throw new CognitoNotAuthorizedException ("user is not authenticated" );
677+ throw new CognitoNotAuthorizedException ("user is not authenticated" ,e );
678+ } catch (AmazonClientException e ) {
679+ // General IO errors - not clearing cached tokens
680+ throw new AmazonClientException ("failed to get new tokens from refresh" ,e );
681+ } catch (Exception e ) {
682+ // Errors like NetworkOnMainThreadException etc - not clearing cached tokens.
683+ throw new AmazonClientException ("failed to get new tokens from refresh" ,e );
659684 }
660685 }
661686 throw new CognitoNotAuthorizedException ("user is not authenticated" );
@@ -2018,7 +2043,7 @@ private CognitoUserSession refreshSessionInternal(CognitoRefreshToken refreshTok
20182043 cognitoIdentityProviderClient .refreshTokens (refreshTokensRequest );
20192044 AuthenticationResultType authenticationResult = refreshTokensResult .getAuthenticationResult ();
20202045
2021- if (authenticationResult ! = null ) {
2046+ if (authenticationResult = = null ) {
20222047 throw new CognitoNotAuthorizedException ("user is not authenticated" );
20232048 }
20242049
0 commit comments