diff --git a/apps/Frontend/src/hooks/use-auth.tsx b/apps/Frontend/src/hooks/use-auth.tsx index 46f1d72d..3839cce2 100755 --- a/apps/Frontend/src/hooks/use-auth.tsx +++ b/apps/Frontend/src/hooks/use-auth.tsx @@ -1,4 +1,4 @@ -import { createContext, ReactNode, useContext } from "react"; +import { createContext, ReactNode, useContext, useEffect, useRef } from "react"; import { useQuery, useMutation, @@ -131,6 +131,51 @@ export function AuthProvider({ children }: { children: ReactNode }) { }, }); + const IDLE_TIMEOUT = 60 * 60 * 1000; + const WARN_BEFORE = 5 * 60 * 1000; + + const logoutTimer = useRef | null>(null); + const warnTimer = useRef | null>(null); + const warnedRef = useRef(false); + + useEffect(() => { + if (!user) return; + + const clearTimers = () => { + if (logoutTimer.current) clearTimeout(logoutTimer.current); + if (warnTimer.current) clearTimeout(warnTimer.current); + }; + + const resetTimers = () => { + clearTimers(); + warnedRef.current = false; + + warnTimer.current = setTimeout(() => { + if (!warnedRef.current) { + warnedRef.current = true; + toast({ + title: "Session expiring soon", + description: "You will be logged out in 5 minutes due to inactivity.", + duration: 10000, + }); + } + }, IDLE_TIMEOUT - WARN_BEFORE); + + logoutTimer.current = setTimeout(() => { + logoutMutation.mutate(); + }, IDLE_TIMEOUT); + }; + + const events = ["mousemove", "mousedown", "keydown", "scroll", "touchstart", "click"]; + events.forEach((e) => window.addEventListener(e, resetTimers, { passive: true })); + resetTimers(); + + return () => { + clearTimers(); + events.forEach((e) => window.removeEventListener(e, resetTimers)); + }; + }, [user]); + return (