Repository: auth0/auth0.android
Issue: NPE in com.auth0.android.authentication.storage.CredentialsManager

### Description

> NullPointerException inside com.auth0.android.authentication.storage.CredentialsManager

### Reproduction
Reproduced in user on fabric.
> Details of crash:
```
Non-fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'long java.lang.Long.longValue()' on a null object reference
       at com.auth0.android.authentication.storage.CredentialsManager.getCredentials + 101(CredentialsManager.java:101)
       at com.android.test.app.auth.MoreScreenFragment.onViewCreated + 113(MoreScreenFragment.java:113)
       at androidx.fragment.app.FragmentManagerImpl.moveToState + 892(FragmentManagerImpl.java:892)
       at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState + 1238(FragmentManagerImpl.java:1238)
       at androidx.fragment.app.FragmentManagerImpl.moveToState + 1303(FragmentManagerImpl.java:1303)
       at androidx.fragment.app.BackStackRecord.executeOps + 439(BackStackRecord.java:439)
       at androidx.fragment.app.FragmentManagerImpl.executeOps + 2079(FragmentManagerImpl.java:2079)
       at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether + 1869(FragmentManagerImpl.java:1869)
       at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute + 1824(FragmentManagerImpl.java:1824)
       at androidx.fragment.app.FragmentManagerImpl.execPendingActions + 1727(FragmentManagerImpl.java:1727)
       at androidx.fragment.app.FragmentManagerImpl$2.run + 150(FragmentManagerImpl.java:150)
       at android.os.Handler.handleCallback + 883(Handler.java:883)
       at android.os.Handler.dispatchMessage + 100(Handler.java:100)
       at android.os.Looper.loop + 214(Looper.java:214)
       at android.app.ActivityThread.main + 7356(ActivityThread.java:7356)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run + 492(RuntimeInit.java:492)
       at com.android.internal.os.ZygoteInit.main + 930(ZygoteInit.java:930)
```

### Environment

> Please provide the following:

- Version of library : implementation 'com.auth0.android:auth0:1.19.0'
- Android OS Version: 10
- Device: Pixel 3a XL

### Suggestion
Looks like you should just add null safe condition [here](https://github.com/auth0/Auth0.Android/blob/master/auth0/src/main/java/com/auth0/android/authentication/storage/CredentialsManager.java#L101):
```
if (cacheExpiresAt != null && cacheExpiresAt > getCurrentTimeInMillis()) {
    callback.onSuccess(recreateCredentials(idToken, accessToken, tokenType, refreshToken, new Date(expiresAt), scope));
    return;
}
```

Changed files:
auth0/src/test/java/com/auth0/android/authentication/storage/CredentialsManagerTest.java
auth0/src/main/java/com/auth0/android/authentication/storage/CredentialsManager.java

diff --git a/auth0/src/main/java/com/auth0/android/authentication/storage/CredentialsManager.java b/auth0/src/main/java/com/auth0/android/authentication/storage/CredentialsManager.java
index 2594e03..17840fc 100644
--- a/auth0/src/main/java/com/auth0/android/authentication/storage/CredentialsManager.java
+++ b/auth0/src/main/java/com/auth0/android/authentication/storage/CredentialsManager.java
@@ -93,6 +93,9 @@ public class CredentialsManager {
         Long expiresAt = storage.retrieveLong(KEY_EXPIRES_AT);
         String scope = storage.retrieveString(KEY_SCOPE);
         Long cacheExpiresAt = storage.retrieveLong(KEY_CACHE_EXPIRES_AT);
+        if (cacheExpiresAt == null) {
+            cacheExpiresAt = expiresAt;
+        }
 
         if (isEmpty(accessToken) && isEmpty(idToken) || expiresAt == null) {
             callback.onFailure(new CredentialsManagerException("No Credentials were previously set."));
diff --git a/auth0/src/test/java/com/auth0/android/authentication/storage/CredentialsManagerTest.java b/auth0/src/test/java/com/auth0/android/authentication/storage/CredentialsManagerTest.java
index 2db4b40..0d9f037 100644
--- a/auth0/src/test/java/com/auth0/android/authentication/storage/CredentialsManagerTest.java
+++ b/auth0/src/test/java/com/auth0/android/authentication/storage/CredentialsManagerTest.java
@@ -116,7 +116,7 @@ public class CredentialsManagerTest {
         prepareJwtDecoderMock(new Date(accessTokenExpirationTime));
         manager.saveCredentials(credentials);
 
-        verify(storage).store("com.auth0.id_token", (String)null);
+        verify(storage).store("com.auth0.id_token", (String) null);
         verify(storage).store("com.auth0.access_token", "accessToken");
         verify(storage).store("com.auth0.refresh_token", "refreshToken");
         verify(storage).store("com.auth0.token_type", "type");
@@ -235,6 +235,25 @@ public class CredentialsManagerTest {
         assertThat(exception.getMessage(), is("Credentials have expired and no Refresh Token was available to renew them."));
     }
 
+    @Test
+    public void shouldNotFailOnGetCredentialsWhenCacheExpiresAtNotSetButExpiresAtIsPresent() {
+        verifyNoMoreInteractions(client);
+
+        when(storage.retrieveString("com.auth0.id_token")).thenReturn("idToken");
+        when(storage.retrieveString("com.auth0.access_token")).thenReturn("accessToken");
+        when(storage.retrieveString("com.auth0.token_type")).thenReturn("type");
+        long expirationTime = CredentialsMock.CURRENT_TIME_MS + 123456L * 1000;
+        when(storage.retrieveLong("com.auth0.expires_at")).thenReturn(expirationTime);
+        when(storage.retrieveLong("com.auth0.cache_expires_at")).thenReturn(null);
+        when(storage.retrieveString("com.auth0.scope")).thenReturn("scope");
+
+        manager.getCredentials(callback);
+
+        verify(callback).onSuccess(credentialsCaptor.capture());
+        Credentials retrievedCredentials = credentialsCaptor.getValue();
+        assertThat(retrievedCredentials, is(notNullValue()));
+    }
+
     @Test
     public void shouldGetNonExpiredCredentialsFromStorage() {
         verifyNoMoreInteractions(client);