diff --git a/ADMIN_CHAT_DEBUG.md b/ADMIN_CHAT_DEBUG.md deleted file mode 100644 index 60ce286..0000000 --- a/ADMIN_CHAT_DEBUG.md +++ /dev/null @@ -1,236 +0,0 @@ -# 🔍 Отладка админского чата - -## Проблема - -Админский чат не подключается в системе модерации. - -## Что проверить - -### 1. Откройте DevTools в системе модерации - -Нажмите F12 и откройте вкладку **Console** - -### 2. Перейдите на вкладку "Чат" - -Должны увидеть логи: - -``` -[Chat] Инициализация чата -[Chat] User данные: { username: "glpshchn00", telegramId: "...", hasUsername: true, hasTelegramId: true } -[Chat] Подключение к: http://localhost:3000/mod-chat -[Chat] ✅ WebSocket подключен, ID: abc123 -[Chat] Отправка auth с данными: { username: "glpshchn00", telegramId: "..." } -``` - -**Затем должно быть:** - -✅ **Успех:** -``` -[Chat] ✅ Авторизация успешна! -``` - -❌ **Ошибка - нет прав:** -``` -[Chat] ❌ Нет прав для доступа к чату -[Chat] user.username: glpshchn00 -[Chat] user.telegramId: 123456789 -[Chat] Вы должны быть в списке MODERATION_OWNER_USERNAMES -``` - -❌ **Ошибка подключения:** -``` -[Chat] ❌ Ошибка подключения: timeout -``` - -## Решения - -### Проблема: "Нет прав доступа" - -**Причина:** Ваш username не в списке админов на сервере. - -**Решение:** - -1. Откройте `.env` на сервере: -```bash -nano .env -``` - -2. Проверьте/добавьте: -```env -MODERATION_OWNER_USERNAMES=glpshchn00 -``` - -3. Перезапустите backend: -```bash -docker-compose restart backend -``` - -4. Проверьте логи: -```bash -docker-compose logs backend | grep "Mod chat" -``` - -Должно быть: -``` -[INFO] Mod chat auth success { username: 'glpshchn00', isOwner: true } -``` - -### Проблема: "Ошибка подключения: timeout" - -**Причина:** Backend недоступен или неправильный URL. - -**Решение:** - -1. Проверьте что backend запущен: -```bash -docker-compose ps backend -``` - -2. Проверьте `VITE_API_URL` в moderation frontend: -```bash -# В docker-compose.yml -environment: - - VITE_API_URL=http://localhost:3000 # Для локальной разработки - - VITE_API_URL=https://ваш-домен.com # Для production -``` - -3. Проверьте CORS в backend `.env`: -```env -CORS_ORIGIN=http://localhost:5174,https://ваш-домен.com -``` - -### Проблема: user.username или user.telegramId пустые - -**Причина:** Пользователь не авторизован. - -**Решение:** - -1. Убедитесь что открыли через Telegram бота -2. Проверьте логи auth: -``` -[Chat] user.username: undefined ← ПРОБЛЕМА! -``` - -3. Попробуйте переоткрыть систему модерации из бота - -### Проблема: WebSocket вообще не подключается - -**Причина:** CORS блокирует WebSocket. - -**Решение:** - -1. Проверьте browser console на ошибки CORS: -``` -Access to XMLHttpRequest at 'http://...' from origin '...' has been blocked by CORS -``` - -2. Добавьте origin в `.env`: -```env -CORS_ORIGIN=http://localhost:5173,http://localhost:5174,https://web.telegram.org -``` - -3. Перезапустите: -```bash -docker-compose restart backend -``` - -## Backend логи - -### Успешное подключение: - -```bash -docker-compose logs backend | tail -20 -``` - -Должно быть: -``` -✅ WebSocket подключен: abc123 -[INFO] Mod chat auth success { username: 'glpshchn00', isOwner: true, isAdmin: false } -``` - -### Ошибка авторизации: - -``` -[WARN] Mod chat auth failed: no username/telegramId -# или -[WARN] Mod chat access denied { username: '...', telegramId: '...' } -``` - -## Быстрая проверка - -### 1. Backend работает? - -```bash -curl http://localhost:3000/health -# Должен вернуть 200 OK -``` - -### 2. WebSocket работает? - -```bash -curl http://localhost:3000/socket.io/ -# Должен вернуть: {"code":0,"message":"Transport unknown"} -# Это нормально - значит WebSocket сервер работает -``` - -### 3. Username в списке? - -```bash -# Проверьте переменную -docker-compose exec backend printenv | grep MODERATION_OWNER -``` - -Должно быть: -``` -MODERATION_OWNER_USERNAMES=glpshchn00 -``` - -## Полная перезагрузка - -Если ничего не помогло: - -```bash -# 1. Остановите всё -docker-compose down - -# 2. Проверьте .env -cat .env | grep -E "MODERATION|CORS" - -# 3. Запустите заново -docker-compose up -d - -# 4. Смотрите логи -docker-compose logs -f backend - -# 5. Переоткройте систему модерации из бота -``` - -## Контрольный список - -- [ ] Backend запущен (`docker-compose ps`) -- [ ] MODERATION_OWNER_USERNAMES содержит ваш username -- [ ] CORS_ORIGIN включает домен системы модерации -- [ ] User авторизован (есть username и telegramId) -- [ ] VITE_API_URL указывает на правильный backend -- [ ] Нет ошибок CORS в browser console -- [ ] WebSocket сервер инициализирован (логи backend) -- [ ] Firewall не блокирует WebSocket порты - -## Если всё еще не работает - -Отправьте в @NakamaReportbot: - -1. Скриншот DevTools Console (вкладка Чат) -2. Логи backend: -```bash -docker-compose logs backend > backend-logs.txt -``` -3. Переменные окружения (без секретов): -```bash -cat .env | grep -v SECRET | grep -v KEY | grep -v PASSWORD > env-safe.txt -``` - ---- - -**После исправления чат должен подключиться автоматически при открытии вкладки "Чат"!** ✅ - diff --git a/ENV_EXAMPLE.txt b/ENV_EXAMPLE.txt index 425bd76..78312c4 100644 --- a/ENV_EXAMPLE.txt +++ b/ENV_EXAMPLE.txt @@ -22,6 +22,10 @@ MODERATION_CHANNEL_USERNAME=@reichenbfurry GELBOORU_API_KEY=your_gelbooru_api_key GELBOORU_USER_ID=your_gelbooru_user_id +# e621 API (обязательно для поиска) +E621_USERNAME=your_e621_username +E621_API_KEY=your_e621_api_key + # Frontend URL FRONTEND_URL=http://localhost:5173 VITE_API_URL=http://localhost:3000/api diff --git a/backend/config/index.js b/backend/config/index.js index aa6ef28..bbc5382 100644 --- a/backend/config/index.js +++ b/backend/config/index.js @@ -36,6 +36,10 @@ module.exports = { gelbooruApiKey: process.env.GELBOORU_API_KEY || '638e2433d451fc02e848811acdafdce08317073c01ed78e38139115c19fe04afa367f736726514ef1337565d4c05b3cbe2c81125c424301e90d29d1f7f4cceff', gelbooruUserId: process.env.GELBOORU_USER_ID || '1844464', + // e621 API + e621Username: process.env.E621_USERNAME || 'glpshchn00', + e621ApiKey: process.env.E621_API_KEY || 'cW2SYnKFJgbViqd6gpC3xu9t', + // Frontend URL frontendUrl: process.env.FRONTEND_URL || 'http://localhost:5173', diff --git a/backend/routes/search.js b/backend/routes/search.js index 7356f1a..803eab0 100644 --- a/backend/routes/search.js +++ b/backend/routes/search.js @@ -4,7 +4,8 @@ const axios = require('axios'); const { authenticate } = require('../middleware/auth'); const config = require('../config'); -const E621_USER_AGENT = 'NakamaSpace/1.0 (by Reichenbach on e621)'; +// e621 требует описательный User-Agent с контактами +const E621_USER_AGENT = 'NakamaApp/1.0 (by glpshchn00 on e621; Telegram: @glpshchn00)'; const CACHE_TTL_MS = 60 * 1000; // 1 минута const searchCache = new Map(); @@ -79,12 +80,21 @@ router.get('/proxy/:encodedUrl', async (req, res) => { } // Запрашиваем изображение + // Для e621 добавляем авторизацию + const headers = { + 'User-Agent': E621_USER_AGENT, + 'Referer': urlObj.origin + }; + + // Если это e621, добавляем авторизацию + if (urlObj.hostname.includes('e621.net')) { + const auth = Buffer.from(`${config.e621Username}:${config.e621ApiKey}`).toString('base64'); + headers['Authorization'] = `Basic ${auth}`; + } + const response = await axios.get(originalUrl, { responseType: 'stream', - headers: { - 'User-Agent': E621_USER_AGENT, - 'Referer': urlObj.origin - }, + headers, timeout: 30000 // 30 секунд таймаут }); @@ -123,6 +133,9 @@ router.get('/furry', authenticate, async (req, res) => { // e621 API автоматически обрабатывает теги через пробел в параметре tags try { + // Базовая авторизация для e621 API + const auth = Buffer.from(`${config.e621Username}:${config.e621ApiKey}`).toString('base64'); + const response = await axios.get('https://e621.net/posts.json', { params: { tags: query.trim(), // Множественные теги через пробел @@ -130,7 +143,8 @@ router.get('/furry', authenticate, async (req, res) => { page: parseInt(page) || 1 }, headers: { - 'User-Agent': E621_USER_AGENT + 'User-Agent': E621_USER_AGENT, + 'Authorization': `Basic ${auth}` }, timeout: 30000, validateStatus: (status) => status < 500 // Не бросать ошибку для 429 @@ -275,6 +289,9 @@ router.get('/furry/tags', authenticate, async (req, res) => { } try { + // Базовая авторизация для e621 API + const auth = Buffer.from(`${config.e621Username}:${config.e621ApiKey}`).toString('base64'); + const response = await axios.get('https://e621.net/tags.json', { params: { 'search[name_matches]': `${query}*`, @@ -282,7 +299,8 @@ router.get('/furry/tags', authenticate, async (req, res) => { limit: 10 }, headers: { - 'User-Agent': E621_USER_AGENT + 'User-Agent': E621_USER_AGENT, + 'Authorization': `Basic ${auth}` }, timeout: 10000, validateStatus: (status) => status < 500 // Не бросать ошибку для 429