|
1 | | -import { AuthenticationInfo, fetchAuthenticationInfo, logout } from "./api" |
2 | | -import { currentTimeSeconds, getLocalStorageNumber, hasLocalStorage, hasWindow } from "./helpers" |
| 1 | +import {AuthenticationInfo, fetchAuthenticationInfo, logout} from "./api" |
| 2 | +import {currentTimeSeconds, getLocalStorageNumber, hasLocalStorage, hasWindow} from "./helpers" |
3 | 3 |
|
4 | 4 | const LOGGED_IN_AT_KEY = "__PROPEL_AUTH_LOGGED_IN_AT" |
5 | 5 | const LOGGED_OUT_AT_KEY = "__PROPEL_AUTH_LOGGED_OUT_AT" |
6 | | -const STALE_AUTH_INFO_THRESHOLD_SECS = 4 * 60 |
| 6 | +const AUTH_TOKEN_REFRESH_BEFORE_EXPIRATION_SECONDS = 4 * 60 |
| 7 | +const DEBOUNCE_DURATION_FOR_REFOCUS_SECONDS = 4 * 60 |
7 | 8 |
|
8 | 9 | export interface IAuthClient { |
9 | 10 | /** |
@@ -88,6 +89,7 @@ interface ClientState { |
88 | 89 | lastLoggedInAtMessage: number | null |
89 | 90 | lastLoggedOutAtMessage: number | null |
90 | 91 | refreshInterval: number | null |
| 92 | + lastRefresh: number | null |
91 | 93 | readonly authUrl: string |
92 | 94 | } |
93 | 95 |
|
@@ -118,6 +120,7 @@ export function createClient(authOptions: IAuthOptions): IAuthClient { |
118 | 120 | lastLoggedOutAtMessage: getLocalStorageNumber(LOGGED_OUT_AT_KEY), |
119 | 121 | authUrl: authOptions.authUrl, |
120 | 122 | refreshInterval: null, |
| 123 | + lastRefresh: null, |
121 | 124 | } |
122 | 125 |
|
123 | 126 | // Helper functions |
@@ -165,6 +168,7 @@ export function createClient(authOptions: IAuthOptions): IAuthClient { |
165 | 168 | updateLastLoggedInAt() |
166 | 169 | } |
167 | 170 |
|
| 171 | + clientState.lastRefresh = currentTimeSeconds() |
168 | 172 | clientState.initialLoadFinished = true |
169 | 173 | } |
170 | 174 |
|
@@ -214,7 +218,7 @@ export function createClient(authOptions: IAuthOptions): IAuthClient { |
214 | 218 | } else if (!clientState.authenticationInfo) { |
215 | 219 | return await forceRefreshToken(false) |
216 | 220 | } else if ( |
217 | | - currentTimeSecs + STALE_AUTH_INFO_THRESHOLD_SECS > |
| 221 | + currentTimeSecs + AUTH_TOKEN_REFRESH_BEFORE_EXPIRATION_SECONDS > |
218 | 222 | clientState.authenticationInfo.expiresAtSeconds |
219 | 223 | ) { |
220 | 224 | // Small edge case: If we were being proactive |
@@ -295,8 +299,13 @@ export function createClient(authOptions: IAuthOptions): IAuthClient { |
295 | 299 | } |
296 | 300 |
|
297 | 301 | // If we were offline or on a different tab, when we return, refetch auth info |
| 302 | + // Some browsers trigger focus more often than we'd like, so we'll debounce a little here as well |
298 | 303 | const onOnlineOrFocus = async function () { |
299 | | - await forceRefreshToken(true) |
| 304 | + if (clientState.lastRefresh && currentTimeSeconds() > clientState.lastRefresh + DEBOUNCE_DURATION_FOR_REFOCUS_SECONDS) { |
| 305 | + await forceRefreshToken(true) |
| 306 | + } else { |
| 307 | + await client.getAuthenticationInfoOrNull() |
| 308 | + } |
300 | 309 | } |
301 | 310 |
|
302 | 311 | if (hasWindow()) { |
|
0 commit comments