web: migrate /user/sign-out to Flamego (#8294)

This commit is contained in:
ᴊᴏᴇ ᴄʜᴇɴ
2026-05-24 11:16:57 -04:00
committed by GitHub
parent 26483c41c6
commit 44f0222a71
6 changed files with 37 additions and 17 deletions
-1
View File
@@ -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 *****
+8 -1
View File
@@ -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
}
-11
View File
@@ -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) {
+17
View File
@@ -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) {
+1 -2
View File
@@ -161,8 +161,7 @@
<div class="divider"></div>
<form id="logout-form" class="item" action="{{AppSubURL}}/user/logout" method="POST">
{{.CSRFTokenHTML}}
<form id="logout-form" class="item" action="{{AppSubURL}}/api/web/user/sign-out" method="POST" data-done-url="{{AppSubURL}}/">
<div class="submit-button" data-form="#logout-form">
<i class="octicon octicon-sign-out"></i> {{.i18n.Tr "sign_out"}}
</div>
+11 -2
View File
@@ -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({