diff --git a/backend/src/app/config.clj b/backend/src/app/config.clj index 10a97b7bee..6c04c82861 100644 --- a/backend/src/app/config.clj +++ b/backend/src/app/config.clj @@ -432,6 +432,13 @@ (or (c/get config :file-clean-delay) (ct/duration {:days 2}))) +(defn- join-path-segments + [segments] + (let [path (->> segments (map str) (str/join "/"))] + (->> (str/split path #"/") + (remove str/blank?) + (str/join "/")))) + (defn join-uri "Join path segments onto a base URI, preserving a potential subpath (same semantics as the frontend config). The base is normalized with @@ -440,7 +447,8 @@ [base & segments] (assert (not (some #(str/starts-with? % "/") segments)) "URI segments must be relative (no leading slash)") - (str (apply u/join (u/ensure-path-slash base) segments))) + (str (u/join (u/ensure-path-slash base) + (join-path-segments segments)))) (defn get-public-uri "Canonical public URI builder: `join-uri` over the configured diff --git a/backend/test/backend_tests/config_test.clj b/backend/test/backend_tests/config_test.clj index 863be00a5e..3fb8a96e57 100644 --- a/backend/test/backend_tests/config_test.clj +++ b/backend/test/backend_tests/config_test.clj @@ -34,6 +34,15 @@ (t/is (= "https://nitrate.example.com/api/teams/123" (cf/join-uri "https://nitrate.example.com/" "api/teams/123"))))) +(t/deftest join-uri-joins-multiple-segments + (t/testing "path segments are appended instead of replacing previous segments" + (t/is (= "https://nitrate.example.com/admin-console/api/teams/team-id/users/profile-id" + (cf/join-uri "https://nitrate.example.com/admin-console" + "api/teams/" + "team-id" + "users/" + "profile-id"))))) + (t/deftest join-uri-rejects-leading-slash (t/testing "a leading slash would drop the subpath, so it fails fast" (t/is (thrown? AssertionError