The bug that ships most often
The capstone handler you just built checks who is asking. This lesson finishes the job: making sure users can only see and delete their own notes. Skipping that comparison is one of the most common real-world API vulnerabilities, the IDOR (insecure direct object reference): a user changes the id in the URL from /notes/17 to /notes/18 and reads or deletes a stranger's data. Security scanners hunt for it automatically and bug-bounty programs pay for it weekly, because unlike a broken login it hides inside endpoints that look protected — the request is authenticated; it is the ownership check that is missing.
Two rules, mapped onto the lesson 9-1 endpoints:
GET /notesnever returns all notes. It filters by the session's user, and the username comes from the server-side session, never from the request, because the client does not get to declare who it is.DELETE /notes/:idloads the note first, then compares its author to the session user: no such note → 404, someone else's note → 403. That is your lesson 3-3 problem, finally as running code.
Code exercise · javascript
Your turn. Implement handleListNotes: 401 with the usual error shape for an unknown session; otherwise filter notes down to the session user's own (notes.filter) and return 200 with { data, meta: { total } }. Grace's note must never appear in ada's list.
Quiz
Some APIs answer 404 (not 403) when a user requests someone ELSE's note by id. What is the reasoning?
Code exercise · javascript
Your turn, the last handler of the course. handleDeleteNote walks four outcomes in order: unknown session -> 401; no note with req.id -> 404 with code "note_not_found"; a note owned by someone else -> 403 with code "forbidden"; otherwise remove the note (reassign notes = notes.filter(...)) and return { status: 204 }, success with no body.
Problem
Wiring GET /notes to the real database from lesson 6-3: which SQL keyword filters the query down to the session user's own rows (as in ... author = ?)? Answer with the one keyword.