diff --git a/Website/main.py b/Website/main.py index 512eeac..4a81871 100644 --- a/Website/main.py +++ b/Website/main.py @@ -26,6 +26,8 @@ from bson.objectid import ObjectId import user as user_store import buchungen import server_steering as steering +from modules.emailservice.email import send_register_token +import secrets app = Flask(__name__) app.secret_key = "ASDfhbsdfseiufhgildsrfrjg874368546987s6e8468f4!?FAUS/&s" @@ -1881,15 +1883,9 @@ def login(): if stored_user: if stored_user.get("verified", True) is False: - if request.is_json: - return jsonify({ - "error": "Account not verified", - "username": stored_user.get("username"), - "needs_verification": True - }, 403) - - flash('Bitte verifizieren Sie Ihre E-Mail-Adresse, bevor Sie sich einloggen.', 'error') - return redirect(url_for('login')) + flash('Bitte verifizieren Sie Ihr Konto mit dem Code aus der E-Mail, bevor Sie sich einloggen.', 'error') + + return redirect(url_for('verify_account', username=stored_user.get("username"))) session['username'] = stored_user.get("username") session['display_name'] = stored_user.get("display_name") or stored_user.get("username") @@ -1991,7 +1987,7 @@ def verify_account(): if not username or not token: flash("Bitte Benutzername und Token eingeben.", "error") - return redirect(url_for("verify_account")) + return redirect(url_for("verify_account", username=username)) user = _find_user(username) if not user: @@ -2002,8 +1998,6 @@ def verify_account(): flash("Konto ist bereits verifiziert. Bitte einloggen.", "success") return redirect(url_for("login")) - # Die Funktion verify_user_token übernimmt jetzt das Hashing und den Vergleich. - # Sie gibt True zurück, wenn es passt, und False, wenn der Token falsch ist. is_valid = user_store.verify_user_token(username, token) if is_valid: @@ -2016,6 +2010,60 @@ def verify_account(): prefilled_username = request.args.get("username", "") return render_template("verify.html", username=prefilled_username) + +@app.route("/resend-token", methods=["POST"]) +def resend_token(): + username = (request.form.get("username") or "").strip() + user = _find_user(username) + + if not user: + flash("Benutzer nicht gefunden.", "error") + return redirect(url_for("verify_account")) + + if user.get("verified"): + flash("Konto ist bereits verifiziert.", "info") + return redirect(url_for("login")) + + new_token = secrets.token_hex(3).upper() + user_store.update_verification_token(user["username"], new_token) + + if send_register_token(user["email"], new_token): + flash("Ein neuer Bestätigungscode wurde an Ihre E-Mail-Adresse gesendet.", "success") + else: + flash("E-Mail konnte nicht gesendet werden. Bitte versuchen Sie es später erneut.", "error") + + return redirect(url_for("verify_account", username=username)) + + +@app.route("/change-email", methods=["POST"]) +def change_email_and_resend(): + username = (request.form.get("username") or "").strip() + new_email = (request.form.get("new_email") or "").strip().lower() + + if not username or not new_email or "@" not in new_email: + flash("Bitte geben Sie eine gültige E-Mail-Adresse ein.", "error") + return redirect(url_for("verify_account", username=username)) + + user = _find_user(username) + if not user: + flash("Benutzer nicht gefunden.", "error") + return redirect(url_for("verify_account")) + + if user_store.email_exists(new_email): + flash("Diese E-Mail-Adresse wird bereits verwendet.", "error") + return redirect(url_for("verify_account", username=username)) + + new_token = secrets.token_hex(3).upper() + + user_store.update_user_email_and_token(username, new_email, new_token) + + if send_register_token(new_email, new_token): + flash("E-Mail-Adresse erfolgreich geändert und neuer Code gesendet.", "success") + else: + flash("E-Mail-Adresse geändert, aber der Code konnte nicht gesendet werden.", "error") + + return redirect(url_for("verify_account", username=username)) + @app.route('/download-sample') def download_sample(): # Ensure the file is only served from the specific directory diff --git a/Website/templates/login.html b/Website/templates/login.html index 89f73ff..ae10928 100644 --- a/Website/templates/login.html +++ b/Website/templates/login.html @@ -87,82 +87,6 @@ color: #0a5f8f; font-weight: 700; } - - /* Custom Modal Overlay Styles */ - .custom-modal-overlay { - display: none; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(14, 32, 48, 0.5); - backdrop-filter: blur(3px); - z-index: 1000; - justify-content: center; - align-items: center; - } - - .custom-modal-overlay.active { - display: flex; - } - - .custom-modal { - background: #ffffff; - padding: 2rem; - border-radius: 16px; - max-width: 440px; - width: 90%; - box-shadow: 0 20px 44px rgba(14, 32, 48, 0.15); - border: 1px solid #d4e0e9; - text-align: center; - } - - .custom-modal h3 { - color: #0f344d; - font-size: 1.4rem; - margin-bottom: 0.5rem; - } - - .custom-modal p { - color: #547184; - font-size: 0.95rem; - margin-bottom: 1.5rem; - } - - .modal-actions { - display: flex; - flex-direction: column; - gap: 0.75rem; - } - - .modal-btn-primary { - background: #0a5f8f; - color: #ffffff; - border: none; - border-radius: 999px; - padding: 0.65rem; - font-weight: 700; - cursor: pointer; - text-decoration: none; - display: block; - } - - .modal-btn-secondary { - background: #f1f5f9; - color: #19445f; - border: 1px solid #c4d5e2; - border-radius: 999px; - padding: 0.65rem; - font-weight: 700; - cursor: pointer; - text-decoration: none; - display: block; - } - - .modal-btn-secondary:hover { - background: #e2e8f0; - } {% endblock %} @@ -183,45 +107,4 @@

Noch kein Konto? Jetzt registrieren

- - -
-
-

Konto nicht verifiziert

-

Ihr Konto wurde noch nicht aktiviert. Bitte geben Sie Ihren Bestätigungscode ein oder fordern Sie einen neuen an.

- -
-
- - {% endblock %} \ No newline at end of file diff --git a/Website/templates/verify.html b/Website/templates/verify.html index a3d51bd..229e903 100644 --- a/Website/templates/verify.html +++ b/Website/templates/verify.html @@ -5,8 +5,6 @@ {% block head %} {{ super() }} {% endblock %} @@ -44,5 +141,58 @@ + +
+
+ Keinen Code erhalten? +
+ + +
+
+
+ Falsche E-Mail-Adresse? + +
+
+ + +
+
+

E-Mail-Adresse ändern

+

Geben Sie Ihre neue E-Mail-Adresse ein. Wir senden Ihnen umgehend einen neuen Bestätigungscode.

+ +
+ + +
+ + +
+ + +
+
+
+ + {% endblock %} \ No newline at end of file diff --git a/Website/user.py b/Website/user.py index 26b67e4..3a9414d 100644 --- a/Website/user.py +++ b/Website/user.py @@ -174,4 +174,51 @@ def update_password(username, new_password): return result.modified_count > 0 except Exception as e: print(f"Error updating password: {e}") - return False \ No newline at end of file + return False + +def email_exists(email): + """ + Prüft, ob die E-Mail bereits von einem verifizierten Konto genutzt wird. + """ + client = None + try: + client, users = _get_users_collection() + user = users.find_one({'email': email.strip().lower(), 'verified': True}) + return user is not None + finally: + if client: + client.close() + +def update_verification_token(username, new_token): + """ + Aktualisiert den Verifizierungs-Token für einen Benutzer. + """ + client = None + try: + client, users = _get_users_collection() + hashed_token = hashing(new_token) + result = users.update_one( + {'Username': username}, + {'$set': {'verification_token': hashed_token}} + ) + return result.modified_count > 0 + finally: + if client: + client.close() + +def update_user_email_and_token(username, new_email, new_token): + """ + Aktualisiert die E-Mail-Adresse und den Verifizierungs-Token für einen Benutzer. + """ + client = None + try: + client, users = _get_users_collection() + hashed_token = hashing(new_token) + result = users.update_one( + {'Username': username}, + {'$set': {'email': new_email.strip().lower(), 'verification_token': hashed_token}} + ) + return result.modified_count > 0 + finally: + if client: + client.close() \ No newline at end of file