Start learning free

LESSON 159 OF 173 · BACKEND: BACKEND WITH AI

The AI Left the Door Open

Practice

An AI assistant wrote the route the shop's admin uses to delete a product. Here is the AI's version:

app.delete("/products/:productId", (req: Request, res: Response) => {
  const productId = Number(req.params.productId);
  const result = db.prepare("DELETE FROM products WHERE id = ?").run(productId);
  if (result.changes === 0) {
    return res.status(404).json({ error: "Product not found" });
  }
  res.status(204).send();
});

Every line is right, it compiles without a single error, and a quick try works. The hole is a line that isn't there: the route never asks who is calling, so anyone on the internet can delete products from the shop.

A route that changes data checks the caller first, and there are two ways to refuse. 401 means "we don't know who you are": no token, or a token the shop never gave out. 403 Forbidden means "we know who you are, and you may not do this". The helper currentRole(req: Request): string | undefined reads the token from the Authorization header and gives that user's role from TOKENS, or undefined. Here is the first check on another route:

app.get("/account", (req: Request, res: Response) => {
  const role = currentRole(req);
  if (role === undefined) {
    return res.status(401).json({ error: "Login required" });
  }
  res.json({ role: role });
});

The tests run in this order, on one database:

DELETE /products/8   (no token)                →  401  {"error": "Login required"}
DELETE /products/8   Bearer ana-token-123      →  403  {"error": "Admins only"}
GET    /products/8                             →  200  {"id": 8, "name": "Gift card", "price": 50, "category": null, "stock": 999}
DELETE /products/8   Bearer admin-token-456    →  204  (empty)
GET    /products/8                             →  404  {"error": "Product not found"}
DELETE /products/8   Bearer admin-token-456    →  404  {"error": "Product not found"}
DELETE /products/3   Bearer let-me-in          →  401  {"error": "Login required"}
DELETE /products/99  (no token)                →  401  {"error": "Login required"}
GET    /products/3                             →  200  {"id": 3, "name": "Lamp", "price": 29, "category": "home", "stock": 1}

Your task: rewrite the app.delete handler. Delete the product and answer 204, or 404 if there was none. Then add the checks at the top: 401 { error: "Login required" } when there is no role, and 403 { error: "Admins only" } when the role isn't "admin".


Assignment
Follow the Coding Tutorial to rewrite the delete route so only the admin can delete a product.


Hint
Both checks go before the DELETE: once it runs, the product is gone, whatever you answer. The 401 check comes first (role === undefined), then role !== "admin" for the 403. Start each refusal with return so the handler stops there.


STEP 1 OF 9
    Ctrl + Enter to check