/
Coderdev
/
web-nodejs-labs
Обзор
Документация
Войти
/
Coderdev
/
web-nodejs-labs
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
backend/src/routes/lab11/secure.js
154 строки
6 KB
Coderdev
1
12 май 2026, 11:10
12 май 2026, 11:10
d528236
Код
Авторство
О чём код?
// backend/src/routes/lab11/secure.js import bcrypt from 'bcrypt'; import { getAllUsers, findUserById, createUser, updateUserRole, updateUserPassword, deleteUser, generatePassword, isLoginTaken, } from '../../services/lab11/user.service.js'; export default async function secureRoutes(fastify) { // ── Задание 1: профиль и админ-заглушка ───────────────────────────── // GET /api/lab11/profile fastify.get('/profile', { onRequest: [fastify.authenticate], }, async (request) => { return { id: request.user.id, login: request.user.login, role: request.user.role }; }); // GET /api/lab11/admin (только admin) fastify.get('/admin', { onRequest: [fastify.authenticate], }, async (request, reply) => { if (request.user.role !== 'admin') { return reply.code(403).send({ error: 'Forbidden: admin only' }); } return { message: 'Добро пожаловать в админский раздел!', user: { id: request.user.id, login: request.user.login, role: request.user.role }, }; }); // ── Задание 2: управление пользователями ───────────────────────────── // GET /api/lab11/users // - неавторизованный: только список (id + login) // - авторизованный: полный список с ролями // - admin: полный список + created_at fastify.get('/users', async (request, reply) => { // Пробуем верифицировать токен, но не обязываем let userRole = null; try { await request.jwtVerify(); userRole = request.user.role; } catch (_) { /* не авторизован — ок */ } const pg = fastify.pg; const users = await getAllUsers(pg); if (!userRole) { // Неавторизованный — только id и login return users.map(u => ({ id: u.id, login: u.login })); } if (userRole === 'user') { // Авторизованный — id, login, role return users.map(u => ({ id: u.id, login: u.login, role: u.role })); } // admin — всё return users; }); // GET /api/lab11/users/:id (только авторизованные) fastify.get('/users/:id', { onRequest: [fastify.authenticate], }, async (request, reply) => { const user = await findUserById(fastify.pg, request.params.id); if (!user) return reply.code(404).send({ error: 'Пользователь не найден' }); return user; }); // POST /api/lab11/users (только admin) fastify.post('/users', { onRequest: [fastify.authenticate], schema: { body: { type: 'object', required: ['login', 'password'], properties: { login: { type: 'string', minLength: 3 }, password: { type: 'string', minLength: 6 }, role: { type: 'string', enum: ['user', 'admin'] }, }, }, }, }, async (request, reply) => { if (request.user.role !== 'admin') { return reply.code(403).send({ error: 'Forbidden: admin only' }); } const { login, password, role = 'user' } = request.body; const pg = fastify.pg; if (await isLoginTaken(pg, login)) { return reply.code(400).send({ error: 'Логин уже занят' }); } const passwordHash = await bcrypt.hash(password, 10); const user = await createUser(pg, { login, passwordHash, roleName: role }); reply.code(201); return user; }); // PATCH /api/lab11/users/:id/role (только admin) fastify.patch('/users/:id/role', { onRequest: [fastify.authenticate], schema: { body: { type: 'object', required: ['role'], properties: { role: { type: 'string', enum: ['user', 'admin'] } }, }, }, }, async (request, reply) => { if (request.user.role !== 'admin') { return reply.code(403).send({ error: 'Forbidden: admin only' }); } const updated = await updateUserRole(fastify.pg, request.params.id, request.body.role); if (!updated) return reply.code(404).send({ error: 'Пользователь не найден' }); return updated; }); // POST /api/lab11/users/:id/reset-password (только admin — генерирует новый пароль) fastify.post('/users/:id/reset-password', { onRequest: [fastify.authenticate], }, async (request, reply) => { if (request.user.role !== 'admin') { return reply.code(403).send({ error: 'Forbidden: admin only' }); } const newPassword = generatePassword(); const newHash = await bcrypt.hash(newPassword, 10); await updateUserPassword(fastify.pg, request.params.id, newHash); // Возвращаем сгенерированный пароль открытым текстом — только для демонстрации return { newPassword }; }); // DELETE /api/lab11/users/:id (только admin, нельзя удалить себя) fastify.delete('/users/:id', { onRequest: [fastify.authenticate], }, async (request, reply) => { if (request.user.role !== 'admin') { return reply.code(403).send({ error: 'Forbidden: admin only' }); } if (parseInt(request.params.id) === request.user.id) { return reply.code(400).send({ error: 'Нельзя удалить самого себя' }); } const deleted = await deleteUser(fastify.pg, request.params.id); if (!deleted) return reply.code(404).send({ error: 'Пользователь не найден' }); return { message: 'Удалён', id: deleted.id }; }); }