From 5a5b3233820df9536da75e87ce6184a983d4713a Mon Sep 17 00:00:00 2001 From: Igor Monadical Date: Mon, 8 Sep 2025 10:40:18 -0400 Subject: [PATCH] fix: sync backend and frontend token refresh logic (#614) * sync backend and frontend token refresh logic * return react strict mode --------- Co-authored-by: Igor Loskutov --- www/app/lib/SessionAutoRefresh.tsx | 7 ++----- www/app/lib/auth.ts | 5 +++++ www/app/lib/authBackend.ts | 11 ++++++++--- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/www/app/lib/SessionAutoRefresh.tsx b/www/app/lib/SessionAutoRefresh.tsx index 3729db8c..6b26077d 100644 --- a/www/app/lib/SessionAutoRefresh.tsx +++ b/www/app/lib/SessionAutoRefresh.tsx @@ -9,9 +9,7 @@ import { useEffect } from "react"; import { useAuth } from "./AuthProvider"; -import { REFRESH_ACCESS_TOKEN_BEFORE } from "./auth"; - -const REFRESH_BEFORE = REFRESH_ACCESS_TOKEN_BEFORE; +import { shouldRefreshToken } from "./auth"; export function SessionAutoRefresh({ children }) { const auth = useAuth(); @@ -25,8 +23,7 @@ export function SessionAutoRefresh({ children }) { const INTERVAL_REFRESH_MS = 5000; const interval = setInterval(() => { if (accessTokenExpires === null) return; - const timeLeft = accessTokenExpires - Date.now(); - if (timeLeft < REFRESH_BEFORE) { + if (shouldRefreshToken(accessTokenExpires)) { auth .update() .then(() => {}) diff --git a/www/app/lib/auth.ts b/www/app/lib/auth.ts index f6e60513..c83db264 100644 --- a/www/app/lib/auth.ts +++ b/www/app/lib/auth.ts @@ -2,6 +2,11 @@ export const REFRESH_ACCESS_TOKEN_ERROR = "RefreshAccessTokenError" as const; // 4 min is 1 min less than default authentic value. here we assume that authentic won't be set to access tokens < 4 min export const REFRESH_ACCESS_TOKEN_BEFORE = 4 * 60 * 1000; +export const shouldRefreshToken = (accessTokenExpires: number): boolean => { + const timeLeft = accessTokenExpires - Date.now(); + return timeLeft < REFRESH_ACCESS_TOKEN_BEFORE; +}; + export const LOGIN_REQUIRED_PAGES = [ "/transcripts/[!new]", "/browse(.*)", diff --git a/www/app/lib/authBackend.ts b/www/app/lib/authBackend.ts index 0b48f613..06bddff2 100644 --- a/www/app/lib/authBackend.ts +++ b/www/app/lib/authBackend.ts @@ -10,6 +10,7 @@ import { import { REFRESH_ACCESS_TOKEN_BEFORE, REFRESH_ACCESS_TOKEN_ERROR, + shouldRefreshToken, } from "./auth"; import { getTokenCache, @@ -85,9 +86,13 @@ export const authOptions: AuthOptions = { "currentToken from cache", JSON.stringify(currentToken, null, 2), "will be returned?", - currentToken && Date.now() < currentToken.token.accessTokenExpires, + currentToken && + !shouldRefreshToken(currentToken.token.accessTokenExpires), ); - if (currentToken && Date.now() < currentToken.token.accessTokenExpires) { + if ( + currentToken && + !shouldRefreshToken(currentToken.token.accessTokenExpires) + ) { return currentToken.token; } @@ -128,7 +133,7 @@ async function lockedRefreshAccessToken( if (cached) { if (Date.now() - cached.timestamp > TOKEN_CACHE_TTL) { await deleteTokenCache(tokenCacheRedis, `token:${token.sub}`); - } else if (Date.now() < cached.token.accessTokenExpires) { + } else if (!shouldRefreshToken(cached.token.accessTokenExpires)) { console.debug("returning cached token", cached.token); return cached.token; }