From 66ff498fa0e7acedad81d84c352f52db1a53980c Mon Sep 17 00:00:00 2001 From: degradin Date: Sun, 16 Mar 2025 11:53:27 +0300 Subject: [PATCH] up --- .env | 6 ++++++ app/utils/api.ts | 45 +++++++++++++++++++++++++++++++++++++++------ backend/server.ts | 27 +++++++++++++++++++++++++-- package-lock.json | 24 ++++++++++++++++++++++++ package.json | 32 +++++++++++++++++--------------- 5 files changed, 111 insertions(+), 23 deletions(-) diff --git a/.env b/.env index a8ebff1..b7b120a 100644 --- a/.env +++ b/.env @@ -1,5 +1,6 @@ MONGODB_URI=mongodb://localhost:27017/campfire JWT_SECRET=your-super-secret-key-change-in-production +<<<<<<< Updated upstream PORT=3000 # Telegram Bot TELEGRAM_BOT_TOKEN=7641998551:AAF_2-av1rUy_-icQ1fsfHOyYBGFt8cEmE4 @@ -12,4 +13,9 @@ JWT_SECRET=your_jwt_secret_here # App NEXT_PUBLIC_APP_URL=http://localhost:3000 +======= +PORT=3001 +NEXT_PUBLIC_URL=http://localhost:3000 +NEXT_PUBLIC_API_URL=http://localhost:3001/api +>>>>>>> Stashed changes NODE_ENV=development \ No newline at end of file diff --git a/app/utils/api.ts b/app/utils/api.ts index 368d047..d2db4f9 100644 --- a/app/utils/api.ts +++ b/app/utils/api.ts @@ -2,21 +2,54 @@ import axios from 'axios'; const api = axios.create({ baseURL: process.env.NEXT_PUBLIC_API_URL, + withCredentials: true, + headers: { + 'Content-Type': 'application/json', + }, + timeout: 10000, // 10 секунд таймаут }); // Интерцептор для добавления токена к запросам api.interceptors.request.use((config) => { - const token = localStorage.getItem('token'); - if (token) { - config.headers.Authorization = `Bearer ${token}`; + if (typeof window !== 'undefined') { + const token = localStorage.getItem('token'); + if (token) { + config.headers.Authorization = `Bearer ${token}`; + } } return config; +}, (error) => { + return Promise.reject(error); }); +// Интерцептор для обработки ошибок +api.interceptors.response.use( + (response) => response, + (error) => { + if (error.response) { + // Ошибка от сервера + return Promise.reject(error.response.data); + } else if (error.request) { + // Ошибка сети + return Promise.reject({ error: 'Ошибка сети. Проверьте подключение к интернету.' }); + } else { + // Другие ошибки + return Promise.reject({ error: 'Произошла ошибка при выполнении запроса.' }); + } + } +); + export const auth = async (telegramId: string, username: string) => { - const response = await api.post('/auth', { telegramId, username }); - localStorage.setItem('token', response.data.token); - return response.data; + try { + const response = await api.post('/auth', { telegramId, username }); + if (typeof window !== 'undefined') { + localStorage.setItem('token', response.data.token); + } + return response.data; + } catch (error) { + console.error('Auth error:', error); + throw error; + } }; export const getProfile = async () => { diff --git a/backend/server.ts b/backend/server.ts index cb47c58..1699344 100644 --- a/backend/server.ts +++ b/backend/server.ts @@ -2,6 +2,7 @@ import express from 'express'; import mongoose from 'mongoose'; import dotenv from 'dotenv'; import jwt from 'jsonwebtoken'; +import cors from 'cors'; import User, { IUser } from './models/User'; import ShopItem from './models/ShopItem'; @@ -20,6 +21,12 @@ declare global { } const app = express(); + +// Middleware +app.use(cors({ + origin: process.env.NEXT_PUBLIC_URL || 'http://localhost:3000', + credentials: true +})); app.use(express.json()); // Подключение к MongoDB @@ -45,11 +52,24 @@ const authenticateToken = (req: express.Request, res: express.Response, next: ex }); }; +// Обработка ошибок +const errorHandler = (err: any, req: express.Request, res: express.Response, next: express.NextFunction) => { + console.error(err.stack); + res.status(500).json({ + error: 'Ошибка сервера', + message: process.env.NODE_ENV === 'development' ? err.message : undefined + }); +}; + // Регистрация/авторизация пользователя -app.post('/api/auth', async (req, res) => { +app.post('/api/auth', async (req, res, next) => { try { const { telegramId, username } = req.body; + if (!telegramId || !username) { + return res.status(400).json({ error: 'Отсутствуют обязательные поля' }); + } + let user = await User.findOne({ telegramId }); if (!user) { @@ -70,7 +90,7 @@ app.post('/api/auth', async (req, res) => { res.json({ token, user }); } catch (error) { - res.status(500).json({ error: 'Ошибка сервера' }); + next(error); } }); @@ -178,6 +198,9 @@ app.post('/api/transfer', authenticateToken, async (req, res) => { } }); +// Добавляем обработчик ошибок в конце +app.use(errorHandler); + const PORT = process.env.PORT || 3001; app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); diff --git a/package-lock.json b/package-lock.json index af05477..6ae32e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,8 +12,10 @@ "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@twa-dev/sdk": "^6.9.0", + "@types/cors": "^2.8.17", "axios": "^1.5.1", "bcryptjs": "^2.4.3", + "cors": "^2.8.5", "dotenv": "^16.3.1", "express": "^4.18.2", "framer-motion": "^10.16.4", @@ -1152,6 +1154,15 @@ "@types/node": "*" } }, + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/express": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", @@ -2171,6 +2182,19 @@ "toggle-selection": "^1.0.6" } }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", diff --git a/package.json b/package.json index 63ed8eb..46f4370 100644 --- a/package.json +++ b/package.json @@ -9,28 +9,30 @@ "lint": "next lint" }, "dependencies": { - "next": "^13.5.4", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "@twa-dev/sdk": "^6.9.0", - "mongoose": "^7.5.3", - "express": "^4.18.2", - "jsonwebtoken": "^9.0.2", - "bcryptjs": "^2.4.3", - "dotenv": "^16.3.1", - "axios": "^1.5.1", "@chakra-ui/react": "^2.8.1", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "framer-motion": "^10.16.4" + "@twa-dev/sdk": "^6.9.0", + "@types/cors": "^2.8.17", + "axios": "^1.5.1", + "bcryptjs": "^2.4.3", + "cors": "^2.8.5", + "dotenv": "^16.3.1", + "express": "^4.18.2", + "framer-motion": "^10.16.4", + "jsonwebtoken": "^9.0.2", + "mongoose": "^7.5.3", + "next": "^13.5.4", + "react": "^18.2.0", + "react-dom": "^18.2.0" }, "devDependencies": { - "typescript": "^5.2.2", - "@types/react": "^18.2.25", - "@types/node": "^20.8.3", "@types/express": "^4.17.18", + "@types/node": "^20.8.3", + "@types/react": "^18.2.25", "eslint": "^8.51.0", "eslint-config-next": "13.5.4", - "prettier": "^3.0.3" + "prettier": "^3.0.3", + "typescript": "^5.2.2" } }