From 4abbfeaa367a0703ad8d167d97f3ee1d7aecb7f1 Mon Sep 17 00:00:00 2001 From: Oliver Falk Date: Mon, 8 Sep 2025 12:52:24 +0200 Subject: [PATCH] Handle next parameter on the token auth page to correctly redirect to the initiating page --- ivatar/ivataraccount/auth_views.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/ivatar/ivataraccount/auth_views.py b/ivatar/ivataraccount/auth_views.py index b6c8663..45278e9 100644 --- a/ivatar/ivataraccount/auth_views.py +++ b/ivatar/ivataraccount/auth_views.py @@ -7,6 +7,7 @@ import secrets from typing import Optional from django.views.generic.base import View from django.http import JsonResponse, HttpRequest, HttpResponseRedirect +from urllib.parse import urlencode, urlparse, urlunparse, parse_qs, quote from ipware import get_client_ip from .auth_models import AuthToken, BruteForceAttempt @@ -29,7 +30,9 @@ class ExternalAuthView(View): if not request.user.is_authenticated: # Redirect to login page with next parameter current_path = request.get_full_path() - redirect_url = f"/accounts/login/?next={current_path}" + # URL-encode the current path to preserve query parameters + encoded_path = quote(current_path, safe="") + redirect_url = f"/accounts/login/?next={encoded_path}" return HttpResponseRedirect(redirect_url) # Determine identifier for brute force tracking (only for authenticated users) @@ -90,6 +93,30 @@ class ExternalAuthView(View): brute_force_attempt.is_blocked = False brute_force_attempt.save() + # Check if there's a 'next' parameter for redirect + next_url = request.GET.get("next") + if next_url: + # Parse the next URL and add the token as a parameter + parsed_url = urlparse(next_url) + query_params = parse_qs(parsed_url.query) + query_params["token"] = [token] + + # Rebuild the URL with the token parameter + new_query = urlencode(query_params, doseq=True) + redirect_url = urlunparse( + ( + parsed_url.scheme, + parsed_url.netloc, + parsed_url.path, + parsed_url.params, + new_query, + parsed_url.fragment, + ) + ) + + return HttpResponseRedirect(redirect_url) + + # If no next parameter, return JSON response as before return JsonResponse( { "authenticated": True,