Loginverhalten weiter verbessert

This commit is contained in:
sandro committed 2026-10-11 23:18:54 +02:00
1 parent 7d7e19876d
commit c72520481c
1 file changed
+98 -21
+98 -21
View File
@@ -9,6 +9,7 @@ from flask import Flask, render_template_string, request, session, redirect, url
from flask_cors import CORS
from playwright.async_api import async_playwright
import requests
from urllib.parse import urlencode
import mutagen
from mutagen.mp3 import MP3
from mutagen.oggvorbis import OggVorbis
@@ -395,7 +396,16 @@ TEMPLATE = """
<a href="{{ url_for('index') }}" class="btn btn-nav" style="font-size: 1.1rem; padding: 12px 25px;">📚 Gesamte Bibliothek laden</a>
{% else %}
<input type="text" id="searchInput" placeholder="Hörbuch suchen...">
<a href="{{ url_for('tonie_login') }}" class="btn" style="background: #333; color: #fff; border: 1px solid #444;">🦊 Tonie-Login</a>
{% if tonie_logged_in %}
<div style="display: inline-flex; align-items: center; gap: 8px; background: #1c2e1f; border: 1px solid #2ed573; padding: 6px 14px; border-radius: 20px; font-size: 0.85rem;">
<span style="color: #2ed573;">🟢 TonieCloud:</span>
<strong style="color: #fff; max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">{{ tonie_email or 'Verbunden' }}</strong>
<a href="{{ url_for('tonie_logout') }}" title="Tonie-Verbindung trennen" style="color: #ff4757; text-decoration: none; margin-left: 6px; font-weight: bold;">✕</a>
</div>
{% else %}
<a href="{{ url_for('tonie_login') }}" class="btn" style="background: #333; color: #fff; border: 1px solid #444;">🦊 Tonie-Login</a>
{% endif %}
{% endif %}
</div>
@@ -812,26 +822,78 @@ TONIE_LOGIN_TEMPLATE = """
<title>Tonie-Login - Tonieflix</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background: #141414; color: #fff; margin: 0; }
.login-box { background: #1f1f1f; padding: 40px; border-radius: 12px; box-shadow: 0 4px 15px rgba(0,0,0,0.8); text-align: center; width: 100%; max-width: 350px; }
input { padding: 12px; margin: 10px 0; border: 1px solid #333; background: #2b2b2b; color: #fff; border-radius: 5px; width: 100%; box-sizing: border-box;}
body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; background: #141414; color: #fff; margin: 0; padding: 20px; box-sizing: border-box; }
.login-box { background: #1f1f1f; padding: 35px; border-radius: 12px; box-shadow: 0 4px 15px rgba(0,0,0,0.8); text-align: center; width: 100%; max-width: 420px; }
input { padding: 12px; margin: 10px 0; border: 1px solid #333; background: #2b2b2b; color: #fff; border-radius: 5px; width: 100%; box-sizing: border-box; }
button { background: #e50914; color: white; border: none; padding: 12px 20px; border-radius: 5px; cursor: pointer; width: 100%; font-size: 1rem; font-weight: bold; }
button:hover { opacity: 0.9; }
/* Schnell-Link Box */
.url-box { margin-top: 25px; background: #181818; padding: 12px; border-radius: 8px; border: 1px dashed #444; display: none; text-align: left; }
.url-box label { font-size: 0.75rem; color: #aaa; text-transform: uppercase; letter-spacing: 0.5px; font-weight: bold; }
.url-display { word-break: break-all; font-family: monospace; font-size: 0.8rem; color: #2ed573; margin: 8px 0; background: #111; padding: 8px; border-radius: 4px; border: 1px solid #222; }
.btn-copy { background: #333; color: #fff; padding: 6px 12px; font-size: 0.8rem; border-radius: 4px; border: 1px solid #555; cursor: pointer; width: auto; }
.btn-copy:hover { background: #444; }
</style>
</head>
<body>
<div class="login-box">
<h2 style="color: #e50914; margin-top: 0;">🦊 Tonies Account</h2>
<p style="font-size: 0.85rem; color: #aaa;">Gib deine Zugangsdaten für my.tonies.com ein:</p>
<form method="POST">
<input type="email" name="tonie_email" placeholder="E-Mail-Adresse" required>
<input type="password" name="tonie_password" placeholder="Passwort" required>
<button type="submit">Token generieren & Einloggen</button>
<input type="email" id="emailInput" name="tonie_email" placeholder="E-Mail-Adresse" required>
<input type="password" id="passInput" name="tonie_password" placeholder="Passwort" required>
<button type="submit" style="margin-top: 10px;">Token generieren & Einloggen</button>
</form>
{% if error %}
<p style="color: var(--primary); font-size: 0.9rem; margin-top: 15px;">{{ error }}</p>
<p style="color: #e50914; font-size: 0.9rem; margin-top: 15px;">{{ error }}</p>
{% endif %}
<div class="url-box" id="urlBox">
<label>🔗 Schnelleinwahl-URL:</label>
<div class="url-display" id="urlText"></div>
<button type="button" class="btn-copy" onclick="copyLink()">📋 URL kopieren</button>
</div>
</div>
<script>
const emailInput = document.getElementById('emailInput');
const passInput = document.getElementById('passInput');
const urlBox = document.getElementById('urlBox');
const urlText = document.getElementById('urlText');
const appPassword = {{ app_password|tojson }};
function updateUrlPreview() {
const email = emailInput.value.trim();
const pass = passInput.value;
if (email && pass) {
const fullUrl = window.location.origin + '/tonie-login?' +
'pw=' + encodeURIComponent(appPassword) +
'&tonie_email=' + encodeURIComponent(email) +
'&tonie_password=' + encodeURIComponent(pass);
urlText.innerText = fullUrl;
urlBox.style.display = 'block';
} else {
urlBox.style.display = 'none';
}
}
emailInput.addEventListener('input', updateUrlPreview);
passInput.addEventListener('input', updateUrlPreview);
function copyLink() {
const text = urlText.innerText;
navigator.clipboard.writeText(text).then(() => {
alert('Tonie-Login URL in die Zwischenablage kopiert!');
}).catch(() => {
prompt('Link kopieren:', text);
});
}
</script>
</body>
</html>
"""
@@ -841,7 +903,7 @@ TONIE_LOGIN_TEMPLATE = """
# ---------------------------------------------------------
@app.before_request
def require_login():
# CORS Preflight oder öffentliche API-Routen ignorieren
# CORS Preflight oder API-Routen ignorieren
if request.method == 'OPTIONS' or request.path.startswith('/api/books'):
return None
@@ -849,12 +911,16 @@ def require_login():
url_pw = request.args.get('pw') or request.args.get('password')
if url_pw and url_pw == PASSWORD:
session['logged_in'] = True
# Sauberer Redirect ohne Passwort-Parameter in der URL-Historie:
args = request.args.copy()
args.pop('pw', None)
args.pop('password', None)
clean_url = request.path + ('?' + args.to_encoded_string() if args else '')
# WICHTIG: Wenn wir auf /tonie-login sind, KEINEN Redirect machen,
# damit die Route die Tonie-Zugangsdaten direkt im selben Request verarbeiten kann!
if request.endpoint == 'tonie_login':
return None
# Für alle anderen Seiten: Saubere Weiterleitung ohne 'pw' in der Adresszeile
clean_args = {k: v for k, v in request.args.items() if k not in ('pw', 'password')}
query_string = urlencode(clean_args)
clean_url = request.path + (f"?{query_string}" if query_string else '')
return redirect(clean_url)
# Prüfen, ob eingeloggt oder auf Login/Statics unterwegs
@@ -883,10 +949,12 @@ def login():
@app.route('/tonie-login', methods=['GET', 'POST'])
def tonie_login():
error = None
if request.method == 'POST':
email = request.form.get('tonie_email')
pwd = request.form.get('tonie_password')
# Werte aus Formular (POST) oder Query-String (GET) holen
email = request.form.get('tonie_email') or request.args.get('tonie_email')
pwd = request.form.get('tonie_password') or request.args.get('tonie_password')
if email and pwd:
token = get_tonie_api_token(email, pwd)
if token:
session['tonie_token'] = token
@@ -898,8 +966,15 @@ def tonie_login():
logger.warning(f"Toniecloud-Login fehlgeschlagen für E-Mail: {email} (IP: {request.remote_addr})")
log_to_db("WARNUNG", f"Toniecloud-Login fehlgeschlagen für E-Mail: {email} (IP: {request.remote_addr})")
error = "Login fehlgeschlagen. Bitte Zugangsdaten prüfen."
return render_template_string(TONIE_LOGIN_TEMPLATE, error=error)
return render_template_string(TONIE_LOGIN_TEMPLATE, error=error, app_password=PASSWORD)
@app.route('/tonie-logout')
def tonie_logout():
session.pop('tonie_token', None)
session.pop('tonie_email', None)
return redirect(url_for('index'))
@app.route('/logout')
def logout():
session.clear()
@@ -925,7 +1000,9 @@ def index():
single_mode=False,
all_genres=sorted(list(all_genres)),
all_formats=sorted(list(all_formats)),
all_agegroups=sorted(list(all_agegroups))
all_agegroups=sorted(list(all_agegroups)),
tonie_logged_in=bool(session.get('tonie_token')),
tonie_email=session.get('tonie_email', '')
)
@app.route('/play/<path:book_name>')