From b77efa880bb4847469ee56df73affa6e78334855 Mon Sep 17 00:00:00 2001 From: Florian Heinz Date: Sun, 26 Apr 2026 12:35:19 +0200 Subject: [PATCH] fix: stabilize quick win redirects and task ownership --- app/routes/tasks.py | 27 ++++++++++++++++++++++----- app/services/tasks.py | 8 +++----- app/templates/tasks/task_form.html | 9 ++++++++- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/app/routes/tasks.py b/app/routes/tasks.py index c8102a3..3fb3661 100644 --- a/app/routes/tasks.py +++ b/app/routes/tasks.py @@ -113,6 +113,23 @@ def _redirect_with_celebration(target_url: str, points: int | None = None): return redirect(redirect_url) +def _safe_referrer_target(fallback: str) -> str: + referrer = request.referrer + if not referrer: + return fallback + + parts = urlsplit(referrer) + if parts.netloc and parts.netloc != request.host: + return fallback + + query = dict(parse_qsl(parts.query, keep_blank_values=True)) + query.pop("celebrate_points", None) + target = urlunsplit(("", "", parts.path or fallback, urlencode(query), parts.fragment)) + if not target.startswith("/") or len(target) > 1200: + return fallback + return target + + @bp.route("/my-tasks") @login_required def my_tasks(): @@ -293,7 +310,7 @@ def quick_create(): flash(error, "error") for error in extra_errors: flash(error, "error") - return redirect(request.referrer or url_for("tasks.my_tasks")) + return redirect(_safe_referrer_target(url_for("tasks.my_tasks"))) task = create_quick_task(custom_title, form.effort.data, current_user, description="Quick-Win") complete_task(task, current_user.id) created_titles.append(task.title) @@ -301,14 +318,14 @@ def quick_create(): if not created_titles: flash("Bitte wähle mindestens einen Quick-Win aus.", "error") - return redirect(request.referrer or url_for("tasks.my_tasks")) + return redirect(_safe_referrer_target(url_for("tasks.my_tasks"))) if len(created_titles) == 1: flash(f"Quick-Win „{created_titles[0]}“ wurde als erledigt gespeichert.", "success") else: flash(f"{len(created_titles)} Quick-Wins wurden als erledigt gespeichert.", "success") return _redirect_with_celebration( - request.referrer or url_for("tasks.my_tasks"), + _safe_referrer_target(url_for("tasks.my_tasks")), total_points, ) @@ -360,7 +377,7 @@ def complete(task_id: int): choice = request.form.get("completed_for", "me") if task.is_completed: flash("Diese Aufgabe ist bereits erledigt.", "info") - return redirect(request.referrer or url_for("tasks.my_tasks")) + return redirect(_safe_referrer_target(url_for("tasks.my_tasks"))) completed_by_id = current_user.id allowed_ids = {current_user.id} @@ -377,7 +394,7 @@ def complete(task_id: int): complete_task(task, completed_by_id) flash("Punkte verbucht. Gute Arbeit.", "success") return _redirect_with_celebration( - request.referrer or url_for("tasks.my_tasks"), + _safe_referrer_target(url_for("tasks.my_tasks")), awarded_points, ) diff --git a/app/services/tasks.py b/app/services/tasks.py index 74053ee..cebdd8a 100644 --- a/app/services/tasks.py +++ b/app/services/tasks.py @@ -66,8 +66,6 @@ def update_template_and_instance(task: TaskInstance, form) -> TaskInstance: template.title = form.title.data.strip() template.description = (form.description.data or "").strip() template.default_points = form.default_points.data - template.default_assigned_user_id = form.assigned_user_id.data - template.default_assigned_user_secondary_id = form.assigned_user_secondary_id.data or None template.recurrence_interval_unit = form.recurrence_interval_unit.data template.recurrence_interval_value = ( form.recurrence_interval_value.data if form.recurrence_interval_unit.data != "none" else None @@ -76,9 +74,9 @@ def update_template_and_instance(task: TaskInstance, form) -> TaskInstance: task.title = template.title task.description = template.description - task.assigned_user_id = template.default_assigned_user_id - task.assigned_user_secondary_id = template.default_assigned_user_secondary_id - task.points_awarded = effective_points(template.default_points, template.default_assigned_user_secondary_id) + task.assigned_user_id = form.assigned_user_id.data + task.assigned_user_secondary_id = form.assigned_user_secondary_id.data or None + task.points_awarded = effective_points(template.default_points, task.assigned_user_secondary_id) task.due_date = form.due_date.data refresh_task_status(task, form.due_date.data) db.session.commit() diff --git a/app/templates/tasks/task_form.html b/app/templates/tasks/task_form.html index bdd4e3f..24fdd61 100644 --- a/app/templates/tasks/task_form.html +++ b/app/templates/tasks/task_form.html @@ -30,8 +30,15 @@
- {{ form.assigned_user_id.label }} + {% if mode == 'edit' %} + + {% else %} + {{ form.assigned_user_id.label }} + {% endif %} {{ form.assigned_user_id() }} + {% if mode == 'edit' %} + Wiederholungen bleiben bei der ursprünglich vorgesehenen Person. + {% endif %} {% for error in form.assigned_user_id.errors %}{{ error }}{% endfor %}