/
lostSun
/
project-client-server-apps
Обзор
Документация
Войти
/
lostSun
/
project-client-server-apps
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
server/src/index.js
263 строки
7 KB
1lostsun
update project
25 май 2025, 13:12
25 май 2025, 13:12
78a0079
Код
Авторство
О чём код?
require('dotenv').config(); const express = require('express'); const cors = require('cors'); const sqlite3 = require('sqlite3').verbose(); const path = require('path'); const authRoutes = require('./routes/auth'); const productRoutes = require('./routes/products'); const cartRoutes = require('./routes/cart'); const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); const app = express(); const PORT = process.env.PORT || 3001; const JWT_SECRET = 'your-secret-key'; // В продакшене использовать переменные окружения // Middleware app.use(cors()); app.use(express.json()); // Database connection const db = new sqlite3.Database(path.join(__dirname, 'db/database.sqlite')); // Middleware для проверки JWT const authenticateToken = (req, res, next) => { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (!token) { return res.status(401).json({ error: 'Требуется авторизация' }); } jwt.verify(token, JWT_SECRET, (err, user) => { if (err) { return res.status(403).json({ error: 'Недействительный токен' }); } req.user = user; next(); }); }; // Регистрация app.post('/api/register', async (req, res) => { const { username, email, password } = req.body; if (!username || !email || !password) { return res.status(400).json({ error: 'Все поля обязательны' }); } try { const hashedPassword = await bcrypt.hash(password, 10); db.run( 'INSERT INTO users (username, email, password) VALUES (?, ?, ?)', [username, email, hashedPassword], function(err) { if (err) { if (err.message.includes('UNIQUE constraint failed')) { return res.status(400).json({ error: 'Пользователь уже существует' }); } return res.status(500).json({ error: 'Ошибка сервера' }); } const token = jwt.sign({ id: this.lastID, username }, JWT_SECRET); res.json({ token, username }); } ); } catch (error) { res.status(500).json({ error: 'Ошибка сервера' }); } }); // Авторизация app.post('/api/login', (req, res) => { const { email, password } = req.body; if (!email || !password) { return res.status(400).json({ error: 'Все поля обязательны' }); } db.get( 'SELECT * FROM users WHERE email = ?', [email], async (err, user) => { if (err) { return res.status(500).json({ error: 'Ошибка сервера' }); } if (!user) { return res.status(401).json({ error: 'Неверный email или пароль' }); } const validPassword = await bcrypt.compare(password, user.password); if (!validPassword) { return res.status(401).json({ error: 'Неверный email или пароль' }); } const token = jwt.sign({ id: user.id, username: user.username }, JWT_SECRET); res.json({ token, username: user.username }); } ); }); // Получение информации о пользователе app.get('/api/user', authenticateToken, (req, res) => { res.json({ id: req.user.id, username: req.user.username }); }); // Сохранение книги в профиле app.post('/api/user/books/:bookId', authenticateToken, (req, res) => { const { bookId } = req.params; const userId = req.user.id; db.run( 'INSERT INTO user_books (user_id, book_id) VALUES (?, ?)', [userId, bookId], (err) => { if (err) { if (err.message.includes('UNIQUE constraint failed')) { return res.status(400).json({ error: 'Книга уже сохранена' }); } return res.status(500).json({ error: 'Ошибка сервера' }); } res.json({ message: 'Книга сохранена' }); } ); }); // Получение сохраненных книг пользователя app.get('/api/user/books', authenticateToken, (req, res) => { db.all( `SELECT books.* FROM books JOIN user_books ON books.id = user_books.book_id WHERE user_books.user_id = ?`, [req.user.id], (err, books) => { if (err) { return res.status(500).json({ error: 'Ошибка сервера' }); } res.json(books); } ); }); // Routes app.get('/api/books', (req, res) => { db.all('SELECT * FROM books ORDER BY created_at DESC', (err, rows) => { if (err) { res.status(500).json({ error: err.message }); return; } res.json(rows); }); }); app.get('/api/books/:id', (req, res) => { db.get('SELECT * FROM books WHERE id = ?', [req.params.id], (err, row) => { if (err) { res.status(500).json({ error: err.message }); return; } if (!row) { res.status(404).json({ error: 'Book not found' }); return; } res.json(row); }); }); app.post('/api/books', (req, res) => { const { title, author, description, year, isbn } = req.body; if (!title || !author) { res.status(400).json({ error: 'Title and author are required' }); return; } const sql = ` INSERT INTO books (title, author, description, year, isbn) VALUES (?, ?, ?, ?, ?) `; db.run(sql, [title, author, description, year, isbn], function(err) { if (err) { res.status(500).json({ error: err.message }); return; } db.get('SELECT * FROM books WHERE id = ?', [this.lastID], (err, row) => { if (err) { res.status(500).json({ error: err.message }); return; } res.status(201).json(row); }); }); }); app.put('/api/books/:id', (req, res) => { const { title, author, description, year, isbn } = req.body; if (!title || !author) { res.status(400).json({ error: 'Title and author are required' }); return; } const sql = ` UPDATE books SET title = ?, author = ?, description = ?, year = ?, isbn = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ? `; db.run(sql, [title, author, description, year, isbn, req.params.id], function(err) { if (err) { res.status(500).json({ error: err.message }); return; } if (this.changes === 0) { res.status(404).json({ error: 'Book not found' }); return; } db.get('SELECT * FROM books WHERE id = ?', [req.params.id], (err, row) => { if (err) { res.status(500).json({ error: err.message }); return; } res.json(row); }); }); }); app.delete('/api/books/:id', (req, res) => { db.run('DELETE FROM books WHERE id = ?', [req.params.id], function(err) { if (err) { res.status(500).json({ error: err.message }); return; } if (this.changes === 0) { res.status(404).json({ error: 'Book not found' }); return; } res.status(204).send(); }); }); // Маршруты app.use('/api/auth', authRoutes); app.use('/api/products', productRoutes); app.use('/api/cart', cartRoutes); // Базовый маршрут для проверки работы API app.get('/', (req, res) => { res.json({ message: 'Welcome to the E-commerce API' }); }); app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); });