From c39c26b52bf35f8ad30e4f451fe3f87b515e6a4f Mon Sep 17 00:00:00 2001 From: glpshchn <464976@niuitmo.ru> Date: Mon, 15 Dec 2025 07:17:54 +0300 Subject: [PATCH] Update files --- backend/routes/modApp.js | 6 +++--- backend/routes/posts.js | 20 ++++++++++---------- moderation/backend-py/websocket_server.py | 15 +++++++++++++++ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/backend/routes/modApp.js b/backend/routes/modApp.js index ec452ad..61f772c 100644 --- a/backend/routes/modApp.js +++ b/backend/routes/modApp.js @@ -286,9 +286,9 @@ router.put('/posts/:id', authenticateModerationFlexible, requireModerationAccess post.content = content; // Обновить хэштеги из контента, если hashtags не переданы явно if (hashtags !== undefined) { - post.hashtags = Array.isArray(hashtags) - ? hashtags.map((tag) => tag.toLowerCase()) - : post.hashtags; + post.hashtags = Array.isArray(hashtags) + ? hashtags.map((tag) => tag.toLowerCase()) + : post.hashtags; } else { // Извлечь хэштеги из контента const { extractHashtags } = require('../utils/hashtags'); diff --git a/backend/routes/posts.js b/backend/routes/posts.js index 1b7b2fc..d53dd56 100644 --- a/backend/routes/posts.js +++ b/backend/routes/posts.js @@ -371,8 +371,8 @@ router.put('/:id', authenticate, async (req, res) => { // Если контент не пустой, валидируем его if (content && content.trim().length > 0) { if (!validatePostContent(content)) { - logSecurityEvent('INVALID_POST_CONTENT', req); - return res.status(400).json({ error: 'Недопустимый контент поста' }); + logSecurityEvent('INVALID_POST_CONTENT', req); + return res.status(400).json({ error: 'Недопустимый контент поста' }); } post.content = content.trim(); // Обновить хэштеги @@ -391,15 +391,15 @@ router.put('/:id', authenticate, async (req, res) => { if (tags !== undefined) { let parsedTags = []; if (tags) { - try { + try { parsedTags = typeof tags === 'string' ? JSON.parse(tags) : tags; - } catch (e) { - return res.status(400).json({ error: 'Неверный формат тегов' }); - } - - if (!validateTags(parsedTags)) { - logSecurityEvent('INVALID_TAGS', req, { tags: parsedTags }); - return res.status(400).json({ error: 'Недопустимые теги' }); + } catch (e) { + return res.status(400).json({ error: 'Неверный формат тегов' }); + } + + if (!validateTags(parsedTags)) { + logSecurityEvent('INVALID_TAGS', req, { tags: parsedTags }); + return res.status(400).json({ error: 'Недопустимые теги' }); } } diff --git a/moderation/backend-py/websocket_server.py b/moderation/backend-py/websocket_server.py index dbdb63d..d83b805 100644 --- a/moderation/backend-py/websocket_server.py +++ b/moderation/backend-py/websocket_server.py @@ -49,13 +49,28 @@ class RootNamespace(socketio.AsyncNamespace): print(f"[WebSocket] Environ keys: {list(environ.keys()) if isinstance(environ, dict) else 'N/A'}") logger.info(f"[WebSocket] Handshake to ROOT namespace: {sid}") # Разрешаем подключение для handshake + # В AsyncNamespace не нужно возвращать True явно, но можно return True + + async def on_disconnect(self, sid): + """Handle disconnection from root namespace""" + print(f"[WebSocket] Client disconnected from ROOT namespace: {sid}") + logger.info(f"[WebSocket] Client disconnected from ROOT namespace: {sid}") # Регистрируем корневой namespace ПЕРЕД созданием ASGI app root_ns = RootNamespace('/') sio.register_namespace(root_ns) print(f"[WebSocket] ✅ Корневой namespace зарегистрирован: {root_ns.namespace}") +# Также добавляем обработчик через декоратор для надежности +@sio.on('connect', namespace='/') +async def on_connect_root_decorator(sid, environ): + """Handle client connection to root namespace (Socket.IO handshake) - декоратор""" + print(f"[WebSocket] 🔄 Handshake to ROOT namespace (decorator): {sid}") + logger.info(f"[WebSocket] Handshake to ROOT namespace (decorator): {sid}") + # Разрешаем подключение для handshake + return True + # Namespace handlers for /mod-chat @sio.on('connect', namespace='/mod-chat') async def on_connect(sid, environ):