From 45e4e70986d9678ea685b44ddf123f0398171541 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Sun, 25 May 2025 16:32:29 -0400 Subject: [PATCH] =?UTF-8?q?=E2=8C=9A=20refactor:=20debounce=20setUserConte?= =?UTF-8?q?xt=20to=20avoid=20race=20condition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/hooks/AuthContext.tsx | 51 ++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/client/src/hooks/AuthContext.tsx b/client/src/hooks/AuthContext.tsx index e21d19ebf1..d9d583783a 100644 --- a/client/src/hooks/AuthContext.tsx +++ b/client/src/hooks/AuthContext.tsx @@ -1,4 +1,5 @@ import { + useRef, useMemo, useState, useEffect, @@ -6,10 +7,10 @@ import { useContext, useCallback, createContext, - useRef, } from 'react'; -import { useNavigate } from 'react-router-dom'; +import { debounce } from 'lodash'; import { useRecoilState } from 'recoil'; +import { useNavigate } from 'react-router-dom'; import { setTokenHeader, SystemRoles } from 'librechat-data-provider'; import type * as t from 'librechat-data-provider'; import { @@ -47,27 +48,31 @@ const AuthContextProvider = ({ const navigate = useNavigate(); - const setUserContext = useCallback( - (userContext: TUserContext) => { - const { token, isAuthenticated, user, redirect } = userContext; - setUser(user); - setToken(token); - //@ts-ignore - ok for token to be undefined initially - setTokenHeader(token); - setIsAuthenticated(isAuthenticated); - // Use a custom redirect if set - const finalRedirect = logoutRedirectRef.current || redirect; - // Clear the stored redirect - logoutRedirectRef.current = undefined; - if (finalRedirect == null) { - return; - } - if (finalRedirect.startsWith('http://') || finalRedirect.startsWith('https://')) { - window.location.href = finalRedirect; - } else { - navigate(finalRedirect, { replace: true }); - } - }, + const setUserContext = useMemo( + () => + debounce((userContext: TUserContext) => { + const { token, isAuthenticated, user, redirect } = userContext; + setUser(user); + setToken(token); + //@ts-ignore - ok for token to be undefined initially + setTokenHeader(token); + setIsAuthenticated(isAuthenticated); + + // Use a custom redirect if set + const finalRedirect = logoutRedirectRef.current || redirect; + // Clear the stored redirect + logoutRedirectRef.current = undefined; + + if (finalRedirect == null) { + return; + } + + if (finalRedirect.startsWith('http://') || finalRedirect.startsWith('https://')) { + window.location.href = finalRedirect; + } else { + navigate(finalRedirect, { replace: true }); + } + }, 50), [navigate, setUser], ); const doSetError = useTimeout({ callback: (error) => setError(error as string | undefined) });