diff --git a/backend/config/passportConfig.js b/backend/config/passportConfig.js index 842f50ca..b19ee9b3 100644 --- a/backend/config/passportConfig.js +++ b/backend/config/passportConfig.js @@ -9,12 +9,13 @@ passport.use( try { const user = await User.findOne( {email} ); if (!user) { - return done(null, false, { message: 'Email is invalid '}); + // Generic message prevents user enumeration + return done(null, false, { message: 'Invalid credentials' }); } const isMatch = await user.comparePassword(password); if (!isMatch) { - return done(null, false, { message: 'Invalid password' }); + return done(null, false, { message: 'Invalid credentials' }); } return done(null, { @@ -34,10 +35,10 @@ passport.serializeUser((user, done) => { done(null, user.id); }); -// Deserialize user (retrieve user from session) +// Deserialize user — exclude password hash from req.user on every request passport.deserializeUser(async (id, done) => { try { - const user = await User.findById(id); + const user = await User.findById(id).select('-password'); done(null, user); } catch (err) { done(err, null); diff --git a/backend/routes/auth.js b/backend/routes/auth.js index 7c2cda78..7e6381cf 100644 --- a/backend/routes/auth.js +++ b/backend/routes/auth.js @@ -26,13 +26,29 @@ router.post("/signup", validateRequest(signupSchema), async (req, res) => { return res.status(400).json({ message: 'User already exists' }); } - res.status(500).json({ message: 'Error creating user', error: err.message }); + res.status(500).json({ message: 'Error creating user' }); } }); -// Login route -router.post("/login", validateRequest(loginSchema), passport.authenticate('local'), (req, res) => { - res.status(200).json( { message: 'Login successful', user: req.user } ); +// Login route — session is regenerated after successful authentication +// to prevent session fixation; only safe fields returned in the response +router.post("/login", validateRequest(loginSchema), (req, res, next) => { + passport.authenticate('local', (err, user, info) => { + if (err) return next(err); + if (!user) return res.status(401).json({ message: info?.message || 'Invalid credentials' }); + + req.session.regenerate((regenerateErr) => { + if (regenerateErr) return next(regenerateErr); + + req.logIn(user, (loginErr) => { + if (loginErr) return next(loginErr); + res.status(200).json({ + message: 'Login successful', + user: { id: user.id, username: user.username, email: user.email }, + }); + }); + }); + })(req, res, next); }); // Logout route @@ -41,7 +57,7 @@ router.get("/logout", (req, res) => { req.logout((err) => { if (err) - return res.status(500).json({ message: 'Logout failed', error: err.message }); + return res.status(500).json({ message: 'Logout failed' }); else res.status(200).json({ message: 'Logged out successfully' }); });