From ef95d1d533e394225c47affea4004efda50828a2 Mon Sep 17 00:00:00 2001
From: Yarden Shoham <git@yardenshoham.com>
Date: Mon, 26 Feb 2024 14:40:41 +0200
Subject: [PATCH] Fix htmx rendering the login page in frame on session logout
 (#29405)

- Fix #29391

With this change, htmx will not follow the redirect in the AJAX request
but instead redirect the whole browser.

To reproduce the bug fixed by this change without waiting a long time
for the token to expire, you can logout in another tab then look in the
original tab. Just make sure to comment out both instances of
`window.location.href = appSubUrl` in the codebase so you won't be
redirected immediately on logout. This is what I did in the following
gifs.

Signed-off-by: Yarden Shoham <git@yardenshoham.com>
Co-authored-by: Giteabot <teabot@gitea.io>
(cherry picked from commit 324626a11c041208b003ee64e33000b223994662)
---
 modules/context/base.go | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/modules/context/base.go b/modules/context/base.go
index fa05850a16..ddd04f4767 100644
--- a/modules/context/base.go
+++ b/modules/context/base.go
@@ -265,6 +265,14 @@ func (b *Base) Redirect(location string, status ...int) {
 		// So in this case, we should remove the session cookie from the response header
 		removeSessionCookieHeader(b.Resp)
 	}
+	// in case the request is made by htmx, have it redirect the browser instead of trying to follow the redirect inside htmx
+	if b.Req.Header.Get("HX-Request") == "true" {
+		b.Resp.Header().Set("HX-Redirect", location)
+		// we have to return a non-redirect status code so XMLHTTPRequest will not immediately follow the redirect
+		// so as to give htmx redirect logic a chance to run
+		b.Status(http.StatusNoContent)
+		return
+	}
 	http.Redirect(b.Resp, b.Req, location, code)
 }