Skip to content

Commit 045a952

Browse files
authored
FIX: login redirect to root path in subfolder setup (#36609)
When Discourse is served from a subfolder (e.g., /forum), logging in from the login page itself would incorrectly redirect users to the root domain (/) instead of the subfolder root (/forum/). The issue had two causes: 1. The login path check in `extract_redirect_param` used the Rails `login_path` helper which returns "/login" without the subfolder prefix. When the browser sent the full path "/forum/login", the check `starts_with?("/login")` failed to match, treating it as a valid redirect target instead of rejecting it. 2. The `enter` method didn't apply the subfolder prefix when falling back to the root path "/". Fixed by: - Building the full login path with `Discourse.base_path` for accurate matching in subfolder setups - Wrapping the fallback "/" with `path()` in `enter` to respect the subfolder configuration - Extracting redirect validation into `valid_redirect_uri?` for clarity Ref - meta/t/386619
1 parent 58d298c commit 045a952

File tree

2 files changed

+43
-16
lines changed

2 files changed

+43
-16
lines changed

app/controllers/static_controller.rb

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,24 +28,25 @@ class StaticController < ApplicationController
2828
CUSTOM_PAGES = {} # Add via `#add_topic_static_page` in plugin API
2929

3030
def extract_redirect_param
31-
redirect_path = params[:redirect]
32-
if redirect_path.present?
33-
begin
34-
forum_host = URI(Discourse.base_url).host
35-
uri = URI(redirect_path)
31+
return "/" if params[:redirect].blank?
3632

37-
if uri.path.present? && !uri.path.starts_with?(login_path) &&
38-
(uri.host.blank? || uri.host == forum_host) && uri.path =~ %r{\A\/{1}[^\.\s]*\z}
39-
return "#{uri.path}#{uri.query ? "?#{uri.query}" : ""}"
40-
end
41-
rescue URI::Error, ArgumentError
42-
# If the URI is invalid, return "/" below
43-
end
44-
end
33+
uri = URI(params[:redirect])
34+
return "/" unless valid_redirect_uri?(uri)
4535

36+
uri.query ? "#{uri.path}?#{uri.query}" : uri.path
37+
rescue URI::Error, ArgumentError
4638
"/"
4739
end
4840

41+
def valid_redirect_uri?(uri)
42+
return false if uri.path.blank?
43+
return false if uri.path.starts_with?("#{Discourse.base_path}/login")
44+
return false if uri.host.present? && uri.host != URI(Discourse.base_url).host
45+
return false if !uri.path.match?(%r{\A/[^\.\s]*\z})
46+
47+
true
48+
end
49+
4950
def show
5051
if params[:id] == "login"
5152
destination = extract_redirect_param
@@ -152,14 +153,15 @@ def enter
152153

153154
destination = extract_redirect_param
154155

155-
allow_other_hosts = false
156+
allow_other_host = false
156157

157158
if cookies[:sso_destination_url]
158159
destination = cookies.delete(:sso_destination_url)
159-
allow_other_hosts = true
160+
allow_other_host = true
160161
end
161162

162-
redirect_to(destination, allow_other_host: allow_other_hosts)
163+
destination = path(destination) if destination == "/"
164+
redirect_to(destination, allow_other_host:)
163165
end
164166

165167
FAVICON = -"favicon"

spec/requests/static_controller_spec.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,31 @@
396396
expect(response).to redirect_to("/")
397397
end
398398
end
399+
400+
context "with a subfolder" do
401+
before { set_subfolder "/sub_test" }
402+
403+
context "without a redirect path" do
404+
it "redirects to the subfolder root" do
405+
post "/login.json"
406+
expect(response).to redirect_to("/sub_test/")
407+
end
408+
end
409+
410+
context "when the redirect path is the login page" do
411+
it "redirects to the subfolder root" do
412+
post "/login.json", params: { redirect: "#{Discourse.base_path}/login" }
413+
expect(response).to redirect_to("/sub_test/")
414+
end
415+
end
416+
417+
context "when the redirect path is invalid" do
418+
it "redirects to the subfolder root" do
419+
post "/login.json", params: { redirect: "test" }
420+
expect(response).to redirect_to("/sub_test/")
421+
end
422+
end
423+
end
399424
end
400425

401426
describe "#service_worker_asset" do

0 commit comments

Comments
 (0)