mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-19 09:50:15 +01:00
feat: Refresh Token for improved Session Security (#927)
* feat(api): refresh token logic * feat(client): refresh token logic * feat(data-provider): refresh token logic * fix: SSE uses esm * chore: add default refresh token expiry to AuthService, add message about env var not set when generating a token * chore: update scripts to more compatible bun methods, ran bun install again * chore: update env.example and playwright workflow with JWT_REFRESH_SECRET * chore: update breaking changes docs * chore: add timeout to url visit * chore: add default SESSION_EXPIRY in generateToken logic, add act script for testing github actions * fix(e2e): refresh automatically in development environment to pass e2e tests
This commit is contained in:
parent
75be9a3279
commit
33f087d38f
31 changed files with 420 additions and 232 deletions
|
|
@ -107,12 +107,7 @@ const AuthContextProvider = ({
|
|||
});
|
||||
};
|
||||
|
||||
const logout = () => {
|
||||
document.cookie.split(';').forEach((c) => {
|
||||
document.cookie = c
|
||||
.replace(/^ +/, '')
|
||||
.replace(/=.*/, '=;expires=' + new Date().toUTCString() + ';path=/');
|
||||
});
|
||||
const logout = useCallback(() => {
|
||||
logoutUser.mutate(undefined, {
|
||||
onSuccess: () => {
|
||||
setUserContext({
|
||||
|
|
@ -126,7 +121,25 @@ const AuthContextProvider = ({
|
|||
doSetError((error as Error).message);
|
||||
},
|
||||
});
|
||||
};
|
||||
}, [setUserContext, logoutUser]);
|
||||
|
||||
const silentRefresh = useCallback(() => {
|
||||
refreshToken.mutate(undefined, {
|
||||
onSuccess: (data: TLoginResponse) => {
|
||||
const { user, token } = data;
|
||||
if (token) {
|
||||
setUserContext({ token, isAuthenticated: true, user });
|
||||
} else {
|
||||
console.log('Token is not present. User is not authenticated.');
|
||||
navigate('/login');
|
||||
}
|
||||
},
|
||||
onError: (error) => {
|
||||
console.log('refreshToken mutation error:', error);
|
||||
navigate('/login');
|
||||
},
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (userQuery.data) {
|
||||
|
|
@ -139,12 +152,7 @@ const AuthContextProvider = ({
|
|||
doSetError(undefined);
|
||||
}
|
||||
if (!token || !isAuthenticated) {
|
||||
const tokenFromCookie = getCookieValue('token');
|
||||
if (tokenFromCookie) {
|
||||
setUserContext({ token: tokenFromCookie, isAuthenticated: true, user: userQuery.data });
|
||||
} else {
|
||||
navigate('/login', { replace: true });
|
||||
}
|
||||
silentRefresh();
|
||||
}
|
||||
}, [
|
||||
token,
|
||||
|
|
@ -157,23 +165,23 @@ const AuthContextProvider = ({
|
|||
setUserContext,
|
||||
]);
|
||||
|
||||
// const silentRefresh = useCallback(() => {
|
||||
// refreshToken.mutate(undefined, {
|
||||
// onSuccess: (data: TLoginResponse) => {
|
||||
// const { user, token } = data;
|
||||
// setUserContext({ token, isAuthenticated: true, user });
|
||||
// },
|
||||
// onError: error => {
|
||||
// setError(error.message);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// }, [setUserContext]);
|
||||
useEffect(() => {
|
||||
const handleTokenUpdate = (event) => {
|
||||
console.log('tokenUpdated event received event');
|
||||
const newToken = event.detail;
|
||||
setUserContext({
|
||||
token: newToken,
|
||||
isAuthenticated: true,
|
||||
user: user,
|
||||
});
|
||||
};
|
||||
|
||||
// useEffect(() => {
|
||||
// if (token)
|
||||
// silentRefresh();
|
||||
// }, [token, silentRefresh]);
|
||||
window.addEventListener('tokenUpdated', handleTokenUpdate);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('tokenUpdated', handleTokenUpdate);
|
||||
};
|
||||
}, [setUserContext, user]);
|
||||
|
||||
// Make the provider update only when it should
|
||||
const memoedValue = useMemo(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue