Start learning free

LESSON 98 OF 173 · BACKEND: USERS AND SECURITY

Validate Everything

Practice

A client can send anything: an email without an @, a password of one letter, a price of -5, a price written as text. Today the shop stores all of it. A safe backend validates every value before it stores it.

When a value is wrong, the shop answers 400 Bad Request with a message and the name of the field that is wrong, so an app can show the message next to that box. Two Java tools help: instanceof tells a value's type, and split cuts a text into parts.

Object price = 120;
Object text = "120";
price instanceof Integer       // true
text instanceof Integer        // false: a String, even if it looks like a number
data.get("email")              // null when the field is missing
"bo@shop.io".split("@", -1)    // ["bo", "shop.io"]

value instanceof String s also names the value s for when the test is true, and null instanceof String is simply false. Read fields with data.get(...): a missing field gives null. And check every route that takes a value: a rule that one route forgets protects nothing.

POST /register  {"email": "ana.example.com", "password": "secret123"}  →  400  {"error": "Enter a valid email, like ana@example.com", "field": "email"}
POST /register  {"password": "secret123"}  →  400  {"error": "Enter a valid email, like ana@example.com", "field": "email"}
POST /register  {"email": "ana@example.com", "password": "123"}  →  400  {"error": "The password needs at least 8 characters", "field": "password"}
POST /register  {"email": "ana@example.com", "password": "secret123"}  →  201  {"email": "ana@example.com", "id": 2}
PUT /me/password  {"old_password": "secret123", "new_password": "abc"}  (Ana's token)  →  400  {"error": "The password needs at least 8 characters", "field": "new_password"}
POST /products  {"name": "Desk", "price": -5}  (admin's token)  →  400  {"error": "The price must be a whole number from 1 to 10000", "field": "price"}
POST /products  {"name": "Desk", "price": "120"}  (admin's token)  →  400  {"error": "The price must be a whole number from 1 to 10000", "field": "price"}
POST /products  {"name": "Desk", "price": 120}  (admin's token)  →  201  {"id": 9, "name": "Desk", "price": 120}

Your task: write validEmail(Object email), then check the email and the password in register and the price in saveProduct. The helper invalid(field, message), which builds the 400 answer, and the new-password check in updatePassword are already in the starting code.


Assignment
Follow the Coding Tutorial to write validEmail and add the three checks.


Hint
Put the instanceof test first in each if: || stops at the first true part, so length() or split never runs on null or a number. An email is valid when it is a String with exactly one @, no space, a name before the @ and a dot after it.


STEP 1 OF 11
    Ctrl + Enter to check