Repository: auth0/auth0-spa-js
Pull request #233 (2019-10-03 13:45:52)

Add early expiration of Access Token in cache
### Description

Hello, 

**Problem:** In my case the access token provided by Auth0 is valid for 30 seconds and from time to time I would have 401 when trying to call the resource server.

![image](https://user-images.githubusercontent.com/895123/66131982-a389aa80-e5f4-11e9-9bee-a5d9126e1195.png)

**Proprosed solution:** this PR expires the access token 5 seconds before it really expires so that we can be more sure 
the access token used against the resource server is not expired by the time it reaches it.

Let me know what you think.



### Testing

- [ ] This change adds test coverage for new/changed/fixed functionality

### Checklist

- [ ] I have added documentation for new/changed functionality in this PR or in auth0.com/docs
- [ ] All active GitHub checks for tests, formatting, and security are passing
- [ ] The correct base branch is being used, if not `master`



luisrudge: @B-Galati thanks for the PR. Can you clarify how are you using the `getTokenSilently` method? Are you calling it *right before* doing the API call? Or are you storing the token somewhere else etc? 

Regarding your PR, 5s is not the best solution. If we decide to move forward with this, I think we need to use a percentage based approach. Something like `Math.min(expiresIn, expTime) * 1000 * 0.8;`, so when it gets to 80% of the expiration time. Can yo please do this change and write a test? Thanks!
B-Galati: @luisrudge Good idea! PR updated along with tests.

>Can you clarify how are you using the getTokenSilently method? Are you calling it right before doing the API call? Or are you storing the token somewhere else etc?

That's exactly it, calling it right before doing the API call using the cache strategy provided by the library.


luisrudge: Thank you so much for this PR!

Patch:
diff --git a/src/cache.ts b/src/cache.ts
index 9572221..337e772 100644
--- a/src/cache.ts
+++ b/src/cache.ts
@@ -24,7 +24,7 @@ const createKey = (e: CacheKeyData) => `${e.audience}::${e.scope}`;
 const getExpirationTimeoutInMilliseconds = (expiresIn: number, exp: number) => {
   const expTime =
     (new Date(exp * 1000).getTime() - new Date().getTime()) / 1000;
-  return Math.min(expiresIn, expTime) * 1000;
+  return Math.min(expiresIn, expTime) * 1000 * 0.8;
 };
 
 export default class Cache {


Test patch:
diff --git a/__tests__/cache.test.ts b/__tests__/cache.test.ts
index e0b5d5b..7948100 100644
--- a/__tests__/cache.test.ts
+++ b/__tests__/cache.test.ts
@@ -54,7 +54,9 @@ describe('cache', () => {
         user: { name: 'Test' }
       }
     });
-    jest.advanceTimersByTime(1001);
+    jest.advanceTimersByTime(799);
+    expect(Object.keys(cache.cache).length).toBe(1);
+    jest.advanceTimersByTime(1);
     expect(Object.keys(cache.cache).length).toBe(0);
   });
   it('expires after `user.exp` when `user.exp` < `expires_in`', () => {
@@ -73,7 +75,9 @@ describe('cache', () => {
         user: { name: 'Test' }
       }
     });
-    jest.advanceTimersByTime(1001);
+    jest.advanceTimersByTime(799);
+    expect(Object.keys(cache.cache).length).toBe(1);
+    jest.advanceTimersByTime(1);
     expect(Object.keys(cache.cache).length).toBe(0);
   });
 });