Start learning free

LESSON 24 OF 58 · FULL-STACK: LOGIN WITH COOKIES

Project: Change the Password in JavaScript

Practice

A logged-in visitor should be able to change their password. Being logged in is not enough proof: somebody at an unlocked computer has the cookie too. So the server asks for the old password first, checks that the new one is long enough, and stores the new hash. Then it logs out every other session of that user, so a cookie left behind on another computer stops working.

express-session keeps every session in a session store, req.sessionStore. Its all method hands your callback every session, keyed by session id, and destroy(sid) removes one. req.sessionID is the id of the session making this request. For example, this route on another path counts a user's sessions:

app.get("/api/me/sessions", requireLogin, (req, res) => {
  req.sessionStore.all((err, sessions) => {
    let count = 0;
    for (const sid in sessions) {
      if (sessions[sid].userId === req.user.id) {
        count = count + 1;
      }
    }
    res.json({ sessions: count });
  });
});

The store answers later, so the response goes inside the callback. for … in walks through an object's keys, which here are the session ids.

The Account page (client/src/pages/AccountPage.jsx, given) sends the form to PUT /api/me/password. It shows an error as an alert and the message as a status. The check logs Ana in on the page and also from another browser. Your server must answer:

PUT /api/me/password  {"old_password": "wrong-pass-1", "new_password": "mugs-forever-9"}  →  401  {"error": "Wrong password"}
PUT /api/me/password  {"old_password": "mug-lover-1", "new_password": "short"}  →  400  {"error": "The new password needs at least 8 characters"}
PUT /api/me/password  {"old_password": "mug-lover-1", "new_password": "mugs-forever-9"}  →  200  {"message": "Password changed"}
GET /api/me  (the other browser)  →  401  {"error": "Not logged in"}
GET /api/me  (this page, after a reload)  →  200  (still ana@example.com)
POST /api/login  (old password)  →  401  {"error": "Wrong email or password"}
POST /api/login  (new password)  →  200  {"email": "ana@example.com", "role": "customer"}

Your task: in server/app.js, fill in changePassword. Check the old password (401) and the new one (400), store the new hash, destroy the user's other sessions and answer { message: "Password changed" }. Then add the route PUT /api/me/password with requireLogin first.


Assignment
Follow the Coding Tutorial to write changePassword one line at a time and connect it to PUT /api/me/password.


Hint
req.user has no password_hash, so load the whole row with SELECT * first. In the loop, skip req.sessionID and compare sessions[sid].userId with user.id.


STEP 1 OF 12
    Ctrl + Enter to check

    Fsauth Password Project in JavaScript

    Keep going with JavaScript1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free