import re import logging import requests import threading from datetime import datetime from config import Config config = Config() def sanitize_announcement(message: str) -> str: if not isinstance(message, str): return "" message = message.strip() if not message: return "" message = re.sub(r'<[^>]+>', '', message) message = re.sub(r'(javascript|data|vbscript):', '', message, flags=re.IGNORECASE) message = re.sub(r'\s*on\w+\s*=', '', message, flags=re.IGNORECASE) message = message[:500] return message def validate_announcement(message: str) -> tuple[bool, str]: if not isinstance(message, str): return False, "Message must be a string" if len(message.strip()) == 0: return False, "Message cannot be empty" if len(message) > 500: return False, "Message is too long (max 500 characters)" suspicious_patterns = [ r' bool: if not config.DISCORD_ADMIN_LOGS_WEBHOOK: logging.warning("Discord webhook not configured for announcement logging") return False if avatar_url is None: avatar_url = f"https://www.nexium.fit/Thumbs/Head.ashx?x=48&y=48&userId={str(user_id)}" embed = { "type": "rich", "title": f"Website Announcement {action.capitalize()}", "description": message if message else "(empty message)", "color": 0x2196F3, "author": { "name": username, "icon_url": avatar_url }, "footer": { "text": "NEXIUM - Announcement Logs" }, "timestamp": datetime.utcnow().isoformat() } def send_webhook(): try: response = requests.post( url=config.DISCORD_ADMIN_LOGS_WEBHOOK, json={ "username": "NEXIUM - Announcement Logs", "embeds": [embed], "avatar_url": avatar_url }, timeout=15 ) if response.status_code not in [200, 204]: logging.warning( f"Failed to log announcement to Discord: " f"status={response.status_code}, response={response.text}" ) return False return True except Exception as e: logging.error(f"Exception while logging announcement to Discord: {str(e)}") return False thread = threading.Thread(target=send_webhook) thread.daemon = True thread.start() return True