Exercises
Objectives
By the end of this lesson, you should be able to:
- Build a protected endpoint that requires both a valid session and a correct current password
- Confirm a password change actually takes effect for future logins
- Confirm an old password stops working immediately after a change
⚠️ A note on verification: every command and every output in this lesson was actually run, with real HTTP requests against a real Express app.
Exercise: Change Password While Logged In
a) Build the endpoint. POST /api/v1/auth/change-password, protected by requireAuth (Lesson 3), requiring the current password to match before setting a new one:
app.post('/api/v1/auth/change-password', requireAuth, async (req, res, next) => {
try {
const { currentPassword, newPassword } = req.body;
const user = users.find(u => u.id === req.session.userId);
const matches = await bcrypt.compare(currentPassword, user.passwordHash);
if (!matches) {
return res.status(401).json({ error: 'InvalidCredentials', message: 'Current password is incorrect' });
}
user.passwordHash = await bcrypt.hash(newPassword, 10);
res.status(204).send();
} catch (err) {
next(err);
}
});
b) Test an anonymous attempt. No session at all:
ANON ATTEMPT: 401 {"error":"Unauthorized","message":"Login required"}
c) Test a wrong current password, logged in, but the wrong currentPassword:
WRONG CURRENT: 401 {"error":"InvalidCredentials","message":"Current password is incorrect"}
d) Test a successful change:
SUCCESS: 204
e) Confirm the new password actually works, log in again, from a fresh client, with the new password:
RE-LOGIN WITH NEW PASSWORD: 200 {"id":1,"email":"erin@example.com"}
f) Confirm the old password no longer works:
OLD PASSWORD NO LONGER WORKS: 401 {"error":"InvalidCredentials","message":"Incorrect email or password"}
g) Add a stronger guarantee. Modify the endpoint so it also calls req.session.destroy() after a successful password change, forcing the user to log in again with the new password on their next request too, not just other clients. Confirm, with a test, that the current session’s own follow-up request to a protected route now also returns 401.
Recap
This module covered the complete session-based authentication flow: how sessions work conceptually, wiring up express-session, and building login, logout, and protected routes, including a password-change endpoint that requires both an active session and the correct current password.
Next module: JSON Web Tokens, a stateless alternative to sessions, the pattern most REST APIs use instead.