diff --git a/cmd/gogs/internal/web/web.go b/cmd/gogs/internal/web/web.go index d968cf0e8..df46393f3 100644 --- a/cmd/gogs/internal/web/web.go +++ b/cmd/gogs/internal/web/web.go @@ -130,7 +130,6 @@ func Run(configPath string, portOverride int) error { m.Any("/activate", user.Activate) m.Any("/activate_email", user.ActivateEmail) m.Get("/email2user", user.Email2User) - m.Post("/logout", user.SignOut) }) // ***** END: User ***** diff --git a/cmd/gogs/internal/web/webapi.go b/cmd/gogs/internal/web/webapi.go index a02fbc205..c1d6de082 100644 --- a/cmd/gogs/internal/web/webapi.go +++ b/cmd/gogs/internal/web/webapi.go @@ -600,9 +600,16 @@ func getUserInfo(user *database.User) (statusCode int, resp *userInfo, err error nil } -func postUserSignOut(sess macaronsession.Store, mc *macaron.Context) (statusCode int, resp any, err error) { +type postUserSignOutResponse struct { + RedirectTo string `json:"redirectTo,omitempty"` +} + +func postUserSignOut(sess macaronsession.Store, mc *macaron.Context) (statusCode int, resp *postUserSignOutResponse, err error) { _ = sess.Flush() _ = sess.Destory(mc) mc.SetCookie(conf.Session.CSRFCookieName, "", -1, conf.Server.Subpath) + if conf.Auth.CustomLogoutURL != "" { + return http.StatusOK, &postUserSignOutResponse{RedirectTo: conf.Auth.CustomLogoutURL}, nil + } return http.StatusNoContent, nil, nil } diff --git a/internal/route/user/auth.go b/internal/route/user/auth.go index 2ecc0b208..b292075d9 100644 --- a/internal/route/user/auth.go +++ b/internal/route/user/auth.go @@ -17,17 +17,6 @@ import ( const TmplUserAuthActivate = "user/auth/activate" -func SignOut(c *context.Context) { - _ = c.Session.Flush() - _ = c.Session.Destory(c.Context) - c.SetCookie(conf.Session.CSRFCookieName, "", -1, conf.Server.Subpath) - if conf.Auth.CustomLogoutURL != "" { - c.Redirect(conf.Auth.CustomLogoutURL) - return - } - c.RedirectSubpath("/") -} - // parseUserFromCode returns user by username encoded in code. // It returns nil if code or username is invalid. func parseUserFromCode(code string) (user *database.User) { diff --git a/public/js/gogs.js b/public/js/gogs.js index ab1cd8cdb..bcb6a2a96 100644 --- a/public/js/gogs.js +++ b/public/js/gogs.js @@ -1607,6 +1607,23 @@ $(document).ready(function() { $($(this).data("form")).submit(); }); + // Intercept the legacy sign-out form so it talks to the JSON API and + // navigates to the URL the server hands back (honors CustomLogoutURL). + $("#logout-form").on("submit", function(event) { + event.preventDefault(); + var $form = $(this); + var doneUrl = $form.data("done-url"); + $.ajax({ + url: $form.attr("action"), + method: "POST" + }).done(function(data) { + var target = (data && data.redirectTo) ? data.redirectTo : doneUrl; + window.location.assign(target); + }).fail(function() { + window.location.assign(doneUrl); + }); + }); + // Check or select on option to enable/disable target region $(".enable-system").change(function() { if (this.checked) { diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl index 6aa7439b8..b22beebc0 100644 --- a/templates/base/head.tmpl +++ b/templates/base/head.tmpl @@ -161,8 +161,7 @@
-
- {{.CSRFTokenHTML}} +
{{.i18n.Tr "sign_out"}}
diff --git a/web/src/components/Navbar.tsx b/web/src/components/Navbar.tsx index c43b61ab3..a17e27875 100644 --- a/web/src/components/Navbar.tsx +++ b/web/src/components/Navbar.tsx @@ -346,15 +346,24 @@ function SignOutForm({ children }: { children: React.ReactNode }) { } async function signOut() { + let redirectTo = subUrl("/"); try { - await fetch(subUrl("/api/web/user/sign-out"), { + const res = await fetch(subUrl("/api/web/user/sign-out"), { method: "POST", credentials: "same-origin", }); + if (res.ok && res.status !== 204) { + const body = (await res.json().catch(() => null)) as { + redirectTo?: string; + } | null; + if (body?.redirectTo) { + redirectTo = body.redirectTo; + } + } } catch (err) { console.error("signOut: request failed", err); } - window.location.assign(subUrl("/")); + window.location.assign(redirectTo); } function MobileLink({