Start learning free

LESSON 91 OF 173 · BACKEND: USERS AND SECURITY

Customers and Admins

Practice

So far every user is the same kind of user, so the shop can't tell its owner from a shopper. A role column fixes that: each user is a 'customer' or an 'admin', and only admins may add products.

A column with a DEFAULT fills itself in when an INSERT leaves it out. For example, an orders table could start every order as 'new', so an INSERT that gives only the user_id still gets a status:

db.exec("CREATE TABLE IF NOT EXISTS orders (id INTEGER PRIMARY KEY, user_id INTEGER NOT NULL, status TEXT NOT NULL DEFAULT 'new')");
db.prepare("INSERT INTO orders (user_id) VALUES (?)").run(2);

There are two ways to say no. 401 means "I don't know who you are: log in". 403 Forbidden means "I know who you are, and you may not do this". A second middleware, adminRequired, gives the 403. In a route it goes after loginRequired, which finds the user first and stores it in req.user. The UserInfo type now has a role: string property, so req.user.role is a string.

Nobody can sign up as an admin, so the shop creates its owner's account itself when it starts. Ana signs up after that, so she gets id 2:

POST /register  {"email": "ana@example.com", "password": "secret123"}  →  201  {"email": "ana@example.com", "id": 2}
POST /login  {"email": "ana@example.com", "password": "secret123"}  →  200  {"token": "<token>"}
GET /me  (Ana's token)  →  200  {"email": "ana@example.com", "id": 2, "role": "customer"}
POST /products  {"name": "Desk", "price": 120}  (Ana's token)  →  403  {"error": "Admins only"}
POST /products  {"name": "Desk", "price": 120}  (no token)  →  401  {"error": "Login required"}
POST /login  {"email": "admin@example.com", "password": "admin-pass-123"}  →  200  {"token": "<admin>"}
GET /me  (admin's token)  →  200  {"email": "admin@example.com", "id": 1, "role": "admin"}
POST /products  {"name": "Desk", "price": 120}  (admin's token)  →  201  {"id": 9, "name": "Desk", "price": 120}
GET /products/9  →  200  {"category": null, "id": 9, "name": "Desk", "price": 120, "stock": 0}

Your task: give the users table a role column that defaults to 'customer', create the admin account when the app starts, select the role in currentUser, write the adminRequired middleware, and write the POST /products route with loginRequired, then adminRequired, then addProduct.


Assignment
Follow the Coding Tutorial to give every user a role and let only admins add products.


Hint
Inside SQL written in double quotes, the text 'customer' takes single quotes. Until you write currentUser's query again in step 3, tsc reports that it must return a value: that's expected. In the route, put loginRequired first: adminRequired needs the req.user it stores.


STEP 1 OF 9
    Ctrl + Enter to check