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 7c2cda78..b97f662a 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 fd5eac86..3e352a0a 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -1,16 +1,21 @@ import { NavLink, Link } from "react-router-dom"; import { useState, useContext } from "react"; import { ThemeContext } from "../context/ThemeContext"; -import { Moon, Sun, Menu, X, Github } from "lucide-react"; +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); + const authContext = useContext(AuthContext); + const navigate = useNavigate(); - if (!themeContext) return null; + if (!themeContext || !authContext) return 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 ${ @@ -21,6 +26,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 (