diff --git a/backend/app.py b/backend/app.py index 9d50df7..401dc3e 100644 --- a/backend/app.py +++ b/backend/app.py @@ -44,7 +44,8 @@ def serve_frontend(path): return redirect('/setup') if path.startswith('setup') or path.startswith('api'): - return redirect(f'/{path}') + from flask import abort + abort(404) dist_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'frontend', 'dist')) file_path = os.path.join(dist_dir, path) diff --git a/backend/auth/login.py b/backend/auth/login.py index 0d2657f..cec8474 100644 --- a/backend/auth/login.py +++ b/backend/auth/login.py @@ -11,9 +11,12 @@ from auth.token import SECRET_KEY @limiter.limit("10 per minute") def login_route(): - data = request.get_json() - username = data.get('username') - password = data.get('password') + data = request.get_json(silent=True) or {} + username = data.get('username', '').strip() + password = data.get('password', '') + + if not username or not password: + return jsonify({"message": "Username und Passwort erforderlich"}), 400 if not SECRET_KEY: logger.error("Login blocked: SECRET_KEY is not configured.") diff --git a/backend/tools/jwtdecoder.py b/backend/tools/jwtdecoder.py index 9cc7561..12f7efe 100644 --- a/backend/tools/jwtdecoder.py +++ b/backend/tools/jwtdecoder.py @@ -16,7 +16,7 @@ def decode_jwt(): data = request.get_json() token = data.get("token", "").strip() header = jwt.get_unverified_header(token) - payload = jwt.decode(token, options={"verify_signature": False}) + payload = jwt.decode(token, options={"verify_signature": False}, algorithms=["HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "ES256", "ES384", "ES512"]) expired = False if "exp" in payload: diff --git a/backend/util/logger.py b/backend/util/logger.py index 9def01a..c9e985b 100644 --- a/backend/util/logger.py +++ b/backend/util/logger.py @@ -1,19 +1,21 @@ import logging import os -# Ensure logs directory exists os.makedirs("logs", exist_ok=True) -# Configure logger +fmt = "%(asctime)s [%(levelname)s] %(message)s" + +error_handler = logging.FileHandler("logs/error.log") +error_handler.setLevel(logging.ERROR) + logging.basicConfig( level=logging.INFO, - format="%(asctime)s [%(levelname)s] %(message)s", + format=fmt, handlers=[ logging.FileHandler("logs/app.log"), - logging.FileHandler("logs/error.log"), + error_handler, logging.StreamHandler() ] ) -# Hauptlogger, wird von anderen Modulen importiert logger = logging.getLogger("main") diff --git a/backend/util/setup_routes.py b/backend/util/setup_routes.py index 64be420..06f9142 100644 --- a/backend/util/setup_routes.py +++ b/backend/util/setup_routes.py @@ -2,6 +2,7 @@ import time import os from flask import Blueprint, request, render_template, redirect, jsonify, send_from_directory from util.db_config import load_config, save_config, test_connection, is_configured +from util.db_pool import reset_pool from auth.setup_admin import initialize_admin_user from util.logger import logger @@ -39,6 +40,7 @@ def setup(): "database": request.form['database'] } save_config(db_config) + reset_pool() if test_connection(db_config): initialize_admin_user(db_config) return redirect('/') diff --git a/frontend/src/components/LoginForm.jsx b/frontend/src/components/LoginForm.jsx index 25f6c38..7364896 100644 --- a/frontend/src/components/LoginForm.jsx +++ b/frontend/src/components/LoginForm.jsx @@ -12,8 +12,6 @@ function LoginForm() { const res = await axios.post('/api/login', { username, password }); localStorage.setItem('token', res.data.token); localStorage.setItem('role', res.data.role); - navigate('/', { replace: true }); - // ensure nav + route state reflect the new token immediately window.location.href = '/'; } catch (err) { alert('Login fehlgeschlagen'); diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx index 89bd47e..52b41ae 100644 --- a/frontend/src/main.jsx +++ b/frontend/src/main.jsx @@ -1,9 +1,6 @@ import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import App from './App.jsx'; -import './css/base.css'; -import './css/dark.css'; -import './css/light.css'; import './css/navbar.css';