mirror of
https://github.com/penpot/penpot.git
synced 2025-03-13 08:11:30 -05:00
✨ Make the upload media size configurable
This commit is contained in:
parent
0471df36ef
commit
b9b53258c1
24 changed files with 66 additions and 60 deletions
|
@ -31,6 +31,7 @@
|
|||
- Support for import/export binary format [Taiga #2991](https://tree.taiga.io/project/penpot/us/2991)
|
||||
- Comments positioning [Taiga #2007](https://tree.taiga.io/project/penpot/us/2007)
|
||||
- Select all inside a group select only the objects at this group level [Taiga #2382](https://tree.taiga.io/project/penpot/issue/2382)
|
||||
- Make the media maximum upload size configurable
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
|
|
|
@ -83,11 +83,11 @@
|
|||
;; a server prop key where initial project is stored.
|
||||
:initial-project-skey "initial-project"})
|
||||
|
||||
(s/def ::flags ::us/vec-of-valid-keywords)
|
||||
|
||||
;; DEPRECATED PROPERTIES
|
||||
(s/def ::media-max-file-size ::us/integer)
|
||||
|
||||
(s/def ::flags ::us/vec-of-valid-keywords)
|
||||
(s/def ::telemetry-enabled ::us/boolean)
|
||||
;; END DEPRECATED
|
||||
|
||||
(s/def ::audit-log-archive-uri ::us/string)
|
||||
(s/def ::audit-log-gc-max-age ::dt/duration)
|
||||
|
@ -143,8 +143,6 @@
|
|||
(s/def ::http-server-max-multipart-body-size ::us/integer)
|
||||
(s/def ::http-server-io-threads ::us/integer)
|
||||
(s/def ::http-server-worker-threads ::us/integer)
|
||||
(s/def ::http-session-updater-batch-max-age ::dt/duration)
|
||||
(s/def ::http-session-updater-batch-max-size ::us/integer)
|
||||
(s/def ::initial-project-skey ::us/string)
|
||||
(s/def ::ldap-attrs-email ::us/string)
|
||||
(s/def ::ldap-attrs-fullname ::us/string)
|
||||
|
@ -251,8 +249,6 @@
|
|||
::http-server-max-multipart-body-size
|
||||
::http-server-io-threads
|
||||
::http-server-worker-threads
|
||||
::http-session-updater-batch-max-age
|
||||
::http-session-updater-batch-max-size
|
||||
::initial-project-skey
|
||||
::ldap-attrs-email
|
||||
::ldap-attrs-fullname
|
||||
|
@ -268,6 +264,7 @@
|
|||
::local-assets-uri
|
||||
::loggers-loki-uri
|
||||
::loggers-zmq-uri
|
||||
::media-max-file-size
|
||||
::profile-bounce-max-age
|
||||
::profile-bounce-threshold
|
||||
::profile-complaint-max-age
|
||||
|
|
|
@ -22,9 +22,12 @@
|
|||
[app.util.services :as sv]
|
||||
[app.util.time :as dt]
|
||||
[clojure.spec.alpha :as s]
|
||||
[cuerdas.core :as str]
|
||||
[promesa.core :as p]
|
||||
[promesa.exec :as px]))
|
||||
|
||||
(def default-max-file-size (* 1024 1024 10)) ; 10 MiB
|
||||
|
||||
(def thumbnail-options
|
||||
{:width 100
|
||||
:height 100
|
||||
|
@ -51,10 +54,20 @@
|
|||
|
||||
(sv/defmethod ::upload-file-media-object
|
||||
{::rlimit/permits (cf/get :rlimit-image)}
|
||||
[{:keys [pool] :as cfg} {:keys [profile-id file-id] :as params}]
|
||||
[{:keys [pool] :as cfg} {:keys [profile-id file-id content] :as params}]
|
||||
(let [file (select-file pool file-id)
|
||||
cfg (update cfg :storage media/configure-assets-storage)]
|
||||
|
||||
(teams/check-edition-permissions! pool profile-id (:team-id file))
|
||||
(media/validate-media-type! content)
|
||||
|
||||
(when (> (:size content) (cf/get :media-max-file-size default-max-file-size))
|
||||
(ex/raise :type :restriction
|
||||
:code :media-max-file-size-reached
|
||||
:hint (str/ffmt "the uploaded file size % is greater than the maximum %"
|
||||
(:size content)
|
||||
default-max-file-size)))
|
||||
|
||||
(create-file-media-object cfg params)))
|
||||
|
||||
(defn- big-enough-for-thumbnail?
|
||||
|
@ -94,8 +107,6 @@
|
|||
|
||||
(defn create-file-media-object
|
||||
[{:keys [storage pool executors] :as cfg} {:keys [id file-id is-local name content] :as params}]
|
||||
(media/validate-media-type! content)
|
||||
|
||||
(letfn [;; Function responsible to retrieve the file information, as
|
||||
;; it is synchronous operation it should be wrapped into
|
||||
;; with-dispatch macro.
|
||||
|
@ -177,30 +188,30 @@
|
|||
(teams/check-edition-permissions! pool profile-id (:team-id file))
|
||||
(create-file-media-object-from-url cfg params)))
|
||||
|
||||
(def max-download-file-size
|
||||
(* 1024 1024 100)) ; 100MiB
|
||||
|
||||
(defn- create-file-media-object-from-url
|
||||
[{:keys [http-client] :as cfg} {:keys [url name] :as params}]
|
||||
(letfn [(parse-and-validate-size [headers]
|
||||
(let [size (some-> (get headers "content-length") d/parse-integer)
|
||||
mtype (get headers "content-type")
|
||||
format (cm/mtype->format mtype)]
|
||||
(let [size (some-> (get headers "content-length") d/parse-integer)
|
||||
mtype (get headers "content-type")
|
||||
format (cm/mtype->format mtype)
|
||||
max-size (cf/get :media-max-file-size default-max-file-size)]
|
||||
|
||||
(when-not size
|
||||
(ex/raise :type :validation
|
||||
:code :unknown-size
|
||||
:hint "Seems like the url points to resource with unknown size"))
|
||||
:hint "seems like the url points to resource with unknown size"))
|
||||
|
||||
(when (> size max-download-file-size)
|
||||
(when (> size max-size)
|
||||
(ex/raise :type :validation
|
||||
:code :file-too-large
|
||||
:hint "Seems like the url points to resource with size greater than 100MiB"))
|
||||
:hint (str/ffmt "the file size % is greater than the maximum %"
|
||||
size
|
||||
default-max-file-size)))
|
||||
|
||||
(when (nil? format)
|
||||
(ex/raise :type :validation
|
||||
:code :media-type-not-allowed
|
||||
:hint "Seems like the url points to an invalid media object"))
|
||||
:hint "seems like the url points to an invalid media object"))
|
||||
|
||||
{:size size
|
||||
:mtype mtype
|
||||
|
|
|
@ -59,8 +59,6 @@
|
|||
"application/pdf" ".pdf"
|
||||
nil))
|
||||
|
||||
(def max-file-size (* 5 1024 1024))
|
||||
|
||||
(s/def ::id uuid?)
|
||||
(s/def ::name string?)
|
||||
(s/def ::width number?)
|
||||
|
|
|
@ -19,8 +19,8 @@ http {
|
|||
server_tokens off;
|
||||
|
||||
reset_timedout_connection on;
|
||||
client_body_timeout 20s;
|
||||
client_header_timeout 20s;
|
||||
client_body_timeout 30s;
|
||||
client_header_timeout 30s;
|
||||
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
@ -49,7 +49,7 @@ http {
|
|||
listen 80 default_server;
|
||||
server_name _;
|
||||
|
||||
client_max_body_size 50M;
|
||||
client_max_body_size 100M;
|
||||
charset utf-8;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
|
@ -78,10 +78,6 @@ http {
|
|||
proxy_pass http://penpot-backend:6060/api;
|
||||
}
|
||||
|
||||
location /dbg {
|
||||
proxy_pass http://penpot-backend:6060/dbg;
|
||||
}
|
||||
|
||||
location /ws/notifications {
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
|
|
|
@ -35,12 +35,9 @@
|
|||
|
||||
;; --- Utility functions
|
||||
|
||||
(defn validate-file ;; Check that a file obtained with the file javascript API is valid.
|
||||
(defn validate-file
|
||||
"Check that a file obtained with the file javascript API is valid."
|
||||
[file]
|
||||
(when (> (.-size file) cm/max-file-size)
|
||||
(ex/raise :type :validation
|
||||
:code :media-too-large
|
||||
:hint (str/fmt "media size is large than 5mb (size: %s)" (.-size file))))
|
||||
(when-not (contains? cm/valid-image-types (.-type file))
|
||||
(ex/raise :type :validation
|
||||
:code :media-type-not-allowed
|
||||
|
|
|
@ -200,7 +200,7 @@
|
|||
(= (:code error) :invalid-image)
|
||||
(rx/of (dm/error (tr "errors.media-type-not-allowed")))
|
||||
|
||||
(= (:code error) :media-too-large)
|
||||
(= (:code error) :media-max-file-size-reached)
|
||||
(rx/of (dm/error (tr "errors.media-too-large")))
|
||||
|
||||
(= (:code error) :media-type-mismatch)
|
||||
|
|
|
@ -46,6 +46,14 @@
|
|||
;; Set the main potok error handler
|
||||
(reset! st/on-error on-error)
|
||||
|
||||
(defmethod ptk/handle-error :default
|
||||
[error]
|
||||
(let [hint (str/concat "Unexpected error: " (:hint error))]
|
||||
(ts/schedule #(st/emit! (rt/assign-exception error)))
|
||||
(js/console.group hint)
|
||||
(ex/ignoring (js/console.error (pr-str error)))
|
||||
(js/console.groupEnd hint)))
|
||||
|
||||
;; We receive a explicit authentication error; this explicitly clears
|
||||
;; all profile data and redirect the user to the login page. This is
|
||||
;; here and not in app.main.errors because of circular dependency.
|
||||
|
@ -188,9 +196,10 @@
|
|||
(defn on-unhandled-error
|
||||
[error]
|
||||
(letfn [(is-ignorable-exception? [cause]
|
||||
(condp = (ex-message cause)
|
||||
"Possible side-effect in debug-evaluate" true
|
||||
false))]
|
||||
(let [message (ex-message cause)]
|
||||
(or (= message "Possible side-effect in debug-evaluate")
|
||||
(= message "Unexpected end of input") true
|
||||
(str/starts-with? message "Unexpected token "))))]
|
||||
(if (instance? ExceptionInfo error)
|
||||
(-> error ex-data ptk/handle-error)
|
||||
(when-not (is-ignorable-exception? error)
|
||||
|
@ -203,12 +212,9 @@
|
|||
|
||||
(defonce uncaught-error-handler
|
||||
(letfn [(on-error [event]
|
||||
;; EvalError is a debug error that happens for unknown reason
|
||||
(when-not (str/includes? (.-message event) "EvalError")
|
||||
(.error js/console event)
|
||||
(.preventDefault ^js event)
|
||||
(some-> (unchecked-get event "error")
|
||||
(on-unhandled-error))))]
|
||||
(.preventDefault ^js event)
|
||||
(some-> (unchecked-get event "error")
|
||||
(on-unhandled-error)))]
|
||||
(.addEventListener glob/window "error" on-error)
|
||||
(fn []
|
||||
(.removeEventListener glob/window "error" on-error))))
|
||||
|
|
|
@ -499,7 +499,7 @@ msgstr "تنسيق الصورة غير مدعوم (يجب أن يكون svg أو
|
|||
|
||||
#: src/app/main/data/workspace/persistence.cljs
|
||||
msgid "errors.media-too-large"
|
||||
msgstr "الصورة كبيرة جدا بحيث لا يمكن إدراجها (يجب أن تكون أقل من 5mb)."
|
||||
msgstr "الصورة كبيرة جدا بحيث لا يمكن إدراجها."
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "errors.media-type-mismatch"
|
||||
|
|
|
@ -678,7 +678,7 @@ msgstr "El format d'imatge no està suportat (ha de ser SVG, JPG o PNG)."
|
|||
|
||||
#: src/app/main/data/workspace/persistence.cljs
|
||||
msgid "errors.media-too-large"
|
||||
msgstr "La imatge és massa gran (ha de ser inferior a 5 MB)."
|
||||
msgstr "La imatge és massa gran."
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "errors.media-type-mismatch"
|
||||
|
|
|
@ -693,7 +693,7 @@ msgstr "Das Bildformat wird nicht unterstützt (es muss ein SVG, JPG oder PNG se
|
|||
|
||||
#: src/app/main/data/workspace/persistence.cljs
|
||||
msgid "errors.media-too-large"
|
||||
msgstr "Das Bild ist zu groß, um eingefügt zu werden (es muss unter 5MB sein)."
|
||||
msgstr "Das Bild ist zu groß, um eingefügt zu werden."
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "errors.media-type-mismatch"
|
||||
|
|
|
@ -414,7 +414,7 @@ msgstr "Η μορφή εικόνας δεν αναγνωρίζεται (πρέπ
|
|||
|
||||
#: src/app/main/data/workspace/persistence.cljs
|
||||
msgid "errors.media-too-large"
|
||||
msgstr "Η εικόνα είναι πολύ μεγάλη (πρέπει να είναι μικρότερη από 5mb)."
|
||||
msgstr "Η εικόνα είναι πολύ μεγάλη."
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "errors.media-type-mismatch"
|
||||
|
|
|
@ -720,7 +720,7 @@ msgstr "The image format is not supported (must be svg, jpg or png)."
|
|||
|
||||
#: src/app/main/data/workspace/persistence.cljs
|
||||
msgid "errors.media-too-large"
|
||||
msgstr "The image is too large to be inserted (must be under 5mb)."
|
||||
msgstr "The image is too large to be inserted."
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "errors.media-type-mismatch"
|
||||
|
|
|
@ -738,7 +738,7 @@ msgstr "No se reconoce el formato de imagen (debe ser svg, jpg o png)."
|
|||
|
||||
#: src/app/main/data/workspace/persistence.cljs
|
||||
msgid "errors.media-too-large"
|
||||
msgstr "La imagen es demasiado grande (debe tener menos de 5mb)."
|
||||
msgstr "La imagen es demasiado grande."
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "errors.media-type-mismatch"
|
||||
|
|
|
@ -670,7 +670,7 @@ msgstr "فرمت تصویر پشتیبانی نمیشود (باید svg، jpg
|
|||
|
||||
#: src/app/main/data/workspace/persistence.cljs
|
||||
msgid "errors.media-too-large"
|
||||
msgstr "تصویر برای درج خیلی بزرگ است (باید کمتر از 5 مگابایت باشد)."
|
||||
msgstr "تصویر برای درج خیلی بزرگ است."
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "errors.media-type-mismatch"
|
||||
|
|
|
@ -703,7 +703,7 @@ msgstr "Le format d’image n’est pas supporté (doit être svg, jpg ou png)."
|
|||
|
||||
#: src/app/main/data/workspace/persistence.cljs
|
||||
msgid "errors.media-too-large"
|
||||
msgstr "L’image est trop grande (doit être inférieure à 5 Mo)."
|
||||
msgstr "L’image est trop grande."
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "errors.media-type-mismatch"
|
||||
|
|
|
@ -675,7 +675,7 @@ msgstr "סוג התמונה אינו נתמך (חייב להיות svg, jpg
|
|||
|
||||
#: src/app/main/data/workspace/persistence.cljs
|
||||
msgid "errors.media-too-large"
|
||||
msgstr "התמונה גדולה מכדי להוסיף אותה (חייבת להיות פחות מ־5 מ״ב)."
|
||||
msgstr "התמונה גדולה מכדי להוסיף אותה."
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "errors.media-type-mismatch"
|
||||
|
|
|
@ -680,7 +680,7 @@ msgstr "Format obrazu nie jest obsługiwany (musi to być svg, jpg lub png)."
|
|||
|
||||
#: src/app/main/data/workspace/persistence.cljs
|
||||
msgid "errors.media-too-large"
|
||||
msgstr "Obraz jest zbyt duży (musi mieć mniej niż 5 MB)."
|
||||
msgstr "Obraz jest zbyt duży."
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "errors.media-type-mismatch"
|
||||
|
|
|
@ -591,7 +591,7 @@ msgstr "O formato da imagem não é compatível (deve ser svg, jpg ou png)."
|
|||
|
||||
#: src/app/main/data/workspace/persistence.cljs
|
||||
msgid "errors.media-too-large"
|
||||
msgstr "A imagem é muito grande para ser inserida (deve ter menos de 5mb)."
|
||||
msgstr "A imagem é muito grande para ser inserida."
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "errors.media-type-mismatch"
|
||||
|
|
|
@ -469,7 +469,7 @@ msgstr "Formatul imaginii nu este acceptat (poate fi svg, jpg sau png)."
|
|||
|
||||
#: src/app/main/data/workspace/persistence.cljs
|
||||
msgid "errors.media-too-large"
|
||||
msgstr "Imaginea este prea mare pentru a fi inserată (trebuie să fie sub 5mb)."
|
||||
msgstr "Imaginea este prea mare pentru a fi inserată."
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "errors.media-type-mismatch"
|
||||
|
|
|
@ -632,7 +632,7 @@ msgstr "Формат изображения не поддерживается (
|
|||
|
||||
#: src/app/main/data/workspace/persistence.cljs
|
||||
msgid "errors.media-too-large"
|
||||
msgstr "Изображение слишком большое для вставки (должно быть меньше 5mb)."
|
||||
msgstr "Изображение слишком большое для вставки."
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "errors.media-type-mismatch"
|
||||
|
|
|
@ -692,7 +692,7 @@ msgstr "Görsel biçimi desteklenmiyor (svg, jpg veya png olmalı)."
|
|||
|
||||
#: src/app/main/data/workspace/persistence.cljs
|
||||
msgid "errors.media-too-large"
|
||||
msgstr "Bu görsel eklemek için çok büyük (5MB altında olmalı)."
|
||||
msgstr "Bu görsel eklemek için çok büyük."
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "errors.media-type-mismatch"
|
||||
|
|
|
@ -655,7 +655,7 @@ msgstr "不支持该图片格式(只能是svg、jpg或png)。"
|
|||
|
||||
#: src/app/main/data/workspace/persistence.cljs
|
||||
msgid "errors.media-too-large"
|
||||
msgstr "图片尺寸过大,故无法插入(不能超过5MB)。"
|
||||
msgstr "图片尺寸过大,故无法插入。"
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "errors.media-type-mismatch"
|
||||
|
|
|
@ -541,7 +541,7 @@ msgstr "不支援此影像格式(必須是 svg,jpg 或者 png)"
|
|||
|
||||
#: src/app/main/data/workspace/persistence.cljs
|
||||
msgid "errors.media-too-large"
|
||||
msgstr "影像檔案過大,無法插入(須小於 5MB)"
|
||||
msgstr "影像檔案過大,無法插入"
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/workspace/persistence.cljs, src/app/main/data/workspace/persistence.cljs, src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "errors.media-type-not-allowed"
|
||||
|
|
Loading…
Add table
Reference in a new issue