diff --git a/lib/hexdocs/plug.ex b/lib/hexdocs/plug.ex index 1f4954a..fc4f7d1 100644 --- a/lib/hexdocs/plug.ex +++ b/lib/hexdocs/plug.ex @@ -67,26 +67,41 @@ defmodule Hexdocs.Plug do end defp run(conn, _opts) do - case subdomain(conn.host) do - :error -> - send_resp(conn, 400, "") - - {:ok, subdomain} -> - cond do - # OAuth callback - exchange code for tokens - conn.request_path == "/oauth/callback" -> - handle_oauth_callback(conn, subdomain) - - # OAuth access token in session - access_token = get_session(conn, "access_token") -> - try_serve_page_oauth(conn, subdomain, access_token) - - true -> - redirect_oauth(conn, subdomain) - end + if conn.host == Application.get_env(:hexdocs, :private_host) do + redirect_to_hexpm(conn) + else + case subdomain(conn.host) do + :error -> + send_resp(conn, 400, "") + + {:ok, subdomain} -> + cond do + # OAuth callback - exchange code for tokens + conn.request_path == "/oauth/callback" -> + handle_oauth_callback(conn, subdomain) + + # OAuth access token in session + access_token = get_session(conn, "access_token") -> + try_serve_page_oauth(conn, subdomain, access_token) + + true -> + redirect_oauth(conn, subdomain) + end + end end end + defp redirect_to_hexpm(conn) do + url = Application.get_env(:hexdocs, :hexpm_url) + html = Plug.HTML.html_escape(url) + body = "
You are being redirected." + + conn + |> put_resp_header("location", url) + |> put_resp_header("content-type", "text/html") + |> send_resp(301, body) + end + defp redirect_oauth(conn, organization) do code_verifier = Hexdocs.OAuth.generate_code_verifier() code_challenge = Hexdocs.OAuth.generate_code_challenge(code_verifier) diff --git a/test/hexdocs/plug_test.exs b/test/hexdocs/plug_test.exs index c8206cd..d5c09cc 100644 --- a/test/hexdocs/plug_test.exs +++ b/test/hexdocs/plug_test.exs @@ -9,9 +9,13 @@ defmodule Hexdocs.PlugTest do @bucket :docs_private_bucket - test "requests without subdomain not supported" do + test "bare private host apex redirects to hexpm_url" do + # In the test env :host and :private_host are both "localhost", so a + # bare-host request hits the private-host-apex redirect. conn = conn(:get, "http://localhost:5002/foo") |> call() - assert conn.status == 400 + assert conn.status == 301 + [location] = get_resp_header(conn, "location") + assert location == "http://localhost:5000" end describe "OAuth flow" do @@ -340,6 +344,13 @@ defmodule Hexdocs.PlugTest do conn = conn(:get, "http://phoenix.hexdocs.test:5002/index.html") |> call() assert conn.status == 400 end + + test "redirects bare private host apex to hexpm_url" do + conn = conn(:get, "http://hexorgs.test:5002/") |> call() + assert conn.status == 301 + [location] = get_resp_header(conn, "location") + assert location == "http://localhost:5000" + end end test "sets security headers" do