/
Cooolprogrammers
/
web-nodejs-labs
Обзор
Документация
Войти
/
Cooolprogrammers
/
web-nodejs-labs
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
backend/src/routes/lab11/task3.js
461 строка
18 KB
darkvoid6@mail.ru
lavlab
15 дек 2025, 23:05
15 дек 2025, 23:05
a5bf0e9
Код
Авторство
О чём код?
export default async function task3Routes(fastify) { // Проверка доступа к магазину fastify.get("/shop/check-access", { onRequest: [fastify.authenticate] }, async (request, reply) => { const userRole = request.user.role; let message; if (userRole === 'admin') { message = 'У вас полный доступ к магазину (администратор)'; } else if (userRole === 'user') { message = 'У вас ограниченный доступ к магазину (можете редактировать только свои товары)'; } else { message = 'У вас доступ только для просмотра товаров'; } return { message, user: request.user, permissions: { view: true, add: userRole === 'admin', edit_own: userRole === 'user' || userRole === 'admin', edit_all: userRole === 'admin', delete: userRole === 'admin' } }; }); // Проверка доступа к расписанию fastify.get("/schedule/check-access", { onRequest: [fastify.authenticate] }, async (request, reply) => { const userRole = request.user.role; let message; if (userRole === 'admin') { message = 'У вас полный доступ к расписанию (администратор)'; } else if (userRole === 'user') { message = 'У вас доступ к расписанию (можете добавлять свои события)'; } else { message = 'У вас доступ только для просмотра расписания'; } return { message, user: request.user, permissions: { view: true, add: userRole === 'user' || userRole === 'admin', edit_own: userRole === 'user' || userRole === 'admin', edit_all: userRole === 'admin', delete: userRole === 'admin' } }; }); // Магазин: получение товаров fastify.get("/shop/products", async (request, reply) => { const pg = fastify.pg; try { // Проверяем, существуют ли таблицы, если нет - создаем const tableExists = await pg.query(` SELECT EXISTS ( SELECT FROM information_schema.tables WHERE table_schema = 'lab11' AND table_name = 'shop_products' ) `); if (!tableExists.rows[0].exists) { reply.code(500).send({ error: 'Таблица shop_products не существует. Выполните SQL скрипт для создания таблиц.' }); return; } // Получаем товары с информацией о владельце const result = await pg.query(` SELECT p.*, u.login as owner_name, CASE WHEN p.owner_id = $1 THEN true ELSE false END as is_owner FROM lab11.shop_products p LEFT JOIN lab11.users u ON p.owner_id = u.id WHERE p.is_active = true ORDER BY p.created_at DESC `, [request.user?.id || 0]); // Добавляем информацию о правах доступа const products = result.rows.map(product => ({ ...product, is_admin: request.user?.role === 'admin', can_edit: request.user?.role === 'admin' || (request.user?.role === 'user' && product.owner_id === request.user?.id) })); return products; } catch (error) { console.error('Shop products error:', error); reply.code(500).send({ error: 'Internal server error' }); } }); // Магазин: добавление товара fastify.post("/shop/products", { onRequest: [fastify.authenticate] }, async (request, reply) => { const pg = fastify.pg; const { name, description, price, category, quantity, image_url } = request.body; // Проверяем права доступа (только админы и пользователи могут добавлять товары) if (request.user.role === 'guest') { reply.code(403).send({ error: 'Only authenticated users can add products' }); return; } try { const result = await pg.query(` INSERT INTO lab11.shop_products (name, description, price, category, quantity, owner_id, image_url) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING * `, [name, description, price, category, quantity, request.user.id, image_url || null]); reply.code(201); return result.rows[0]; } catch (error) { console.error('Add product error:', error); reply.code(500).send({ error: 'Internal server error' }); } }); // Магазин: проверка прав на редактирование fastify.get("/shop/products/:id/check-edit", { onRequest: [fastify.authenticate] }, async (request, reply) => { const pg = fastify.pg; const productId = request.params.id; try { // Получаем информацию о товаре const result = await pg.query( 'SELECT owner_id FROM lab11.shop_products WHERE id = $1 AND is_active = true', [productId] ); if (result.rowCount === 0) { reply.code(404).send({ error: 'Product not found' }); return; } const product = result.rows[0]; const canEdit = request.user.role === 'admin' || (request.user.role === 'user' && product.owner_id === request.user.id); return { can_edit: canEdit, product_id: productId, user_role: request.user.role, is_owner: product.owner_id === request.user.id }; } catch (error) { console.error('Check edit error:', error); reply.code(500).send({ error: 'Internal server error' }); } }); // Магазин: удаление товара fastify.delete("/shop/products/:id", { onRequest: [fastify.authenticate] }, async (request, reply) => { const pg = fastify.pg; const productId = request.params.id; try { // Получаем информацию о товаре const productResult = await pg.query( 'SELECT owner_id FROM lab11.shop_products WHERE id = $1', [productId] ); if (productResult.rowCount === 0) { reply.code(404).send({ error: 'Product not found' }); return; } const product = productResult.rows[0]; // Проверяем права на удаление if (request.user.role !== 'admin' && product.owner_id !== request.user.id) { reply.code(403).send({ error: 'You can only delete your own products' }); return; } // Мягкое удаление (устанавливаем is_active = false) await pg.query( 'UPDATE lab11.shop_products SET is_active = false WHERE id = $1', [productId] ); return { success: true, message: 'Product deleted' }; } catch (error) { console.error('Delete product error:', error); reply.code(500).send({ error: 'Internal server error' }); } }); // Расписание: получение событий fastify.get("/schedule/events", async (request, reply) => { const pg = fastify.pg; try { // Проверяем, существуют ли таблицы const tableExists = await pg.query(` SELECT EXISTS ( SELECT FROM information_schema.tables WHERE table_schema = 'lab11' AND table_name = 'schedule_events' ) `); if (!tableExists.rows[0].exists) { reply.code(500).send({ error: 'Таблица schedule_events не существует. Выполните SQL скрипт для создания таблиц.' }); return; } // Получаем события let query = ` SELECT e.*, u.login as owner_name, CASE WHEN e.owner_id = $1 THEN true ELSE false END as is_owner FROM lab11.schedule_events e LEFT JOIN lab11.users u ON e.owner_id = u.id WHERE e.is_public = true OR e.owner_id = $1 ORDER BY e.start_time ASC `; const result = await pg.query(query, [request.user?.id || 0]); // Добавляем информацию о правах доступа const events = result.rows.map(event => ({ ...event, can_edit: request.user?.role === 'admin' || (request.user?.role === 'user' && event.owner_id === request.user?.id) })); return events; } catch (error) { console.error('Schedule events error:', error); reply.code(500).send({ error: 'Internal server error' }); } }); // Расписание: получение конкретного события fastify.get("/schedule/events/:id", { onRequest: [fastify.authenticate] }, async (request, reply) => { const pg = fastify.pg; const eventId = request.params.id; try { // Получаем событие с информацией о владельце const eventResult = await pg.query( `SELECT e.*, u.login as owner_name FROM lab11.schedule_events e LEFT JOIN lab11.users u ON e.owner_id = u.id WHERE e.id = $1`, [eventId] ); if (eventResult.rowCount === 0) { reply.code(404).send({ error: 'Event not found' }); return; } const event = eventResult.rows[0]; // Проверяем, может ли пользователь просматривать событие if (!event.is_public && event.owner_id !== request.user.id && request.user.role !== 'admin') { reply.code(403).send({ error: 'Access denied' }); return; } return event; } catch (error) { console.error('Get event error:', error); reply.code(500).send({ error: 'Internal server error' }); } }); // Расписание: добавление события fastify.post("/schedule/events", { onRequest: [fastify.authenticate] }, async (request, reply) => { const pg = fastify.pg; const { title, description, start_time, end_time, location, category, is_public, color } = request.body; // Проверяем, что пользователь имеет право добавлять события if (request.user.role === 'guest') { reply.code(403).send({ error: 'Only authenticated users can add events' }); return; } // Проверяем, что end_time > start_time if (new Date(end_time) <= new Date(start_time)) { reply.code(400).send({ error: 'End time must be after start time' }); return; } try { const result = await pg.query(` INSERT INTO lab11.schedule_events (title, description, start_time, end_time, location, owner_id, is_public, category, color) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING * `, [title, description, start_time, end_time, location, request.user.id, is_public, category, color || '#3788d8']); reply.code(201); return result.rows[0]; } catch (error) { console.error('Add event error:', error); reply.code(500).send({ error: 'Internal server error' }); } }); // Магазин: редактирование товара fastify.put("/shop/products/:id", { onRequest: [fastify.authenticate] }, async (request, reply) => { const pg = fastify.pg; const productId = request.params.id; const { name, description, price, category, quantity, image_url } = request.body; try { // Проверяем права на редактирование const productResult = await pg.query( 'SELECT owner_id FROM lab11.shop_products WHERE id = $1 AND is_active = true', [productId] ); if (productResult.rowCount === 0) { reply.code(404).send({ error: 'Product not found' }); return; } const product = productResult.rows[0]; // Проверяем права доступа if (request.user.role !== 'admin' && product.owner_id !== request.user.id) { reply.code(403).send({ error: 'You can only edit your own products' }); return; } // Обновляем товар const result = await pg.query(` UPDATE lab11.shop_products SET name = $1, description = $2, price = $3, category = $4, quantity = $5, image_url = $6, updated_at = CURRENT_TIMESTAMP WHERE id = $7 RETURNING * `, [name, description, price, category, quantity, image_url, productId]); return result.rows[0]; } catch (error) { console.error('Update product error:', error); reply.code(500).send({ error: 'Internal server error' }); } }); // Расписание: проверка прав на редактирование fastify.get("/schedule/events/:id/check-edit", { onRequest: [fastify.authenticate] }, async (request, reply) => { const pg = fastify.pg; const eventId = request.params.id; try { const result = await pg.query( 'SELECT owner_id FROM lab11.schedule_events WHERE id = $1', [eventId] ); if (result.rowCount === 0) { reply.code(404).send({ error: 'Event not found' }); return; } const event = result.rows[0]; const canEdit = request.user.role === 'admin' || (request.user.role === 'user' && event.owner_id === request.user.id); return { can_edit: canEdit, event_id: eventId, user_role: request.user.role, is_owner: event.owner_id === request.user.id }; } catch (error) { console.error('Check edit error:', error); reply.code(500).send({ error: 'Internal server error' }); } }); // Расписание: удаление события fastify.delete("/schedule/events/:id", { onRequest: [fastify.authenticate] }, async (request, reply) => { const pg = fastify.pg; const eventId = request.params.id; try { // Получаем информацию о событии const eventResult = await pg.query( 'SELECT owner_id FROM lab11.schedule_events WHERE id = $1', [eventId] ); if (eventResult.rowCount === 0) { reply.code(404).send({ error: 'Event not found' }); return; } const event = eventResult.rows[0]; // Проверяем права на удаление if (request.user.role !== 'admin' && event.owner_id !== request.user.id) { reply.code(403).send({ error: 'You can only delete your own events' }); return; } await pg.query( 'DELETE FROM lab11.schedule_events WHERE id = $1', [eventId] ); return { success: true, message: 'Event deleted' }; } catch (error) { console.error('Delete event error:', error); reply.code(500).send({ error: 'Internal server error' }); } }); }