Продовж створення REST API для роботи з колекцією контактів у новій гілці 04-auth. Додай логіку аутентифікації / авторизації користувача через JWT.
У коді створи схему і модель користувача для колекції users.
{ password: { type: String, required: [true, ‘Set password for user’], }, email: { type: String, required: [true, ‘Email is required’], unique: true, }, subscription: { type: String, enum: [“starter”, “pro”, “business”], default: “starter” }, token: String }
Змініть схему контактів, щоб кожен користувач бачив тільки свої контакти. Для цього в схемі контактів додайте властивість
owner: {
type: Schema.Types.ObjectId,
ref: 'user',
}
Примітка: ‘user’ - назва колекції, у якій зберігаються користувачі
Створити ендпоінт /users/register
Зробити валідацію всіх обов’язкових полів (email і password). При помилці валідації повернути Помилку валідації.
У разі успішної валідації в моделі User створити користувача за даними, які пройшли валідацію. Для засолювання паролів використовуй bcrypt або bcryptjs
Якщо пошта вже використовується кимось іншим, повернути Помилку Conflict. В іншому випадку повернути Успішна відповідь.
POST /users/register Content-Type: application/json RequestBody: { “email”: “example@example.com”, “password”: “examplepassword” }
Status: 400 Bad Request Content-Type: application/json ResponseBody: <Помилка від="" Joi="" або="" іншої="" бібліотеки="" валідації="">Помилка>
Status: 409 Conflict Content-Type: application/json ResponseBody: { “message”: “Email in use” }
Status: 201 Created Content-Type: application/json ResponseBody: { “user”: { “email”: “example@example.com”, “subscription”: “starter” } }
Створити ендпоінт /users/login
В моделі User знайти користувача за email.
Зробити валідацію всіх обов’язкових полів (email і password). При помилці валідації повернути Помилку валідації.
В іншому випадку, порівняти пароль для знайденого користувача, якщо паролі збігаються створити токен, зберегти в поточному юзера і повернути Успішна відповідь. Якщо пароль або імейл невірний, повернути Помилку Unauthorized.
POST /users/login Content-Type: application/json RequestBody: { “email”: “example@example.com”, “password”: “examplepassword” }
Status: 400 Bad Request Content-Type: application/json ResponseBody: <Помилка від="" Joi="" або="" іншої="" бібліотеки="" валідації="">Помилка>
Status: 200 OK Content-Type: application/json ResponseBody: { “token”: “exampletoken”, “user”: { “email”: “example@example.com”, “subscription”: “starter” } }
Status: 401 Unauthorized ResponseBody: { “message”: “Email or password is wrong” }
Створи мідлвар для перевірки токена і додай його до всіх раутів, які повинні бути захищені.
Мідлвар бере токен з заголовків Authorization, перевіряє токен на валідність. У випадку помилки повернути Помилку Unauthorized. Якщо валідація пройшла успішно, отримати з токена id користувача. Знайти користувача в базі даних з цим id. Якщо користувач існує і токен збігається з тим, що знаходиться в базі, записати його дані в req.user і викликати next(). Якщо користувача з таким id НЕ існує або токени не збігаються, повернути Помилку Unauthorized
Status: 401 Unauthorized Content-Type: application/json ResponseBody: { “message”: “Not authorized” }
Створити ендпоінт /users/logout
Додай в маршрут мідлвар перевірки токена.
У моделі User знайти користувача за _id. Якщо користувача не існує повернути Помилку Unauthorized. В іншому випадку, видалити токен у поточного юзера і повернути Успішна відповідь.
POST /users/logout Authorization: “Bearer “
Status: 401 Unauthorized Content-Type: application/json ResponseBody: { “message”: “Not authorized” }
Status: 204 No Content
Створити ендпоінт /users/current
Додай в раут мідлвар перевірки токена.
Якщо користувача не існує повернути Помилку Unauthorized В іншому випадку повернути Успішну відповідь
GET /users/current Authorization: “Bearer “
Status: 401 Unauthorized Content-Type: application/json ResponseBody: { “message”: “Not authorized” }
Status: 200 OK Content-Type: application/json ResponseBody: { “email”: “example@example.com”, “subscription”: “starter” }
Зробити пагінацію для колекції контактів (GET /contacts?page=1&limit=20). Зробити фільтрацію контактів по полю обраного (GET /contacts?favorite=true) Оновлення підписки (subscription) користувача через ендпоінт PATCH /users. Підписка повинна мати одне з наступних значень [‘starter’, ‘pro’, ‘business’]