Update files
This commit is contained in:
parent
a93c95158f
commit
299f872020
|
|
@ -15,6 +15,7 @@ JWT_REFRESH_EXPIRES_IN=604800
|
||||||
# Telegram Bot Configuration
|
# Telegram Bot Configuration
|
||||||
TELEGRAM_BOT_TOKEN=your_telegram_bot_token
|
TELEGRAM_BOT_TOKEN=your_telegram_bot_token
|
||||||
MODERATION_BOT_TOKEN=your_moderation_bot_token
|
MODERATION_BOT_TOKEN=your_moderation_bot_token
|
||||||
|
MODERATION_BOT_USERNAME=your_moderation_bot_username # Опционально: будет получен через Bot API если не указан
|
||||||
MODERATION_OWNER_USERNAMES=glpshchn00
|
MODERATION_OWNER_USERNAMES=glpshchn00
|
||||||
MODERATION_CHANNEL_USERNAME=@reichenbfurry
|
MODERATION_CHANNEL_USERNAME=@reichenbfurry
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ module.exports = {
|
||||||
// Telegram
|
// Telegram
|
||||||
telegramBotToken: process.env.TELEGRAM_BOT_TOKEN,
|
telegramBotToken: process.env.TELEGRAM_BOT_TOKEN,
|
||||||
moderationBotToken: process.env.MODERATION_BOT_TOKEN || process.env.SERVER_MONITOR_BOT_TOKEN || '7604181694:AAGmnpWtR2rknbZreWNoU3PtVWMFJdlwVmc',
|
moderationBotToken: process.env.MODERATION_BOT_TOKEN || process.env.SERVER_MONITOR_BOT_TOKEN || '7604181694:AAGmnpWtR2rknbZreWNoU3PtVWMFJdlwVmc',
|
||||||
|
moderationBotUsername: process.env.MODERATION_BOT_USERNAME || null, // Будет получен через Bot API если не указан
|
||||||
moderationOwnerUsernames: (process.env.MODERATION_OWNER_USERNAMES || 'glpshchn00')
|
moderationOwnerUsernames: (process.env.MODERATION_OWNER_USERNAMES || 'glpshchn00')
|
||||||
.split(',')
|
.split(',')
|
||||||
.map((name) => name.trim().toLowerCase())
|
.map((name) => name.trim().toLowerCase())
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const bcrypt = require('bcryptjs');
|
const bcrypt = require('bcryptjs');
|
||||||
|
const axios = require('axios');
|
||||||
const User = require('../models/User');
|
const User = require('../models/User');
|
||||||
const EmailVerificationCode = require('../models/EmailVerificationCode');
|
const EmailVerificationCode = require('../models/EmailVerificationCode');
|
||||||
const { sendVerificationCode } = require('../utils/email');
|
const { sendVerificationCode } = require('../utils/email');
|
||||||
|
|
@ -9,6 +10,10 @@ const { signAuthTokens, setAuthCookies, clearAuthCookies, verifyAccessToken } =
|
||||||
const { logSecurityEvent } = require('../middleware/logger');
|
const { logSecurityEvent } = require('../middleware/logger');
|
||||||
const { authenticateModeration } = require('../middleware/auth');
|
const { authenticateModeration } = require('../middleware/auth');
|
||||||
const { isEmail } = require('validator');
|
const { isEmail } = require('validator');
|
||||||
|
const config = require('../config');
|
||||||
|
|
||||||
|
// Кэш для username бота модерации
|
||||||
|
let cachedModerationBotUsername = null;
|
||||||
|
|
||||||
// Rate limiting для авторизации
|
// Rate limiting для авторизации
|
||||||
const rateLimit = require('express-rate-limit');
|
const rateLimit = require('express-rate-limit');
|
||||||
|
|
@ -371,6 +376,52 @@ router.post('/logout', (req, res) => {
|
||||||
res.json({ success: true });
|
res.json({ success: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Получить конфигурацию для фронтенда (включая bot username)
|
||||||
|
router.get('/config', async (req, res) => {
|
||||||
|
try {
|
||||||
|
// Если username указан в env - используем его
|
||||||
|
if (config.moderationBotUsername) {
|
||||||
|
return res.json({
|
||||||
|
botUsername: config.moderationBotUsername
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если есть кэш - используем его
|
||||||
|
if (cachedModerationBotUsername) {
|
||||||
|
return res.json({
|
||||||
|
botUsername: cachedModerationBotUsername
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получить username через Bot API используя MODERATION_BOT_TOKEN
|
||||||
|
if (config.moderationBotToken) {
|
||||||
|
try {
|
||||||
|
const botInfo = await axios.get(`https://api.telegram.org/bot${config.moderationBotToken}/getMe`);
|
||||||
|
const username = botInfo.data.result?.username;
|
||||||
|
|
||||||
|
if (username) {
|
||||||
|
cachedModerationBotUsername = username;
|
||||||
|
return res.json({
|
||||||
|
botUsername: username
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Ошибка получения username бота модерации через Bot API:', error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback
|
||||||
|
res.json({
|
||||||
|
botUsername: 'moderation_bot'
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Ошибка получения конфигурации:', error);
|
||||||
|
res.json({
|
||||||
|
botUsername: cachedModerationBotUsername || 'moderation_bot'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Проверка текущей сессии
|
// Проверка текущей сессии
|
||||||
router.get('/me', async (req, res) => {
|
router.get('/me', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,7 @@ services:
|
||||||
- MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY}
|
- MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY}
|
||||||
- MINIO_SECRET_KEY=${MINIO_SECRET_KEY}
|
- MINIO_SECRET_KEY=${MINIO_SECRET_KEY}
|
||||||
- MINIO_BUCKET=${MINIO_BUCKET:-nakama-media}
|
- MINIO_BUCKET=${MINIO_BUCKET:-nakama-media}
|
||||||
|
- MINIO_REGION=${MINIO_REGION:-us-east-1}
|
||||||
networks:
|
networks:
|
||||||
- nakama-network
|
- nakama-network
|
||||||
healthcheck:
|
healthcheck:
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ dotenv.config({ path: rootEnvPath });
|
||||||
|
|
||||||
const config = require('../../backend/config');
|
const config = require('../../backend/config');
|
||||||
const { initWebSocket } = require('../../backend/websocket');
|
const { initWebSocket } = require('../../backend/websocket');
|
||||||
|
const { initMinioClient, checkConnection: checkMinioConnection } = require('../../backend/utils/minio');
|
||||||
|
const { printMinioConfig } = require('../../backend/utils/minioDebug');
|
||||||
|
const { log, logSuccess, logError } = require('../../backend/middleware/logger');
|
||||||
|
|
||||||
// Security middleware
|
// Security middleware
|
||||||
const {
|
const {
|
||||||
|
|
@ -97,6 +100,35 @@ mongoose.connect(config.mongoUri)
|
||||||
mongoose.connection.on('reconnected', () => {
|
mongoose.connection.on('reconnected', () => {
|
||||||
console.log('✅ MongoDB переподключена');
|
console.log('✅ MongoDB переподключена');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Инициализировать MinIO (опционально)
|
||||||
|
if (config.minio.enabled) {
|
||||||
|
try {
|
||||||
|
log('info', 'Инициализация MinIO для модерации...');
|
||||||
|
|
||||||
|
// Вывести конфигурацию и проверки
|
||||||
|
printMinioConfig();
|
||||||
|
|
||||||
|
initMinioClient();
|
||||||
|
const minioOk = await checkMinioConnection();
|
||||||
|
if (minioOk) {
|
||||||
|
logSuccess('MinIO успешно подключен для модерации', {
|
||||||
|
endpoint: `${config.minio.endpoint}:${config.minio.port}`,
|
||||||
|
bucket: config.minio.bucket,
|
||||||
|
ssl: config.minio.useSSL
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
log('warn', 'MinIO недоступен, используется локальное хранилище');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
logError('MinIO initialization failed for moderation', err, {
|
||||||
|
endpoint: `${config.minio.endpoint}:${config.minio.port}`
|
||||||
|
});
|
||||||
|
log('warn', 'Используется локальное хранилище');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log('info', 'MinIO отключен, используется локальное хранилище');
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.error('❌ Не удалось подключиться к MongoDB:', err);
|
console.error('❌ Не удалось подключиться к MongoDB:', err);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@ import {
|
||||||
confirmRemoveAdmin,
|
confirmRemoveAdmin,
|
||||||
getPostComments,
|
getPostComments,
|
||||||
deleteComment,
|
deleteComment,
|
||||||
getApiUrl
|
getApiUrl,
|
||||||
|
getModerationConfig
|
||||||
} from './utils/api';
|
} from './utils/api';
|
||||||
import { io } from 'socket.io-client';
|
import { io } from 'socket.io-client';
|
||||||
import {
|
import {
|
||||||
|
|
@ -126,6 +127,9 @@ export default function App() {
|
||||||
const [commentsModal, setCommentsModal] = useState(null); // { postId, comments: [] }
|
const [commentsModal, setCommentsModal] = useState(null); // { postId, comments: [] }
|
||||||
const [commentsLoading, setCommentsLoading] = useState(false);
|
const [commentsLoading, setCommentsLoading] = useState(false);
|
||||||
|
|
||||||
|
// Конфигурация (bot username)
|
||||||
|
const [moderationBotUsername, setModerationBotUsername] = useState('moderation_bot');
|
||||||
|
|
||||||
// Форма авторизации
|
// Форма авторизации
|
||||||
const [authForm, setAuthForm] = useState({
|
const [authForm, setAuthForm] = useState({
|
||||||
step: 'login', // 'login', 'register-step1', 'register-step2'
|
step: 'login', // 'login', 'register-step1', 'register-step2'
|
||||||
|
|
@ -137,6 +141,21 @@ export default function App() {
|
||||||
});
|
});
|
||||||
const [authLoading, setAuthLoading] = useState(false);
|
const [authLoading, setAuthLoading] = useState(false);
|
||||||
|
|
||||||
|
// Загрузить конфигурацию бота при монтировании
|
||||||
|
useEffect(() => {
|
||||||
|
const loadConfig = async () => {
|
||||||
|
try {
|
||||||
|
const config = await getModerationConfig();
|
||||||
|
if (config.botUsername) {
|
||||||
|
setModerationBotUsername(config.botUsername);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('Не удалось загрузить конфигурацию бота:', err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
loadConfig();
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let cancelled = false;
|
let cancelled = false;
|
||||||
|
|
||||||
|
|
@ -280,7 +299,7 @@ export default function App() {
|
||||||
const script = document.createElement('script');
|
const script = document.createElement('script');
|
||||||
script.async = true;
|
script.async = true;
|
||||||
script.src = 'https://telegram.org/js/telegram-widget.js?22';
|
script.src = 'https://telegram.org/js/telegram-widget.js?22';
|
||||||
script.setAttribute('data-telegram-login', 'NakamaSpaceBot');
|
script.setAttribute('data-telegram-login', moderationBotUsername);
|
||||||
script.setAttribute('data-size', 'large');
|
script.setAttribute('data-size', 'large');
|
||||||
script.setAttribute('data-request-access', 'write');
|
script.setAttribute('data-request-access', 'write');
|
||||||
script.setAttribute('data-onauth', 'onTelegramAuth');
|
script.setAttribute('data-onauth', 'onTelegramAuth');
|
||||||
|
|
@ -312,7 +331,7 @@ export default function App() {
|
||||||
delete window.onTelegramAuth;
|
delete window.onTelegramAuth;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [error, user, loading]);
|
}, [error, user, loading, moderationBotUsername]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (tab === 'users') {
|
if (tab === 'users') {
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,9 @@ export const logout = () => {
|
||||||
export const getCurrentUser = () =>
|
export const getCurrentUser = () =>
|
||||||
api.get('/moderation-auth/me').then((res) => res.data.user)
|
api.get('/moderation-auth/me').then((res) => res.data.user)
|
||||||
|
|
||||||
|
export const getModerationConfig = () =>
|
||||||
|
api.get('/moderation-auth/config').then((res) => res.data)
|
||||||
|
|
||||||
export const verifyAuth = () => api.post('/mod-app/auth/verify').then((res) => res.data.user)
|
export const verifyAuth = () => api.post('/mod-app/auth/verify').then((res) => res.data.user)
|
||||||
|
|
||||||
export const fetchUsers = (params = {}) =>
|
export const fetchUsers = (params = {}) =>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue