Index: backend/scripts/toggleModeratorStatus.js
===================================================================
--- backend/scripts/toggleModeratorStatus.js	(revision 25605436e464c2bbfdacaf77b357293891b4d63a)
+++ backend/scripts/toggleModeratorStatus.js	(revision 30df7efd842910e0c8c99d20770ebc37c873cee6)
@@ -1,27 +1,12 @@
-const { createClient } = require('@supabase/supabase-js');
-const path = require('path');
-
-require('dotenv').config({ path: path.join(__dirname, '..', '.env') });
-
-console.log(
-  'SUPABASE_URL:',
-  process.env.SUPABASE_URL ? 'Loaded' : 'Not loaded'
-);
-console.log(
-  'SERVICE_ROLE_KEY:',
-  process.env.SUPABASE_SERVICE_ROLE_KEY ? 'Loaded' : 'Not loaded'
-);
-
-const supabase = createClient(
-  process.env.SUPABASE_URL,
-  process.env.SUPABASE_SERVICE_ROLE_KEY
-);
+const { createClient } = require("@supabase/supabase-js");
+const path = require("path");
+const { supabase } = require("../supabaseClient");
 
 async function toggleModeratorStatus(userId) {
   try {
     const { data: user, error: fetchError } = await supabase
-      .from('users')
-      .select('isModerator, username')
-      .eq('id', userId)
+      .from("users")
+      .select("isModerator, username")
+      .eq("id", userId)
       .single();
 
@@ -33,8 +18,8 @@
 
     const { data: updatedUser, error: updateError } = await supabase
-      .from('users')
+      .from("users")
       .update({ isModerator: !user.isModerator })
-      .eq('id', userId)
-      .select('username')
+      .eq("id", userId)
+      .select("username")
       .single();
 
@@ -45,5 +30,5 @@
     );
   } catch (error) {
-    console.error('Error:', error);
+    console.error("Error:", error);
   }
 }
@@ -51,5 +36,5 @@
 const userId = process.argv[2];
 if (!userId) {
-  console.error('Please provide a user ID');
+  console.error("Please provide a user ID");
   process.exit(1);
 }
Index: backend/supabase/functions/leaderboard/index.ts
===================================================================
--- backend/supabase/functions/leaderboard/index.ts	(revision 25605436e464c2bbfdacaf77b357293891b4d63a)
+++ backend/supabase/functions/leaderboard/index.ts	(revision 30df7efd842910e0c8c99d20770ebc37c873cee6)
@@ -1,6 +1,6 @@
 // Supabase Edge Function - leaderboard.ts
-import { serve } from 'https://deno.land/std/http/server.ts';
-import { createClient } from 'https://esm.sh/@supabase/supabase-js';
-
+import { serve } from "https://deno.land/std/http/server.ts";
+import { createClient } from "https://esm.sh/@supabase/supabase-js";
+import supabase from "../../../supabaseClient";
 // Cache constants
 const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes
@@ -15,11 +15,11 @@
 serve(async (req: Request): Promise<Response> => {
   // Handle CORS preflight
-  if (req.method === 'OPTIONS') {
+  if (req.method === "OPTIONS") {
     return new Response(null, {
       status: 200,
       headers: {
-        'Access-Control-Allow-Origin': '*',
-        'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
-        'Access-Control-Allow-Headers': 'Content-Type, Authorization',
+        "Access-Control-Allow-Origin": "*",
+        "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
+        "Access-Control-Allow-Headers": "Content-Type, Authorization",
       },
     });
@@ -28,7 +28,7 @@
   try {
     const url = new URL(req.url);
-    const page = parseInt(url.searchParams.get('page') || '1');
+    const page = parseInt(url.searchParams.get("page") || "1");
     const limit = parseInt(
-      url.searchParams.get('limit') || PAGE_SIZE.toString()
+      url.searchParams.get("limit") || PAGE_SIZE.toString()
     );
 
@@ -36,12 +36,12 @@
       return new Response(
         JSON.stringify({
-          error: 'Invalid parameters',
-          message: 'Page must be >= 1 and limit must be between 1 and 100',
+          error: "Invalid parameters",
+          message: "Page must be >= 1 and limit must be between 1 and 100",
         }),
         {
           status: 400,
           headers: {
-            'Content-Type': 'application/json',
-            'Access-Control-Allow-Origin': '*',
+            "Content-Type": "application/json",
+            "Access-Control-Allow-Origin": "*",
           },
         }
@@ -68,7 +68,7 @@
           status: 200,
           headers: {
-            'Content-Type': 'application/json',
-            'Access-Control-Allow-Origin': '*',
-            'Cache-Control': 'max-age=300', // Allow browser caching for 5 minutes
+            "Content-Type": "application/json",
+            "Access-Control-Allow-Origin": "*",
+            "Cache-Control": "max-age=300", // Allow browser caching for 5 minutes
           },
         }
@@ -77,19 +77,19 @@
 
     // Load env variables
-    const supabaseUrl = Deno.env.get('SUPABASE_URL');
-    const supabaseServiceKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY');
+    // const supabaseUrl = Deno.env.get('SUPABASE_URL');
+    // const supabaseServiceKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY');
 
-    if (!supabaseUrl || !supabaseServiceKey) {
-      throw new Error('Missing Supabase env variables');
-    }
+    // if (!supabaseUrl || !supabaseServiceKey) {
+    //   throw new Error('Missing Supabase env variables');
+    // }
 
-    const supabase = createClient(supabaseUrl, supabaseServiceKey);
+    // const supabase = createClient(supabaseUrl, supabaseServiceKey);
 
     // Pagination
     const offset = (page - 1) * limit;
     const { data, error, count } = await supabase
-      .from('users')
-      .select('id, username, points, rank', { count: 'exact' })
-      .order('points', { ascending: false })
+      .from("users")
+      .select("id, username, points, rank", { count: "exact" })
+      .order("points", { ascending: false })
       .range(offset, offset + limit - 1);
 
@@ -131,14 +131,14 @@
       status: 200,
       headers: {
-        'Content-Type': 'application/json',
-        'Access-Control-Allow-Origin': '*',
-        'Cache-Control': 'max-age=300', // Allow browser caching
+        "Content-Type": "application/json",
+        "Access-Control-Allow-Origin": "*",
+        "Cache-Control": "max-age=300", // Allow browser caching
       },
     });
   } catch (err: any) {
-    console.error('Leaderboard error:', err.message);
+    console.error("Leaderboard error:", err.message);
     return new Response(
       JSON.stringify({
-        error: 'Failed to fetch leaderboard',
+        error: "Failed to fetch leaderboard",
         message: err.message,
       }),
@@ -146,6 +146,6 @@
         status: 500,
         headers: {
-          'Content-Type': 'application/json',
-          'Access-Control-Allow-Origin': '*',
+          "Content-Type": "application/json",
+          "Access-Control-Allow-Origin": "*",
         },
       }
Index: client/src/contexts/AuthContext.jsx
===================================================================
--- client/src/contexts/AuthContext.jsx	(revision 25605436e464c2bbfdacaf77b357293891b4d63a)
+++ client/src/contexts/AuthContext.jsx	(revision 30df7efd842910e0c8c99d20770ebc37c873cee6)
@@ -22,6 +22,20 @@
 });
 
+function parseJwt(token) {
+  try {
+    const base64Url = token.split(".")[1];
+    const base64 = decodeURIComponent(
+      atob(base64Url)
+        .split("")
+        .map((c) => "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2))
+        .join("")
+    );
+    return JSON.parse(base64);
+  } catch (e) {
+    return null;
+  }
+}
+
 export const AuthContext = createContext();
-
 export const useAuth = () => useContext(AuthContext);
 
@@ -30,104 +44,63 @@
   const [loading, setLoading] = useState(true);
   const [isLoggingOut, setIsLoggingOut] = useState(false);
-  // Use refs for mutable values that shouldn't trigger re-renders
   const inactivityTimeoutRef = useRef(null);
+  const tokenExpiryTimeoutRef = useRef(null);
   const isActiveRef = useRef(false);
-  const userRef = useRef(null); // Store user ID in ref to avoid dependency cycle
+  const userRef = useRef(null);
   const navigate = useNavigate();
 
-  // 2 minutes timeout (in milliseconds)
-  const INACTIVITY_TIMEOUT = 7 * 60 * 1000;
-
-  // Update userRef when user changes
+  const INACTIVITY_TIMEOUT = 120 * 60 * 1000;
+
   useEffect(() => {
     userRef.current = user?.id || null;
-
-    // Debug log only once when user changes
-    if (import.meta.env.DEV && user) {
-      console.log(
-        `Inactivity timeout set for ${INACTIVITY_TIMEOUT / 1000} seconds`
-      );
-    }
-  }, [user, INACTIVITY_TIMEOUT]);
-
-  // Function to logout - using userRef instead of user state
+  }, [user]);
+
   const logout = useCallback(async () => {
     try {
-      console.log(
-        "Logging out user due to:",
-        isActiveRef.current ? "manual logout" : "inactivity"
-      );
       setIsLoggingOut(true);
 
-      // Clear the timeout to prevent duplicate logouts
+      // Clear both timers
       if (inactivityTimeoutRef.current) {
         clearTimeout(inactivityTimeoutRef.current);
         inactivityTimeoutRef.current = null;
       }
-
-      // Remove data first to prevent race conditions
+      if (tokenExpiryTimeoutRef.current) {
+        clearTimeout(tokenExpiryTimeoutRef.current);
+        tokenExpiryTimeoutRef.current = null;
+      }
+
+      localStorage.removeItem("lastActivityTimestamp");
       localStorage.removeItem("jwt");
+      localStorage.removeItem("token_exp");
       localStorage.removeItem("user");
-      localStorage.removeItem("lastActivityTimestamp");
-
-      // Call signOut only once
+
       await supabase.auth.signOut();
-
-      // Update state
       setUser(null);
       userRef.current = null;
-
-      // Navigate to home page
       navigate("/");
 
-      // Reset logout flag after navigation
-      setTimeout(() => {
-        setIsLoggingOut(false);
-      }, 1000);
+      setTimeout(() => setIsLoggingOut(false), 1000);
     } catch (error) {
       console.error("Error during logout:", error);
       setIsLoggingOut(false);
     }
-  }, [navigate]); // Remove user dependency
-
-  // Function to reset inactivity timer - using userRef instead of user state
+  }, [navigate]);
+
   const resetInactivityTimer = useCallback(() => {
     isActiveRef.current = true;
-
-    // Clear existing timeout
+    localStorage.setItem("lastActivityTimestamp", Date.now().toString());
+
     if (inactivityTimeoutRef.current) {
       clearTimeout(inactivityTimeoutRef.current);
-      inactivityTimeoutRef.current = null;
     }
 
-    // Only set new timeout if we have a user (using ref)
     if (userRef.current) {
-      // Update timestamp in localStorage, but limit frequency to avoid excessive writes
-      const now = Date.now();
-      const lastStoredTime = parseInt(
-        localStorage.getItem("lastActivityTimestamp") || "0"
-      );
-      if (now - lastStoredTime > 10000) {
-        // Only update every 10 seconds
-        localStorage.setItem("lastActivityTimestamp", now.toString());
-
-        // Debug log with reduced frequency
-        if (import.meta.env.DEV) {
-          const currentTime = new Date().toLocaleTimeString();
-          console.debug(
-            `[${currentTime}] Activity detected, resetting timeout`
-          );
-        }
-      }
-
       inactivityTimeoutRef.current = setTimeout(() => {
         isActiveRef.current = false;
-        console.warn("User inactive for 2 minutes, logging out...");
+        console.warn("User inactive, logging out");
         logout();
       }, INACTIVITY_TIMEOUT);
     }
-  }, [logout, INACTIVITY_TIMEOUT]); // Remove user dependency
-
-  // Initial session check
+  }, [logout]);
   useEffect(() => {
     const checkStaleSession = () => {
@@ -139,9 +112,5 @@
 
         if (inactiveTime > INACTIVITY_TIMEOUT) {
-          console.log("Found stale session - logging out");
-          localStorage.removeItem("user");
-          localStorage.removeItem("lastActivityTimestamp");
-          supabase.auth.signOut();
-          navigate("/");
+          logout();
         }
       }
@@ -150,12 +119,123 @@
     checkStaleSession();
   }, [navigate, INACTIVITY_TIMEOUT]);
-
-  // Set up activity listeners - use a stable reference to avoid recreation
-  useEffect(() => {
-    if (!user) return; // ✅ Use `user` instead of `userRef.current`
-
-    if (import.meta.env.DEV) {
-      console.log("Setting up activity listeners for inactivity timeout");
-    }
+  const setupTokenExpiryLogout = useCallback(
+    (accessToken) => {
+      if (!accessToken) return;
+
+      const payload = parseJwt(accessToken);
+      if (!payload?.exp) return;
+
+      const now = Math.floor(Date.now() / 1000);
+      const expiresIn = payload.exp - now;
+
+      if (expiresIn <= 0) {
+        console.warn("Token already expired, handling expiration");
+
+        const lastActivity = parseInt(
+          localStorage.getItem("lastActivityTimestamp") || "0",
+          10
+        );
+        const inactiveDuration = Date.now() - lastActivity;
+
+        if (inactiveDuration > INACTIVITY_TIMEOUT) {
+          logout();
+        } else {
+          supabase.auth
+            .refreshSession()
+            .then(({ data, error }) => {
+              if (error) {
+                console.error("Token refresh failed:", error);
+                logout();
+              } else if (data?.session?.access_token) {
+                localStorage.setItem("jwt", data.session.access_token);
+                setupTokenExpiryLogout(data.session.access_token);
+              }
+            })
+            .catch((err) => {
+              console.error("Refresh failed:", err);
+              logout();
+            });
+        }
+      } else {
+        localStorage.setItem("token_exp", payload.exp.toString());
+
+        if (tokenExpiryTimeoutRef.current) {
+          clearTimeout(tokenExpiryTimeoutRef.current);
+        }
+
+        tokenExpiryTimeoutRef.current = setTimeout(() => {
+          setupTokenExpiryLogout(accessToken);
+        }, expiresIn * 1000);
+      }
+    },
+    [logout]
+  );
+
+  useEffect(() => {
+    const initializeAuth = async () => {
+      try {
+        const { data } = await supabase.auth.getSession();
+        const session = data?.session;
+        if (session?.user) {
+          setUser(session.user);
+          localStorage.setItem("jwt", session.access_token);
+          setupTokenExpiryLogout(session.access_token);
+        }
+        const tokenExp = localStorage.getItem("token_exp");
+        if (tokenExp) {
+          const now = Math.floor(Date.now() / 1000);
+          const expiresIn = parseInt(tokenExp) - now;
+
+          if (expiresIn <= 0) {
+            await logout();
+          } else {
+            tokenExpiryTimeoutRef.current = setTimeout(() => {
+              logout();
+            }, expiresIn * 1000);
+          }
+        }
+      } catch (error) {
+        console.error("Error retrieving session:", error);
+      } finally {
+        setLoading(false);
+      }
+    };
+
+    initializeAuth();
+
+    const { data: authListener } = supabase.auth.onAuthStateChange(
+      (event, session) => {
+        if (event === "SIGNED_IN" && session?.user) {
+          setUser(session.user);
+          localStorage.setItem("jwt", session.access_token);
+          setupTokenExpiryLogout(session.access_token);
+        } else if (event === "SIGNED_OUT") {
+          setUser(null);
+          localStorage.removeItem("jwt");
+
+          if (inactivityTimeoutRef.current) {
+            clearTimeout(inactivityTimeoutRef.current);
+            inactivityTimeoutRef.current = null;
+          }
+          if (tokenExpiryTimeoutRef.current) {
+            clearTimeout(tokenExpiryTimeoutRef.current);
+            tokenExpiryTimeoutRef.current = null;
+          }
+        } else if (event === "TOKEN_REFRESHED" && session) {
+          localStorage.setItem("jwt", session.access_token);
+          setupTokenExpiryLogout(session.access_token);
+        }
+      }
+    );
+
+    return () => {
+      if (authListener?.subscription) {
+        authListener.subscription.unsubscribe();
+      }
+    };
+  }, [setupTokenExpiryLogout]);
+
+  useEffect(() => {
+    if (!user) return;
 
     const activityEvents = [
@@ -168,106 +248,36 @@
     ];
 
-    let debounceTimeout;
-    const DEBOUNCE_DELAY = 1000;
-
     const handleActivity = () => {
-      if (debounceTimeout) clearTimeout(debounceTimeout);
-      debounceTimeout = setTimeout(() => {
-        resetInactivityTimer();
-      }, DEBOUNCE_DELAY);
+      resetInactivityTimer();
     };
 
     activityEvents.forEach((event) => {
-      document.addEventListener(event, handleActivity, { passive: true });
+      document.addEventListener(event, handleActivity);
     });
 
-    resetInactivityTimer(); // ✅ Ensure it's called when the user logs in
-
-    const handleVisibilityChange = () => {
-      if (document.visibilityState === "visible") {
-        resetInactivityTimer();
-      }
-    };
-
-    document.addEventListener("visibilitychange", handleVisibilityChange);
+    resetInactivityTimer();
 
     return () => {
-      if (debounceTimeout) clearTimeout(debounceTimeout);
-
       activityEvents.forEach((event) => {
         document.removeEventListener(event, handleActivity);
       });
-
-      document.removeEventListener("visibilitychange", handleVisibilityChange);
-
       if (inactivityTimeoutRef.current) {
         clearTimeout(inactivityTimeoutRef.current);
-        inactivityTimeoutRef.current = null;
-      }
-    };
-  }, [resetInactivityTimer, user]); // Only depend on the stable resetInactivityTimer
-
-  // Initial auth and auth listener setup
-  useEffect(() => {
-    const initializeAuth = async () => {
-      try {
-        const { data } = await supabase.auth.getSession();
-        if (data?.session?.user) {
-          setUser(data.session.user);
-          localStorage.setItem("jwt", data.session.access_token);
-          // userRef will be updated via the user effect
-        }
-      } catch (error) {
-        console.error("Error retrieving session:", error);
-      } finally {
-        setLoading(false);
-      }
-    };
-
-    initializeAuth();
-
-    // Set up auth state listener
-    const { data: authListener } = supabase.auth.onAuthStateChange(
-      (event, session) => {
-        if (import.meta.env.DEV && event !== "TOKEN_REFRESHED") {
-          console.log("Auth state changed:", event);
-        }
-
-        if (event === "SIGNED_IN" && session?.user) {
-          setUser(session.user);
-          localStorage.setItem("jwt", session.access_token);
-          // userRef will be updated via the user effect
-        } else if (event === "SIGNED_OUT") {
-          setUser(null);
-          localStorage.removeItem("jwt");
-          if (inactivityTimeoutRef.current) {
-            clearTimeout(inactivityTimeoutRef.current);
-            inactivityTimeoutRef.current = null;
-          }
-        } else if (event === "TOKEN_REFRESHED" && session) {
-          localStorage.setItem("jwt", session.access_token);
-          // Only reset timer if not logged out
-          if (userRef.current) {
-            resetInactivityTimer();
-          }
-        }
-      }
-    );
-
-    return () => {
-      if (authListener?.subscription) {
-        authListener.subscription.unsubscribe();
-      }
-    };
-  }, [resetInactivityTimer]);
-
-  const value = {
-    user,
-    loading,
-    logout,
-    resetInactivityTimer,
-    isLoggingOut,
-  };
-
-  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
+      }
+    };
+  }, [resetInactivityTimer, user]);
+
+  return (
+    <AuthContext.Provider
+      value={{
+        user,
+        loading,
+        logout,
+        resetInactivityTimer,
+        isLoggingOut,
+      }}
+    >
+      {children}
+    </AuthContext.Provider>
+  );
 };
