admin: send /admin/ to /admin, also after login
All checks were successful
Build and Deploy to Production / test (push) Successful in 26s
Build and Deploy to Production / build (push) Successful in 1m1s
Build and Deploy to Production / deploy (push) Successful in 36s

Opening /admin/ logged out stored next=/admin/ in the login form, and a
successful login then redirected to /admin/, which has no route (404).

Redirect trailing-slash admin URLs to the slashless route with a 301,
and drop trailing slashes from the post-login target too.

Assisted-by: Claude:opus-5-5
This commit is contained in:
Sergei Poljanski 2026-10-18 10:39:10 +04:00
commit 9a802106ce
Signed by: asxpi
GPG key ID: 4F8851660FA4121B
2 changed files with 19 additions and 1 deletions

View file

@ -58,8 +58,10 @@ module AdminAuth
Audit.log(action: action, user: user, target: target, detail: detail, ip: client_ip)
end
# Trailing slashes dropped: /admin/ has no route (see the before filter).
def safe_next(target)
target.to_s.match?(%r{\A/admin(/[\w\-/]*)?\z}) ? target : '/admin'
target = target.to_s.sub(%r{(?<=.)/+\z}, '')
target.match?(%r{\A/admin(/[\w\-/]*)?\z}) ? target : '/admin'
end
end
@ -68,6 +70,8 @@ module AdminAuth
app.before do
next unless admin_path?
# One URL per page: /admin/ and /admin/bingo/ go to the slashless route.
redirect request.fullpath.sub(%r{/+(?=\?|\z)}, ''), 301 if request.path_info.match?(%r{./\z})
halt 503, 'Admin needs DATABASE_URL.' unless defined?(User)
next if request.path_info.match?(PUBLIC)
unless current_user