Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions backend/config/passportConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -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, {
Expand All @@ -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);
Expand Down
26 changes: 21 additions & 5 deletions backend/routes/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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' });
});
Expand Down
Loading