mirror of
https://github.com/penpot/penpot.git
synced 2025-03-10 14:51:37 -05:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
31323703a8
21 changed files with 77 additions and 53 deletions
|
@ -22,11 +22,7 @@
|
|||
{% endif %}
|
||||
{% if item.params-schema-js %}
|
||||
<span class="tag">
|
||||
<span>SC</span>
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="tag">
|
||||
<span>SP</span>
|
||||
<span>SCHEMA</span>
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
<h2>GENERAL NOTES</h2>
|
||||
|
||||
<h3>Authentication</h3>
|
||||
<p>The penpot backend right now offerts two way for authenticate the request:
|
||||
<p>The penpot backend right now offers two way for authenticate the request:
|
||||
<b>cookies</b> (the same mechanism that we use ourselves on accessing the API from the
|
||||
web application) and <b>access tokens</b>.</p>
|
||||
|
||||
|
|
|
@ -6,13 +6,19 @@ penpot - error list
|
|||
|
||||
{% block content %}
|
||||
<nav>
|
||||
<h1>Latest error reports:</h1>
|
||||
<div class="title">
|
||||
<h1>Error reports (last 200)</h1>
|
||||
</div>
|
||||
</nav>
|
||||
<main class="horizontal-list">
|
||||
<ul>
|
||||
{% for item in items %}
|
||||
<li><a class="date" href="/dbg/error/{{item.id}}">{{item.created-at}}</a>
|
||||
<span class="title">{{item.hint|abbreviate:150}}</span></li>
|
||||
<li>
|
||||
<a class="date" href="/dbg/error/{{item.id}}">{{item.created-at}}</a>
|
||||
<a class="hint" href="/dbg/error/{{item.id}}">
|
||||
<span class="title">{{item.hint|abbreviate:150}}</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</main>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% extends "app/templates/base.tmpl" %}
|
||||
|
||||
{% block title %}
|
||||
penpot - error report v2 {{id}}
|
||||
Report: {{hint|abbreviate:150}} - {{id}} - Penpot Error Report (v3)
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
|
|
@ -50,7 +50,13 @@ nav {
|
|||
background: #e3e3e3;
|
||||
}
|
||||
|
||||
nav > h1 {
|
||||
nav > .title {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
nav > .title > h1 {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
font-size: 11px;
|
||||
|
@ -151,7 +157,6 @@ nav > div:not(:last-child) {
|
|||
line-height: 18px;
|
||||
min-width: 210px;
|
||||
margin: 0px 20px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
|
|
@ -391,13 +391,14 @@
|
|||
(defn- get-user-info
|
||||
[{:keys [provider]} tdata]
|
||||
(try
|
||||
(let [{:keys [kid alg] :as theader} (jwt/decode-header (:token/id tdata))]
|
||||
(when-let [key (if (str/starts-with? (name alg) "hs")
|
||||
(:client-secret provider)
|
||||
(get-in provider [:jwks kid]))]
|
||||
(when (:token/id tdata)
|
||||
(let [{:keys [kid alg] :as theader} (jwt/decode-header (:token/id tdata))]
|
||||
(when-let [key (if (str/starts-with? (name alg) "hs")
|
||||
(:client-secret provider)
|
||||
(get-in provider [:jwks kid]))]
|
||||
|
||||
(let [claims (jwt/unsign (:token/id tdata) key {:alg alg})]
|
||||
(dissoc claims :exp :iss :iat :sid :aud :sub))))
|
||||
(let [claims (jwt/unsign (:token/id tdata) key {:alg alg})]
|
||||
(dissoc claims :exp :iss :iat :sid :aud :sub)))))
|
||||
(catch Throwable cause
|
||||
(l/warn :hint "unable to get user info from JWT token (unexpected exception)"
|
||||
:cause cause))))
|
||||
|
|
|
@ -238,9 +238,9 @@
|
|||
(-> (io/resource "app/templates/error-report.v2.tmpl")
|
||||
(tmpl/render report)))
|
||||
|
||||
(render-template-v3 [{report :content}]
|
||||
(render-template-v3 [{report :content id :id}]
|
||||
(-> (io/resource "app/templates/error-report.v3.tmpl")
|
||||
(tmpl/render report)))
|
||||
(tmpl/render (assoc report :id id))))
|
||||
]
|
||||
|
||||
(when-not (authorized? pool request)
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
::yrs/headers headers}))
|
||||
|
||||
(defmethod handle-exception :validation
|
||||
[err _]
|
||||
[err request]
|
||||
(let [{:keys [code] :as data} (ex-data err)]
|
||||
(cond
|
||||
(= code :spec-validation)
|
||||
|
@ -95,6 +95,11 @@
|
|||
(= code :request-body-too-large)
|
||||
{::yrs/status 413 ::yrs/body data}
|
||||
|
||||
(= code :invalid-image)
|
||||
(binding [l/*context* (request->context request)]
|
||||
(l/error :hint "unexpected error on processing image" :cause err)
|
||||
{::yrs/status 400 ::yrs/body data})
|
||||
|
||||
:else
|
||||
{::yrs/status 400 ::yrs/body data})))
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
:trace (ex/format-throwable cause :data? false :explain? false :header? false :summary? false)}
|
||||
|
||||
(when-let [params (or (:request/params context) (:params context))]
|
||||
{:params (pp/pprint-str params :width 200)})
|
||||
{:params (pp/pprint-str params :width 200 :length 50 :level 10)})
|
||||
|
||||
(when-let [value (:value context)]
|
||||
{:value (pp/pprint-str value :width 200 :length 50 :level 10)})
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.exceptions :as ex]
|
||||
[app.common.logging :as l]
|
||||
[app.common.media :as cm]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.schema.generators :as sg]
|
||||
|
@ -227,7 +226,6 @@
|
|||
|
||||
(defmethod process-error org.im4java.core.InfoException
|
||||
[error]
|
||||
(l/error :hint "unexpected error on processing image" :cause error)
|
||||
(ex/raise :type :validation
|
||||
:code :invalid-image
|
||||
:hint "invalid image"
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
(sv/defmethod ::get-file-object-thumbnails
|
||||
"Retrieve a file object thumbnails."
|
||||
{::doc/added "1.17"
|
||||
::doc/module :files
|
||||
::sm/params [:map {:title "get-file-object-thumbnails"}
|
||||
[:file-id ::sm/uuid]]
|
||||
::sm/result [:map-of :string :string]
|
||||
|
@ -112,6 +113,7 @@
|
|||
|
||||
(sv/defmethod ::get-file-thumbnail
|
||||
{::doc/added "1.17"
|
||||
::doc/module :files
|
||||
::doc/deprecated "1.19"}
|
||||
[{:keys [::db/pool]} {:keys [::rpc/profile-id file-id revn]}]
|
||||
(dm/with-open [conn (db/open pool)]
|
||||
|
@ -229,11 +231,10 @@
|
|||
(sv/defmethod ::get-file-data-for-thumbnail
|
||||
"Retrieves the data for generate the thumbnail of the file. Used
|
||||
mainly for render thumbnails on dashboard."
|
||||
|
||||
{::doc/added "1.17"
|
||||
::doc/module :files
|
||||
::sm/params schema:get-file-data-for-thumbnail
|
||||
::sm/result schema:partial-file}
|
||||
|
||||
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id file-id features] :as props}]
|
||||
(dm/with-open [conn (db/open pool)]
|
||||
(files/check-read-permissions! conn profile-id file-id)
|
||||
|
@ -274,6 +275,7 @@
|
|||
|
||||
(sv/defmethod ::upsert-file-object-thumbnail
|
||||
{::doc/added "1.17"
|
||||
::doc/module :files
|
||||
::doc/deprecated "1.19"
|
||||
::audit/skip true}
|
||||
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id file-id] :as params}]
|
||||
|
@ -319,6 +321,7 @@
|
|||
|
||||
(sv/defmethod ::create-file-object-thumbnail
|
||||
{:doc/added "1.19"
|
||||
::doc/module :files
|
||||
::audit/skip true
|
||||
::sm/params schema:create-file-object-thumbnail}
|
||||
|
||||
|
@ -357,6 +360,7 @@
|
|||
|
||||
(sv/defmethod ::delete-file-object-thumbnail
|
||||
{:doc/added "1.19"
|
||||
::doc/module :files
|
||||
::audit/skip true}
|
||||
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id file-id object-id]}]
|
||||
|
||||
|
@ -395,6 +399,7 @@
|
|||
"Creates or updates the file thumbnail. Mainly used for paint the
|
||||
grid thumbnails."
|
||||
{::doc/added "1.17"
|
||||
::doc/module :files
|
||||
::doc/deprecated "1.19"
|
||||
::audit/skip true}
|
||||
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id file-id] :as params}]
|
||||
|
@ -437,6 +442,7 @@
|
|||
"Creates or updates the file thumbnail. Mainly used for paint the
|
||||
grid thumbnails."
|
||||
{::doc/added "1.19"
|
||||
::doc/module :files
|
||||
::audit/skip true
|
||||
::sm/params [:map {:title "create-file-thumbnail"}
|
||||
[:file-id ::sm/uuid]
|
||||
|
|
|
@ -38,7 +38,8 @@
|
|||
"Performs the authentication using LDAP backend. Only works if LDAP
|
||||
is properly configured and enabled with `login-with-ldap` flag."
|
||||
{::rpc/auth false
|
||||
::doc/added "1.15"}
|
||||
::doc/added "1.15"
|
||||
::doc/module :auth}
|
||||
[{:keys [::main/props ::ldap/provider] :as cfg} params]
|
||||
(when-not provider
|
||||
(ex/raise :type :restriction
|
||||
|
|
|
@ -171,7 +171,8 @@
|
|||
:opt-un [::id ::name]))
|
||||
|
||||
(sv/defmethod ::create-file-media-object-from-url
|
||||
{::doc/added "1.17"}
|
||||
{::doc/added "1.17"
|
||||
::doc/deprecated "1.19"}
|
||||
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id file-id] :as params}]
|
||||
(let [cfg (update cfg ::sto/storage media/configure-assets-storage)]
|
||||
(files/check-edition-permissions! pool profile-id file-id)
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
:opt-un [::search-term]))
|
||||
|
||||
(sv/defmethod ::search-files
|
||||
{::doc/added "1.17"}
|
||||
{::doc/added "1.17"
|
||||
::doc/module :files}
|
||||
[{:keys [::db/pool]} {:keys [::rpc/profile-id team-id search-term]}]
|
||||
(some->> search-term (search-files pool profile-id team-id)))
|
||||
|
|
|
@ -34,7 +34,8 @@
|
|||
|
||||
(sv/defmethod ::verify-token
|
||||
{::rpc/auth false
|
||||
::doc/added "1.15"}
|
||||
::doc/added "1.15"
|
||||
::doc/module :auth}
|
||||
[{:keys [::db/pool] :as cfg} {:keys [token] :as params}]
|
||||
(db/with-atomic [conn pool]
|
||||
(let [claims (tokens/verify (::main/props cfg) {:token token})
|
||||
|
|
|
@ -54,14 +54,14 @@
|
|||
{:name (::sv/name mdata)
|
||||
:module (or (some-> (::module mdata) d/name)
|
||||
(-> (:ns mdata) (str/split ".") last))
|
||||
:auth (:auth mdata true)
|
||||
:auth (::rpc/auth mdata true)
|
||||
:webhook (::webhooks/event? mdata false)
|
||||
:docs (::sv/docstring mdata)
|
||||
:deprecated (::deprecated mdata)
|
||||
:added (::added mdata)
|
||||
:changes (some->> (::changes mdata) (partition-all 2) (map vec))
|
||||
:spec (fmt-spec mdata)
|
||||
:entrypoint (str (cf/get :public-uri) "/api/rpc/commands/" (::sv/name mdata))
|
||||
:entrypoint (str (cf/get :public-uri) "/api/rpc/command/" (::sv/name mdata))
|
||||
|
||||
:params-schema-js (fmt-schema :js mdata ::sm/params)
|
||||
:result-schema-js (fmt-schema :js mdata ::sm/result)
|
||||
|
@ -156,7 +156,7 @@
|
|||
(map (partial gen-method-doc options))
|
||||
(sort-by (juxt :module :name))
|
||||
(map (fn [doc]
|
||||
[(str/ffmt "/commands/%" (:name doc)) (:repr doc)]))
|
||||
[(str/ffmt "/command/%" (:name doc)) (:repr doc)]))
|
||||
(into {})))]
|
||||
{:openapi "3.0.0"
|
||||
:info {:version (:main cf/version)}
|
||||
|
|
|
@ -248,7 +248,7 @@
|
|||
[:map
|
||||
[:width :int]
|
||||
[:height :int]
|
||||
[:mtype :string]
|
||||
[:mtype {:optional true} [:maybe :string]]
|
||||
[:id ::sm/uuid]]]])
|
||||
|
||||
(sm/def! ::path-attrs
|
||||
|
|
|
@ -73,16 +73,20 @@
|
|||
(rx/map #(svg/add-svg-shapes (assoc svg-data :image-data %) position))))))
|
||||
|
||||
(defn- process-uris
|
||||
[{:keys [file-id local? name uris mtype on-image on-svg]}]
|
||||
[{:keys [file-id local? name uris mtype on-image on-svg] }]
|
||||
(letfn [(svg-url? [url]
|
||||
(or (and mtype (= mtype "image/svg+xml"))
|
||||
(str/ends-with? url ".svg")))
|
||||
|
||||
(prepare [uri]
|
||||
{:file-id file-id
|
||||
:is-local local?
|
||||
:name (or name (svg/extract-name uri))
|
||||
:url uri})
|
||||
(upload [uri]
|
||||
(->> (http/send! {:method :get :uri uri :mode :no-cors :response-type :blob})
|
||||
(rx/map :body)
|
||||
(rx/map (fn [content]
|
||||
{:file-id file-id
|
||||
:name (or name (svg/extract-name uri))
|
||||
:is-local local?
|
||||
:content content}))
|
||||
(rx/mapcat #(rp/cmd! :upload-file-media-object %))))
|
||||
|
||||
(fetch-svg [name uri]
|
||||
(->> (http/send! {:method :get :uri uri :mode :no-cors})
|
||||
|
@ -93,8 +97,7 @@
|
|||
(rx/merge
|
||||
(->> (rx/from uris)
|
||||
(rx/filter (comp not svg-url?))
|
||||
(rx/map prepare)
|
||||
(rx/mapcat #(rp/cmd! :create-file-media-object-from-url %))
|
||||
(rx/mapcat upload)
|
||||
(rx/do on-image))
|
||||
|
||||
(->> (rx/from uris)
|
||||
|
@ -142,7 +145,7 @@
|
|||
[:local? :boolean]
|
||||
[:name {:optional true} :string]
|
||||
[:data {:optional true} :any] ; FIXME
|
||||
[:uris {:optional true} [:vector :string]]
|
||||
[:uris {:optional true} [:sequential :string]]
|
||||
[:mtype {:optional true} :string]])
|
||||
|
||||
(defn- process-media-objects
|
||||
|
@ -213,8 +216,6 @@
|
|||
:on-image #(st/emit! (dwl/add-media %)))]
|
||||
(process-media-objects params)))
|
||||
|
||||
;; TODO: it is really need handle SVG here, looks like it already
|
||||
;; handled separately
|
||||
(defn upload-media-workspace
|
||||
[{:keys [position file-id] :as params}]
|
||||
(let [params (assoc params
|
||||
|
|
|
@ -458,8 +458,8 @@
|
|||
(dnd/has-type? event "text/uri-list")
|
||||
(let [data (dnd/get-data event "text/uri-list")
|
||||
lines (str/lines data)
|
||||
uris (->> lines (filter #(str/starts-with? % "http")))
|
||||
data (->> lines (filter #(str/starts-with? % "data:image/")))
|
||||
uris (filterv #(str/starts-with? % "http") lines)
|
||||
data (filterv #(str/starts-with? % "data:image/") lines)
|
||||
params {:file-id (:id file)
|
||||
:position viewport-coord}
|
||||
params (if (seq uris)
|
||||
|
|
|
@ -151,9 +151,9 @@
|
|||
(rx/tap (fn [[fonts]]
|
||||
(when (seq fonts)
|
||||
(st/emit! (df/fonts-fetched fonts)))))
|
||||
(rx/map (comp :objects second))))))
|
||||
(rx/map (fn [[_ page]] {:objects (:objects page)}))))))
|
||||
|
||||
objects (use-resource fetch-state)]
|
||||
{:keys [objects]} (use-resource fetch-state)]
|
||||
|
||||
(when objects
|
||||
(for [object-id object-ids]
|
||||
|
|
|
@ -737,12 +737,13 @@
|
|||
:fill-color-ref-file (get-meta fill-node :fill-color-ref-file uuid/uuid)
|
||||
:fill-color-ref-id (get-meta fill-node :fill-color-ref-id uuid/uuid)
|
||||
:fill-opacity (get-meta fill-node :fill-opacity d/parse-double)}))
|
||||
(mapv d/without-nils))]
|
||||
(mapv d/without-nils)
|
||||
(filterv #(not= (:fill-color %) "none")))]
|
||||
(if (seq fills)
|
||||
fills
|
||||
(->> [(-> (add-fill {} node svg-data)
|
||||
(d/without-nils))]
|
||||
(filterv not-empty)))))
|
||||
(filterv #(and (not-empty %) (not= (:fill-color %) "none")))))))
|
||||
|
||||
(defn parse-strokes
|
||||
[node svg-data]
|
||||
|
@ -761,12 +762,13 @@
|
|||
:stroke-alignment (get-meta stroke-node :stroke-alignment keyword)
|
||||
:stroke-cap-start (get-meta stroke-node :stroke-cap-start keyword)
|
||||
:stroke-cap-end (get-meta stroke-node :stroke-cap-end keyword)}))
|
||||
(mapv d/without-nils))]
|
||||
(mapv d/without-nils)
|
||||
(filterv #(not= (:stroke-color %) "none")))]
|
||||
(if (seq strokes)
|
||||
strokes
|
||||
(->> [(-> (add-stroke {} node svg-data)
|
||||
(d/without-nils))]
|
||||
(filterv #(and (not-empty %) (not= (:stroke-style %) :none)))))))
|
||||
(filterv #(and (not-empty %) (not= (:stroke-color %) "none") (not= (:stroke-style %) :none)))))))
|
||||
|
||||
(defn add-svg-content
|
||||
[props node]
|
||||
|
|
Loading…
Add table
Reference in a new issue