diff --git a/backend/config/passportConfig.js b/backend/config/passportConfig.js index 842f50ca..59ac9e51 100644 --- a/backend/config/passportConfig.js +++ b/backend/config/passportConfig.js @@ -38,7 +38,11 @@ passport.serializeUser((user, done) => { passport.deserializeUser(async (id, done) => { try { const user = await User.findById(id); - done(null, user); + done(null, user ? { + id: user._id.toString(), + username: user.username, + email: user.email + } : null); } catch (err) { done(err, null); } diff --git a/backend/routes/auth.js b/backend/routes/auth.js index 9c974f79..1c1cf764 100644 --- a/backend/routes/auth.js +++ b/backend/routes/auth.js @@ -30,6 +30,17 @@ router.post("/signup", validateRequest(signupSchema), async (req, res) => { } }); +// Session status route +router.get("/me", (req, res) => { + const isAuthenticated = typeof req.isAuthenticated === "function" && req.isAuthenticated(); + + if (!isAuthenticated) { + return res.status(200).json({ authenticated: false, user: null }); + } + + return res.status(200).json({ authenticated: true, user: req.user }); +}); + // Login route router.post("/login", validateRequest(loginSchema), passport.authenticate('local'), (req, res) => { res.status(200).json( { message: 'Login successful', user: req.user } ); @@ -40,10 +51,18 @@ router.get("/logout", (req, res) => { req.logout((err) => { - if (err) + if (err) { return res.status(500).json({ message: 'Logout failed', error: err.message }); - else - res.status(200).json({ message: 'Logged out successfully' }); + } + + req.session.destroy((sessionErr) => { + if (sessionErr) { + return res.status(500).json({ message: 'Logout failed', error: sessionErr.message }); + } + + res.clearCookie('connect.sid'); + return res.status(200).json({ message: 'Logged out successfully' }); + }); }); }); diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index e5f7eb4f..eaf85e29 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -1,25 +1,21 @@ import { NavLink, Link } from "react-router-dom"; import { useState, useContext } from "react"; import { ThemeContext } from "../context/ThemeContext"; +import { AuthContext } from "../context/AuthContext"; import { Moon, Sun, Menu, X } from "lucide-react"; +import { useNavigate } from "react-router-dom"; const Navbar: React.FC = () => { const [isOpen, setIsOpen] = useState(false); const themeContext = useContext(ThemeContext); - if (!themeContext) return null; + const authContext = useContext(AuthContext); + const navigate = useNavigate(); - const { toggleTheme, mode } = themeContext; - const storedUser = localStorage.getItem("user"); - let user = null; + if (!themeContext || !authContext) return null; - try { - user = storedUser ? JSON.parse(storedUser) : null; - } catch (error) { - console.error("Invalid user data in local Storage"); - localStorage.removeItem("user"); - user = null; - } + const { toggleTheme, mode } = themeContext; + const { isAuthenticated, isLoading, logout } = authContext; const navLinkStyles = ({ isActive }: { isActive: boolean }) => `px-4 py-2 rounded-xl text-sm lg:text-base font-semibold transition-all duration-300 ${isActive @@ -29,6 +25,17 @@ const Navbar: React.FC = () => { const closeMenu = () => setIsOpen(false); + const handleLogout = async () => { + try { + await logout(); + navigate("/login", { replace: true }); + } catch { + // optionally surface a toast/message + } finally { + closeMenu(); + } + }; + return (