Extract 4 self-contained services into services/ module: - server/telegram_bot/ -> services/telegram_bot/ - server/ws_gateway/ -> services/ws_gateway/ - server/corporate_memory/ -> services/corporate_memory/ - server/session_collector.py -> services/session_collector/ Each service now has its own systemd/ directory with .service and .timer files. deploy.sh updated to auto-discover service units from services/*/systemd/*. server/ now contains only deployment infrastructure (deploy.sh, setup scripts, bin/ management tools, sudoers, nginx config). All imports updated: webapp/app.py, server/bin/ scripts, systemd ExecStart paths.
31 lines
855 B
Python
31 lines
855 B
Python
"""JWT authentication for WebSocket Gateway."""
|
|
|
|
import logging
|
|
|
|
import jwt
|
|
|
|
from .config import DESKTOP_JWT_SECRET
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
ALGORITHM = "HS256"
|
|
|
|
|
|
def validate_token(token: str) -> dict | None:
|
|
"""Validate a JWT token and return the payload.
|
|
|
|
Returns the decoded payload dict containing at least "sub" (username)
|
|
and "exp" (expiration), or None if the token is invalid.
|
|
"""
|
|
try:
|
|
payload = jwt.decode(token, DESKTOP_JWT_SECRET, algorithms=[ALGORITHM])
|
|
if "sub" not in payload:
|
|
logger.warning("JWT missing 'sub' claim")
|
|
return None
|
|
return payload
|
|
except jwt.ExpiredSignatureError:
|
|
logger.warning("JWT token expired")
|
|
return None
|
|
except jwt.InvalidTokenError as e:
|
|
logger.warning("Invalid JWT token: %s", e)
|
|
return None
|