Loginverhalten weiter verbessert
This commit is contained in:
1 parent
7d7e19876d
commit
c72520481c
1 file changed
+98
-21
@@ -9,6 +9,7 @@ from flask import Flask, render_template_string, request, session, redirect, url
|
|||||||
from flask_cors import CORS
|
from flask_cors import CORS
|
||||||
from playwright.async_api import async_playwright
|
from playwright.async_api import async_playwright
|
||||||
import requests
|
import requests
|
||||||
|
from urllib.parse import urlencode
|
||||||
import mutagen
|
import mutagen
|
||||||
from mutagen.mp3 import MP3
|
from mutagen.mp3 import MP3
|
||||||
from mutagen.oggvorbis import OggVorbis
|
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>
|
<a href="{{ url_for('index') }}" class="btn btn-nav" style="font-size: 1.1rem; padding: 12px 25px;">📚 Gesamte Bibliothek laden</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<input type="text" id="searchInput" placeholder="Hörbuch suchen...">
|
<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 %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -812,26 +822,78 @@ TONIE_LOGIN_TEMPLATE = """
|
|||||||
<title>Tonie-Login - Tonieflix</title>
|
<title>Tonie-Login - Tonieflix</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<style>
|
<style>
|
||||||
body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background: #141414; color: #fff; margin: 0; }
|
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: 40px; border-radius: 12px; box-shadow: 0 4px 15px rgba(0,0,0,0.8); text-align: center; width: 100%; max-width: 350px; }
|
.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;}
|
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 { 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; }
|
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>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="login-box">
|
<div class="login-box">
|
||||||
<h2 style="color: #e50914; margin-top: 0;">🦊 Tonies Account</h2>
|
<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>
|
<p style="font-size: 0.85rem; color: #aaa;">Gib deine Zugangsdaten für my.tonies.com ein:</p>
|
||||||
|
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
<input type="email" name="tonie_email" placeholder="E-Mail-Adresse" required>
|
<input type="email" id="emailInput" name="tonie_email" placeholder="E-Mail-Adresse" required>
|
||||||
<input type="password" name="tonie_password" placeholder="Passwort" required>
|
<input type="password" id="passInput" name="tonie_password" placeholder="Passwort" required>
|
||||||
<button type="submit">Token generieren & Einloggen</button>
|
<button type="submit" style="margin-top: 10px;">Token generieren & Einloggen</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{% if error %}
|
{% 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 %}
|
{% 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>
|
</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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
"""
|
"""
|
||||||
@@ -841,7 +903,7 @@ TONIE_LOGIN_TEMPLATE = """
|
|||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
@app.before_request
|
@app.before_request
|
||||||
def require_login():
|
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'):
|
if request.method == 'OPTIONS' or request.path.startswith('/api/books'):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -849,12 +911,16 @@ def require_login():
|
|||||||
url_pw = request.args.get('pw') or request.args.get('password')
|
url_pw = request.args.get('pw') or request.args.get('password')
|
||||||
if url_pw and url_pw == PASSWORD:
|
if url_pw and url_pw == PASSWORD:
|
||||||
session['logged_in'] = True
|
session['logged_in'] = True
|
||||||
|
|
||||||
# Sauberer Redirect ohne Passwort-Parameter in der URL-Historie:
|
# WICHTIG: Wenn wir auf /tonie-login sind, KEINEN Redirect machen,
|
||||||
args = request.args.copy()
|
# damit die Route die Tonie-Zugangsdaten direkt im selben Request verarbeiten kann!
|
||||||
args.pop('pw', None)
|
if request.endpoint == 'tonie_login':
|
||||||
args.pop('password', None)
|
return None
|
||||||
clean_url = request.path + ('?' + args.to_encoded_string() if args else '')
|
|
||||||
|
# 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)
|
return redirect(clean_url)
|
||||||
|
|
||||||
# Prüfen, ob eingeloggt oder auf Login/Statics unterwegs
|
# Prüfen, ob eingeloggt oder auf Login/Statics unterwegs
|
||||||
@@ -883,10 +949,12 @@ def login():
|
|||||||
@app.route('/tonie-login', methods=['GET', 'POST'])
|
@app.route('/tonie-login', methods=['GET', 'POST'])
|
||||||
def tonie_login():
|
def tonie_login():
|
||||||
error = None
|
error = None
|
||||||
if request.method == 'POST':
|
|
||||||
email = request.form.get('tonie_email')
|
# Werte aus Formular (POST) oder Query-String (GET) holen
|
||||||
pwd = request.form.get('tonie_password')
|
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)
|
token = get_tonie_api_token(email, pwd)
|
||||||
if token:
|
if token:
|
||||||
session['tonie_token'] = 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})")
|
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})")
|
log_to_db("WARNUNG", f"Toniecloud-Login fehlgeschlagen für E-Mail: {email} (IP: {request.remote_addr})")
|
||||||
error = "Login fehlgeschlagen. Bitte Zugangsdaten prüfen."
|
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')
|
@app.route('/logout')
|
||||||
def logout():
|
def logout():
|
||||||
session.clear()
|
session.clear()
|
||||||
@@ -925,7 +1000,9 @@ def index():
|
|||||||
single_mode=False,
|
single_mode=False,
|
||||||
all_genres=sorted(list(all_genres)),
|
all_genres=sorted(list(all_genres)),
|
||||||
all_formats=sorted(list(all_formats)),
|
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>')
|
@app.route('/play/<path:book_name>')
|
||||||
|
|||||||
Reference in new issue
Block a user