Compare commits

...

10 Commits

3 changed files with 29 additions and 26 deletions
+3 -5
View File
@@ -18,7 +18,6 @@ Features:
"""
from flask import Flask, render_template, request, redirect, url_for, session, flash, send_from_directory, get_flashed_messages, jsonify, Response, make_response, send_file, abort
from flask_wtf.csrf import CSRFProtect
from werkzeug.utils import secure_filename
from werkzeug.middleware.proxy_fix import ProxyFix
from werkzeug.exceptions import HTTPException
@@ -116,7 +115,6 @@ app.config['PREFERRED_URL_SCHEME'] = 'https' if app.config['SESSION_COOKIE_SECUR
# app.config['QR_CODE_FOLDER'] = cfg.QR_CODE_FOLDER # QR Code storage deactivated
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_port=1)
app.register_blueprint(terminplaner_bp, url_prefix='/terminplaner')
csrf = CSRFProtect(app)
"""--------------------------------------------------------------Path Init-------------------------------------------------------"""
@@ -3607,7 +3605,8 @@ def api_item_detail(item_id):
borrows_html = ''
if borrow_records:
rows = []
for rec in borrow_records:
for rec in borrow_records[:3]:
user_raw = rec.get('User')
try:
user = decrypt_text(user_raw) if user_raw is not None else ''
@@ -3617,7 +3616,6 @@ def api_item_detail(item_id):
start = fmt_dt(rec.get('Start'))
end = fmt_dt(rec.get('End'))
notes = html.escape(str(rec.get('Notes') or ''))
rows.append(
f"<li><strong>{html.escape(str(user or '-'))}</strong> — "
f"{html.escape(str(status))}"
@@ -7914,7 +7912,7 @@ def register():
return redirect(url_for('login'))
if request.method == 'POST':
password = request.form.get('password', '')
password = request.form['password']
name = (request.form.get('name') or '').strip()
last_name = (request.form.get('last-name') or '').strip()
+24 -15
View File
@@ -1375,8 +1375,10 @@
<li><a class="dropdown-item" href="{{ url_for('library_loans_admin') }}">Ausleihen / Defekte Items</a></li>
{% endif %}
{% if student_cards_module_enabled %}
{% if current_permissions.actions.get('can_manage_users', False) %}
<li><a class="dropdown-item" href="{{ url_for('student_cards_admin') }}">Bibliotheksausweis</a></li>
{% endif %}
{% endif %}
{% if current_permissions.pages.get('admin_school_settings', False) %}
<li><a class="dropdown-item" href="{{ url_for('admin_school_settings') }}">Schulstammdaten</a></li>
{% endif %}
@@ -1619,11 +1621,10 @@
<div id="cookie-banner" role="dialog" aria-live="polite" aria-label="Cookie-Hinweis">
<div class="cb-inner">
<div class="cb-text">
Wir verwenden technisch notwendige Cookies, um Ihre Sitzung zu verwalten und die Anwendung bereitzustellen. Bitte akzeptieren Sie Cookies, um fortzufahren.
Wir verwenden ausschließlich technisch notwendige Cookies, um Ihre Sitzung zu verwalten und die Anwendung bereitzustellen. Bitte bestätigen Sie dies, um fortzufahren.
</div>
<div class="cb-actions">
<button class="btn-decline" id="cookie-decline">Ablehnen</button>
<button class="btn-accept" id="cookie-accept">Akzeptieren</button>
<button class="btn-accept" id="cookie-accept">Notwendige Cookies akzeptieren</button>
</div>
</div>
</div>
@@ -1728,31 +1729,39 @@
(function(){
function getCookie(name){
const v = document.cookie.split(';').map(s=>s.trim());
for(const c of v){ if(c.startsWith(name+'=')) return decodeURIComponent(c.split('=')[1]); }
for(const c of v){
if(c.startsWith(name+'=')) return decodeURIComponent(c.split('=')[1]);
}
return null;
}
function setCookie(name, value, days){
const d = new Date(); d.setTime(d.getTime() + (days*24*60*60*1000));
const d = new Date();
d.setTime(d.getTime() + (days*24*60*60*1000));
document.cookie = name + '=' + encodeURIComponent(value) + ';expires=' + d.toUTCString() + ';path=/;SameSite=Lax';
}
function showBanner(){ var el = document.getElementById('cookie-banner'); if(el) el.style.display = 'block'; }
function hideBanner(){ var el = document.getElementById('cookie-banner'); if(el) el.style.display = 'none'; }
// If not decided yet, show banner and block app until decision
function showBanner(){
var el = document.getElementById('cookie-banner');
if(el) el.style.display = 'block';
}
function hideBanner(){
var el = document.getElementById('cookie-banner');
if(el) el.style.display = 'none';
}
// Prüfen, ob der Nutzer bereits zugestimmt hat
const consent = getCookie('cookie_consent');
if(!consent){
showBanner();
// Optionally blur content until consent
document.body.style.filter = 'none';
}
// Nur noch der Akzeptieren-Button für vitale Cookies ist vorhanden
document.getElementById('cookie-accept')?.addEventListener('click', function(){
setCookie('cookie_consent','accepted',365);
setCookie('cookie_consent', 'vital_accepted', 365);
hideBanner();
});
document.getElementById('cookie-decline')?.addEventListener('click', function(){
setCookie('cookie_consent','declined',365);
window.location.href = 'https://www.ecosia.org/';
});
const username = {{ (session['username'] if 'username' in session else '')|tojson }};
const isTutorialPage = window.location.pathname === {{ url_for('tutorial_page')|tojson }};
+2 -6
View File
@@ -25,9 +25,6 @@
<div class="content">
<div class="form-card">
<form method="POST" action="{{ url_for('register') }}">
<!-- CSRF-Schutz (Zwingend erforderlich für POST) -->
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<div class="form-group">
<label for="name">Vorname</label>
@@ -65,17 +62,16 @@
<div class="input-container">
<span class="input-icon">🔒</span>
<!-- HTML5 Pattern blockiert unsichere Passwörter vor dem Absenden -->
<input type="password"
<input
id="password"
name="password"
placeholder="Geben Sie ein sicheres Passwort ein"
required
pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{12,}">
</div>
<button type="button" class="btn-secondary" id="toggle-pw-btn" onclick="togglePasswordVisibility()" title="Passwort anzeigen/verbergen">👁️</button>
</div>
<div class="pw-actions">
<button type="button" class="btn-secondary" onclick="generateSecurePassword()">🎲 Automatisches Passwort generieren</button>
<button type="button" class="btn-secondary" onclick="generateSecurePassword()">Passwort generieren</button>
</div>
</div>