import express from 'express'; import mongoose from 'mongoose'; import dotenv from 'dotenv'; import jwt from 'jsonwebtoken'; import User, { IUser } from './models/User'; import ShopItem from './models/ShopItem'; dotenv.config(); // Расширяем типы Express declare global { namespace Express { interface Request { user?: { userId: string; telegramId: string; } } } } const app = express(); app.use(express.json()); // Подключение к MongoDB mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost:27017/campfire-id') .then(() => console.log('Connected to MongoDB')) .catch(err => console.error('MongoDB connection error:', err)); // Middleware для проверки JWT const authenticateToken = (req: express.Request, res: express.Response, next: express.NextFunction) => { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (!token) { return res.status(401).json({ error: 'Требуется авторизация' }); } jwt.verify(token, process.env.JWT_SECRET || 'your-secret-key', (err: any, user: any) => { if (err) { return res.status(403).json({ error: 'Недействительный токен' }); } req.user = user; next(); }); }; // Регистрация/авторизация пользователя app.post('/api/auth', async (req, res) => { try { const { telegramId, username } = req.body; let user = await User.findOne({ telegramId }); if (!user) { user = new User({ telegramId, username, // Начальный бонус для новых пользователей balance: 100 }); await user.save(); } const token = jwt.sign( { userId: user._id, telegramId }, process.env.JWT_SECRET || 'your-secret-key', { expiresIn: '7d' } ); res.json({ token, user }); } catch (error) { res.status(500).json({ error: 'Ошибка сервера' }); } }); // Получение профиля пользователя app.get('/api/profile', authenticateToken, async (req, res) => { try { const user = await User.findById(req.user.userId); if (!user) { return res.status(404).json({ error: 'Пользователь не найден' }); } res.json(user); } catch (error) { res.status(500).json({ error: 'Ошибка сервера' }); } }); // Получение списка предметов в магазине app.get('/api/shop', authenticateToken, async (req, res) => { try { const items = await ShopItem.find({ available: true }); res.json(items); } catch (error) { res.status(500).json({ error: 'Ошибка сервера' }); } }); // Покупка предмета app.post('/api/shop/purchase', authenticateToken, async (req, res) => { try { const { itemId } = req.body; const user = await User.findById(req.user.userId); const item = await ShopItem.findById(itemId); if (!user || !item) { return res.status(404).json({ error: 'Пользователь или предмет не найден' }); } if (user.balance < item.price) { return res.status(400).json({ error: 'Недостаточно средств' }); } // Обновляем баланс и инвентарь user.balance -= item.price; const existingItem = user.inventory.find(i => i.itemId === itemId); if (existingItem) { existingItem.quantity += 1; } else { user.inventory.push({ itemId: item._id, name: item.name, description: item.description, quantity: 1, imageUrl: item.imageUrl }); } await user.save(); res.json({ success: true, user }); } catch (error) { res.status(500).json({ error: 'Ошибка сервера' }); } }); // Перевод баланса между пользователями app.post('/api/transfer', authenticateToken, async (req, res) => { try { const { recipientUsername, amount } = req.body; if (amount <= 0) { return res.status(400).json({ error: 'Неверная сумма перевода' }); } const sender = await User.findById(req.user.userId); const recipient = await User.findOne({ username: recipientUsername }); if (!sender || !recipient) { return res.status(404).json({ error: 'Отправитель или получатель не найден' }); } if (sender.balance < amount) { return res.status(400).json({ error: 'Недостаточно средств' }); } // Выполняем перевод sender.balance -= amount; recipient.balance += amount; await sender.save(); await recipient.save(); // Добавляем достижение за первый перевод if (sender.achievements.every(a => a.id !== 'first_transfer')) { await sender.addAchievement({ id: 'first_transfer', name: 'Щедрая душа', description: 'Совершили первый перевод', dateUnlocked: new Date() }); } res.json({ success: true, balance: sender.balance }); } catch (error) { res.status(500).json({ error: 'Ошибка сервера' }); } }); const PORT = process.env.PORT || 3001; app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); });