🐛 Preserve public URI subpath in asset download URLs (#11234)

Join asset download paths relative to PENPOT_PUBLIC_URI so temporary
exports and binary file downloads retain configured subpaths.

Add regression coverage for both URL generation paths.

AI-assisted-by: gpt-5.6-sol
This commit is contained in:
Gennadiy Ivashchenko 2026-08-18 02:44:43 +05:00 committed by GitHub
parent fb9f92ae6a
commit 7f2dc66e86
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 27 additions and 4 deletions

View File

@ -63,7 +63,8 @@
:bucket "tempfile"})]
(-> (cf/get :public-uri)
(u/join "/assets/by-id/")
(u/ensure-path-slash)
(u/join "assets/by-id/")
(u/join (str (:id object)))))
(finally

View File

@ -47,5 +47,6 @@
object (sto/put-object! storage content)]
{:id (:id object)
:uri (-> (cf/get :public-uri)
(u/join "/assets/by-id/")
(u/ensure-path-slash)
(u/join "assets/by-id/")
(u/join (str (:id object))))}))

View File

@ -16,10 +16,12 @@
[app.common.thumbnails :as thc]
[app.common.types.shape :as cts]
[app.common.uuid :as uuid]
[app.config :as cf]
[app.db :as db]
[app.db.sql :as sql]
[app.http :as http]
[app.rpc :as-alias rpc]
[app.rpc.commands.binfile :as binfile]
[app.storage :as sto]
[app.storage.tmp :as tmp]
[backend-tests.helpers :as th]
@ -207,6 +209,18 @@
(t/is (= (count result) 1))
(t/is (every? uuid? result)))))
(t/deftest export-binfile-preserves-public-uri-subpath
(let [profile (th/create-profile* 1)
file (prepare-simple-file profile)
config (assoc cf/config :public-uri "https://example.com/penpot")
params {:file-id (:id file)
:include-libraries false
:embed-assets false}
uri (binding [cf/config config]
(#'binfile/export-binfile th/*system* params))]
(t/is (str/starts-with? (str uri)
"https://example.com/penpot/assets/by-id/"))))
(t/deftest read-obj-rejects-oversized-buffer
;; N1-07: read-obj! must reject objects exceeding max-object-size
;; before attempting to allocate the buffer

View File

@ -11,6 +11,7 @@
[app.common.pprint :as pp]
[app.common.types.shape :as cts]
[app.common.uuid :as uuid]
[app.config :as cf]
[app.db :as db]
[app.http :as http]
[app.rpc :as-alias rpc]
@ -19,6 +20,7 @@
[backend-tests.storage-test :refer [configure-storage-backend]]
[buddy.core.bytes :as b]
[clojure.test :as t]
[cuerdas.core :as str]
[datoteka.fs :as fs]
[datoteka.io :as io]))
@ -50,10 +52,15 @@
:path path
:mtype "image/png"
:size 7}}
out1 (th/management-command! params)
out2 (th/management-command! params)]
config (assoc cf/config :public-uri "https://example.com/penpot")
out1 (binding [cf/config config]
(th/management-command! params))
out2 (binding [cf/config config]
(th/management-command! params))]
(t/is (nil? (:error out1)))
(t/is (nil? (:error out2)))
(t/is (str/starts-with? (str (get-in out1 [:result :uri]))
"https://example.com/penpot/assets/by-id/"))
(t/is (not= (get-in out1 [:result :id])
(get-in out2 [:result :id])))))