From 91118bec709b261cef0b95f191e15fc27fcae738 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 14 Mar 2024 10:29:21 +0100 Subject: [PATCH 1/2] :sparkles: Improve internal naming of setup/props This reverts commit a6f70c77cbe72875875ab83587d5dcd9cfc61e34. --- backend/src/app/auth/oidc.clj | 11 +++++----- backend/src/app/http.clj | 3 ++- backend/src/app/http/access_token.clj | 3 ++- backend/src/app/http/awsns.clj | 5 +++-- backend/src/app/http/client.clj | 4 ++-- backend/src/app/http/debug.clj | 3 ++- backend/src/app/http/session.clj | 5 +++-- backend/src/app/loggers/audit.clj | 13 ++++++------ backend/src/app/main.clj | 18 ++++++++-------- backend/src/app/rpc.clj | 5 +++-- backend/src/app/rpc/commands/access_token.clj | 5 +++-- backend/src/app/rpc/commands/auth.clj | 21 ++++++++++--------- backend/src/app/rpc/commands/ldap.clj | 3 ++- backend/src/app/rpc/commands/profile.clj | 5 +++-- backend/src/app/rpc/commands/teams.clj | 5 +++-- backend/src/app/rpc/commands/verify_token.clj | 3 ++- backend/src/app/setup.clj | 9 ++++---- backend/src/app/tasks/telemetry.clj | 5 +++-- .../backend_tests/bounce_handling_test.clj | 14 ++++++------- 19 files changed, 77 insertions(+), 63 deletions(-) diff --git a/backend/src/app/auth/oidc.clj b/backend/src/app/auth/oidc.clj index 9e07a21e2..34e2cee57 100644 --- a/backend/src/app/auth/oidc.clj +++ b/backend/src/app/auth/oidc.clj @@ -22,6 +22,7 @@ [app.loggers.audit :as audit] [app.main :as-alias main] [app.rpc.commands.profile :as profile] + [app.setup :as-alias setup] [app.tokens :as tokens] [app.util.json :as json] [app.util.time :as dt] @@ -413,7 +414,7 @@ ::props])) (defn get-info - [{:keys [provider ::main/props] :as cfg} {:keys [params] :as request}] + [{:keys [provider ::setup/props] :as cfg} {:keys [params] :as request}] (when-let [error (get params :error)] (ex/raise :type :internal :code :error-on-retrieving-code @@ -508,7 +509,7 @@ (if profile (let [sxf (session/create-fn cfg (:id profile)) token (or (:invitation-token info) - (tokens/generate (::main/props cfg) + (tokens/generate (::setup/props cfg) {:iss :auth :exp (dt/in-future "15m") :profile-id (:id profile)})) @@ -536,7 +537,7 @@ :iss :prepared-register :is-active true :exp (dt/in-future {:hours 48})) - token (tokens/generate (::main/props cfg) info) + token (tokens/generate (::setup/props cfg) info) params (d/without-nils {:token token :fullname (:fullname info)}) @@ -551,7 +552,7 @@ (defn- auth-handler [cfg {:keys [params] :as request}] (let [props (audit/extract-utm-params params) - state (tokens/generate (::main/props cfg) + state (tokens/generate (::setup/props cfg) {:iss :oauth :invitation-token (:invitation-token params) :props props @@ -618,7 +619,7 @@ [_] (s/keys :req [::session/manager ::http/client - ::main/props + ::setup/props ::db/pool ::providers])) diff --git a/backend/src/app/http.clj b/backend/src/app/http.clj index 1e605cdb0..a696d5477 100644 --- a/backend/src/app/http.clj +++ b/backend/src/app/http.clj @@ -23,6 +23,7 @@ [app.metrics :as mtx] [app.rpc :as-alias rpc] [app.rpc.doc :as-alias rpc.doc] + [app.setup :as-alias setup] [clojure.spec.alpha :as s] [integrant.core :as ig] [promesa.exec :as px] @@ -136,7 +137,7 @@ ::rpc/routes ::rpc.doc/routes ::oidc/routes - ::main/props + ::setup/props ::assets/routes ::debug/routes ::db/pool diff --git a/backend/src/app/http/access_token.clj b/backend/src/app/http/access_token.clj index bfddbb42d..0d1865f10 100644 --- a/backend/src/app/http/access_token.clj +++ b/backend/src/app/http/access_token.clj @@ -10,6 +10,7 @@ [app.config :as cf] [app.db :as db] [app.main :as-alias main] + [app.setup :as-alias setup] [app.tokens :as tokens] [ring.request :as rreq])) @@ -42,7 +43,7 @@ (defn- wrap-soft-auth "Soft Authentication, will be executed synchronously on the undertow worker thread." - [handler {:keys [::main/props]}] + [handler {:keys [::setup/props]}] (letfn [(handle-request [request] (try (let [token (get-token request) diff --git a/backend/src/app/http/awsns.clj b/backend/src/app/http/awsns.clj index 7508be8a2..88060bb20 100644 --- a/backend/src/app/http/awsns.clj +++ b/backend/src/app/http/awsns.clj @@ -13,6 +13,7 @@ [app.db.sql :as sql] [app.http.client :as http] [app.main :as-alias main] + [app.setup :as-alias setup] [app.tokens :as tokens] [app.worker :as-alias wrk] [clojure.spec.alpha :as s] @@ -30,7 +31,7 @@ (defmethod ig/pre-init-spec ::routes [_] (s/keys :req [::http/client - ::main/props + ::setup/props ::db/pool])) (defmethod ig/init-key ::routes @@ -106,7 +107,7 @@ [cfg headers] (let [tdata (get headers "x-penpot-data")] (when-not (str/empty? tdata) - (let [result (tokens/verify (::main/props cfg) {:token tdata :iss :profile-identity})] + (let [result (tokens/verify (::setup/props cfg) {:token tdata :iss :profile-identity})] (:profile-id result))))) (defn- parse-notification diff --git a/backend/src/app/http/client.clj b/backend/src/app/http/client.clj index 5b4a8541c..9ef4cc4b2 100644 --- a/backend/src/app/http/client.clj +++ b/backend/src/app/http/client.clj @@ -55,8 +55,8 @@ convention." ([cfg-or-client request] (let [client (resolve-client cfg-or-client)] - (send! client request {}))) + (send! client request {:sync? true}))) ([cfg-or-client request options] (let [client (resolve-client cfg-or-client)] - (send! client request options)))) + (send! client request (merge {:sync? true} options))))) diff --git a/backend/src/app/http/debug.clj b/backend/src/app/http/debug.clj index 1d2a129cf..a453c6872 100644 --- a/backend/src/app/http/debug.clj +++ b/backend/src/app/http/debug.clj @@ -20,6 +20,7 @@ [app.rpc.commands.auth :as auth] [app.rpc.commands.files-create :refer [create-file]] [app.rpc.commands.profile :as profile] + [app.setup :as-alias setup] [app.srepl.helpers :as srepl] [app.storage :as-alias sto] [app.storage.tmp :as tmp] @@ -340,7 +341,7 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defn- resend-email-notification - [{:keys [::db/pool ::main/props] :as cfg} {:keys [params] :as request}] + [{:keys [::db/pool ::setup/props] :as cfg} {:keys [params] :as request}] (when-not (contains? params :force) (ex/raise :type :validation diff --git a/backend/src/app/http/session.clj b/backend/src/app/http/session.clj index 7ff6dfa01..c4a3f0ba6 100644 --- a/backend/src/app/http/session.clj +++ b/backend/src/app/http/session.clj @@ -15,6 +15,7 @@ [app.db.sql :as sql] [app.http.session.tasks :as-alias tasks] [app.main :as-alias main] + [app.setup :as-alias setup] [app.tokens :as tokens] [app.util.time :as dt] [clojure.spec.alpha :as s] @@ -138,7 +139,7 @@ (declare ^:private gen-token) (defn create-fn - [{:keys [::manager ::main/props]} profile-id] + [{:keys [::manager ::setup/props]} profile-id] (us/assert! ::manager manager) (us/assert! ::us/uuid profile-id) @@ -196,7 +197,7 @@ (neg? (compare default-renewal-max-age elapsed))))) (defn- wrap-soft-auth - [handler {:keys [::manager ::main/props]}] + [handler {:keys [::manager ::setup/props]}] (us/assert! ::manager manager) (letfn [(handle-request [request] (try diff --git a/backend/src/app/loggers/audit.clj b/backend/src/app/loggers/audit.clj index 45c36334a..aead09110 100644 --- a/backend/src/app/loggers/audit.clj +++ b/backend/src/app/loggers/audit.clj @@ -24,6 +24,7 @@ [app.main :as-alias main] [app.rpc :as-alias rpc] [app.rpc.retry :as rtry] + [app.setup :as-alias setup] [app.tokens :as tokens] [app.util.services :as-alias sv] [app.util.time :as dt] @@ -261,7 +262,7 @@ (s/def ::tasks/uri ::us/string) (defmethod ig/pre-init-spec ::tasks/archive-task [_] - (s/keys :req [::db/pool ::main/props ::http.client/client])) + (s/keys :req [::db/pool ::setup/props ::http.client/client])) (defmethod ig/init-key ::tasks/archive [_ cfg] @@ -287,7 +288,7 @@ (px/sleep 100) (recur (+ total ^long n))) (when (pos? total) - (l/debug :hint "events archived" :total total))))))))) + (l/dbg :hint "events archived" :total total))))))))) (def ^:private sql:retrieve-batch-of-audit-log "select * @@ -322,7 +323,7 @@ :context])) (send [events] - (let [token (tokens/generate (::main/props cfg) + (let [token (tokens/generate (::setup/props cfg) {:iss "authentication" :iat (dt/now) :uid uuid/zero}) @@ -331,11 +332,11 @@ "origin" (cf/get :public-uri) "cookie" (u/map->query-string {:auth-token token})} params {:uri uri - :timeout 6000 + :timeout 12000 :method :post :headers headers :body body} - resp (http.client/req! cfg params {:sync? true})] + resp (http.client/req! cfg params)] (if (= (:status resp) 204) true (do @@ -355,7 +356,7 @@ (map row->event)) events (into [] xform rows)] (when-not (empty? events) - (l/trace :hint "archive events chunk" :uri uri :events (count events)) + (l/trc :hint "archive events chunk" :uri uri :events (count events)) (when (send events) (mark-as-archived conn rows) (count events))))))) diff --git a/backend/src/app/main.clj b/backend/src/app/main.clj index 47e43f5cf..e0177110f 100644 --- a/backend/src/app/main.clj +++ b/backend/src/app/main.clj @@ -221,7 +221,7 @@ {::db/pool (ig/ref ::db/pool)} ::http.awsns/routes - {::props (ig/ref ::setup/props) + {::setup/props (ig/ref ::setup/props) ::db/pool (ig/ref ::db/pool) ::http.client/client (ig/ref ::http.client/client)} @@ -262,7 +262,7 @@ ::oidc/routes {::http.client/client (ig/ref ::http.client/client) ::db/pool (ig/ref ::db/pool) - ::props (ig/ref ::setup/props) + ::setup/props (ig/ref ::setup/props) ::oidc/providers {:google (ig/ref ::oidc.providers/google) :github (ig/ref ::oidc.providers/github) :gitlab (ig/ref ::oidc.providers/gitlab) @@ -274,7 +274,7 @@ ::db/pool (ig/ref ::db/pool) ::rpc/routes (ig/ref ::rpc/routes) ::rpc.doc/routes (ig/ref ::rpc.doc/routes) - ::props (ig/ref ::setup/props) + ::setup/props (ig/ref ::setup/props) ::mtx/routes (ig/ref ::mtx/routes) ::oidc/routes (ig/ref ::oidc/routes) ::http.debug/routes (ig/ref ::http.debug/routes) @@ -286,7 +286,7 @@ {::db/pool (ig/ref ::db/pool) ::session/manager (ig/ref ::session/manager) ::sto/storage (ig/ref ::sto/storage) - ::props (ig/ref ::setup/props)} + ::setup/props (ig/ref ::setup/props)} ::http.ws/routes {::db/pool (ig/ref ::db/pool) @@ -322,7 +322,7 @@ ::rpc/climit (ig/ref ::rpc/climit) ::rpc/rlimit (ig/ref ::rpc/rlimit) ::setup/templates (ig/ref ::setup/templates) - ::props (ig/ref ::setup/props)} + ::setup/props (ig/ref ::setup/props)} :app.rpc.doc/routes {:methods (ig/ref :app.rpc/methods)} @@ -331,7 +331,7 @@ {::rpc/methods (ig/ref :app.rpc/methods) ::db/pool (ig/ref ::db/pool) ::session/manager (ig/ref ::session/manager) - ::props (ig/ref ::setup/props)} + ::setup/props (ig/ref ::setup/props)} ::wrk/registry {::mtx/metrics (ig/ref ::mtx/metrics) @@ -388,7 +388,7 @@ :app.tasks.telemetry/handler {::db/pool (ig/ref ::db/pool) ::http.client/client (ig/ref ::http.client/client) - ::props (ig/ref ::setup/props)} + ::setup/props (ig/ref ::setup/props)} [::srepl/urepl ::srepl/server] {::srepl/port (cf/get :urepl-port 6062) @@ -402,7 +402,7 @@ ::setup/props {::db/pool (ig/ref ::db/pool) - ::key (cf/get :secret-key) + ::setup/key (cf/get :secret-key) ;; NOTE: this dependency is only necessary for proper initialization ordering, props ;; module requires the migrations to run before initialize. @@ -412,7 +412,7 @@ {} ::audit.tasks/archive - {::props (ig/ref ::setup/props) + {::setup/props (ig/ref ::setup/props) ::db/pool (ig/ref ::db/pool) ::http.client/client (ig/ref ::http.client/client)} diff --git a/backend/src/app/rpc.clj b/backend/src/app/rpc.clj index 8ae7a38d6..ea49b6b70 100644 --- a/backend/src/app/rpc.clj +++ b/backend/src/app/rpc.clj @@ -27,6 +27,7 @@ [app.rpc.helpers :as rph] [app.rpc.retry :as retry] [app.rpc.rlimit :as rlimit] + [app.setup :as-alias setup] [app.storage :as-alias sto] [app.util.services :as sv] [app.util.time :as dt] @@ -248,7 +249,7 @@ ::ldap/provider ::sto/storage ::mtx/metrics - ::main/props] + ::setup/props] :opt [::climit ::rlimit])) @@ -265,7 +266,7 @@ (defmethod ig/pre-init-spec ::routes [_] (s/keys :req [::methods ::db/pool - ::main/props + ::setup/props ::session/manager])) (defmethod ig/init-key ::routes diff --git a/backend/src/app/rpc/commands/access_token.clj b/backend/src/app/rpc/commands/access_token.clj index dd10f3371..06a6e516c 100644 --- a/backend/src/app/rpc/commands/access_token.clj +++ b/backend/src/app/rpc/commands/access_token.clj @@ -13,6 +13,7 @@ [app.rpc :as-alias rpc] [app.rpc.doc :as-alias doc] [app.rpc.quotes :as quotes] + [app.setup :as-alias setup] [app.tokens :as tokens] [app.util.services :as sv] [app.util.time :as dt] @@ -23,7 +24,7 @@ (dissoc row :perms)) (defn create-access-token - [{:keys [::db/conn ::main/props]} profile-id name expiration] + [{:keys [::db/conn ::setup/props]} profile-id name expiration] (let [created-at (dt/now) token-id (uuid/next) token (tokens/generate props {:iss "access-token" @@ -47,7 +48,7 @@ [{:keys [::db/pool] :as system} profile-id name expiration] (db/with-atomic [conn pool] (let [props (:app.setup/props system)] - (create-access-token {::db/conn conn ::main/props props} + (create-access-token {::db/conn conn ::setup/props props} profile-id name expiration)))) diff --git a/backend/src/app/rpc/commands/auth.clj b/backend/src/app/rpc/commands/auth.clj index 8e9671e59..e87979007 100644 --- a/backend/src/app/rpc/commands/auth.clj +++ b/backend/src/app/rpc/commands/auth.clj @@ -26,6 +26,7 @@ [app.rpc.commands.teams :as teams] [app.rpc.doc :as-alias doc] [app.rpc.helpers :as rph] + [app.setup :as-alias setup] [app.tokens :as tokens] [app.util.services :as sv] [app.util.time :as dt] @@ -88,7 +89,7 @@ (profile/strip-private-attrs)) invitation (when-let [token (:invitation-token params)] - (tokens/verify (::main/props cfg) {:token token :iss :team-invitation})) + (tokens/verify (::setup/props cfg) {:token token :iss :team-invitation})) ;; If invitation member-id does not matches the profile-id, we just proceed to ignore the ;; invitation because invitations matches exactly; and user can't login with other email and @@ -133,7 +134,7 @@ (defn recover-profile [{:keys [::db/pool] :as cfg} {:keys [token password]}] (letfn [(validate-token [token] - (let [tdata (tokens/verify (::main/props cfg) {:token token :iss :password-recovery})] + (let [tdata (tokens/verify (::setup/props cfg) {:token token :iss :password-recovery})] (:profile-id tdata))) (update-password [conn profile-id] @@ -170,7 +171,7 @@ :code :registration-disabled))) (when (contains? params :invitation-token) - (let [invitation (tokens/verify (::main/props cfg) {:token (:invitation-token params) :iss :team-invitation})] + (let [invitation (tokens/verify (::setup/props cfg) {:token (:invitation-token params) :iss :team-invitation})] (when-not (= (:email params) (:member-email invitation)) (ex/raise :type :restriction :code :email-does-not-match-invitation @@ -233,7 +234,7 @@ params (d/without-nils params) - token (tokens/generate (::main/props cfg) params)] + token (tokens/generate (::setup/props cfg) params)] (with-meta {:token token} {::audit/profile-id uuid/zero}))) @@ -340,7 +341,7 @@ (defn register-profile [{:keys [::db/conn] :as cfg} {:keys [token fullname] :as params}] - (let [claims (tokens/verify (::main/props cfg) {:token token :iss :prepared-register}) + (let [claims (tokens/verify (::setup/props cfg) {:token token :iss :prepared-register}) params (-> claims (into params) (assoc :fullname fullname)) @@ -357,7 +358,7 @@ (create-profile-rels! conn)))) invitation (when-let [token (:invitation-token params)] - (tokens/verify (::main/props cfg) {:token token :iss :team-invitation}))] + (tokens/verify (::setup/props cfg) {:token token :iss :team-invitation}))] ;; If profile is filled in claims, means it tries to register ;; again, so we proceed to update the modified-at attr @@ -377,7 +378,7 @@ ;; email. (and (some? invitation) (= (:email profile) (:member-email invitation))) (let [claims (assoc invitation :member-id (:id profile)) - token (tokens/generate (::main/props cfg) claims) + token (tokens/generate (::setup/props cfg) claims) resp {:invitation-token token}] (-> resp (rph/with-transform (session/create-fn cfg (:id profile))) @@ -404,7 +405,7 @@ ;; In all other cases, send a verification email. :else (do - (send-email-verification! conn (::main/props cfg) profile) + (send-email-verification! conn (::setup/props cfg) profile) (rph/with-meta profile {::audit/replace-props (audit/profile->props profile) ::audit/profile-id (:id profile)}))))) @@ -429,14 +430,14 @@ (defn request-profile-recovery [{:keys [::db/pool] :as cfg} {:keys [email] :as params}] (letfn [(create-recovery-token [{:keys [id] :as profile}] - (let [token (tokens/generate (::main/props cfg) + (let [token (tokens/generate (::setup/props cfg) {:iss :password-recovery :exp (dt/in-future "15m") :profile-id id})] (assoc profile :token token))) (send-email-notification [conn profile] - (let [ptoken (tokens/generate (::main/props cfg) + (let [ptoken (tokens/generate (::setup/props cfg) {:iss :profile-identity :profile-id (:id profile) :exp (dt/in-future {:days 30})})] diff --git a/backend/src/app/rpc/commands/ldap.clj b/backend/src/app/rpc/commands/ldap.clj index bb86aec90..780f0e100 100644 --- a/backend/src/app/rpc/commands/ldap.clj +++ b/backend/src/app/rpc/commands/ldap.clj @@ -18,6 +18,7 @@ [app.rpc.commands.profile :as profile] [app.rpc.doc :as-alias doc] [app.rpc.helpers :as rph] + [app.setup :as-alias setup] [app.tokens :as tokens] [app.util.services :as sv] [clojure.spec.alpha :as s])) @@ -40,7 +41,7 @@ {::rpc/auth false ::doc/added "1.15" ::doc/module :auth} - [{:keys [::main/props ::ldap/provider] :as cfg} params] + [{:keys [::setup/props ::ldap/provider] :as cfg} params] (when-not provider (ex/raise :type :restriction :code :ldap-not-initialized diff --git a/backend/src/app/rpc/commands/profile.clj b/backend/src/app/rpc/commands/profile.clj index 6ef2ef90d..ccb6a8b2e 100644 --- a/backend/src/app/rpc/commands/profile.clj +++ b/backend/src/app/rpc/commands/profile.clj @@ -23,6 +23,7 @@ [app.rpc.climit :as climit] [app.rpc.doc :as-alias doc] [app.rpc.helpers :as rph] + [app.setup :as-alias setup] [app.storage :as sto] [app.tokens :as tokens] [app.util.services :as sv] @@ -296,12 +297,12 @@ (defn- request-email-change! [{:keys [::conn] :as cfg} {:keys [profile email] :as params}] - (let [token (tokens/generate (::main/props cfg) + (let [token (tokens/generate (::setup/props cfg) {:iss :change-email :exp (dt/in-future "15m") :profile-id (:id profile) :email email}) - ptoken (tokens/generate (::main/props cfg) + ptoken (tokens/generate (::setup/props cfg) {:iss :profile-identity :profile-id (:id profile) :exp (dt/in-future {:days 30})})] diff --git a/backend/src/app/rpc/commands/teams.clj b/backend/src/app/rpc/commands/teams.clj index 4b5f07700..f62f8bc6a 100644 --- a/backend/src/app/rpc/commands/teams.clj +++ b/backend/src/app/rpc/commands/teams.clj @@ -26,6 +26,7 @@ [app.rpc.helpers :as rph] [app.rpc.permissions :as perms] [app.rpc.quotes :as quotes] + [app.setup :as-alias setup] [app.storage :as sto] [app.tokens :as tokens] [app.util.services :as sv] @@ -691,7 +692,7 @@ (defn- create-invitation-token [cfg {:keys [profile-id valid-until team-id member-id member-email role]}] - (tokens/generate (::main/props cfg) + (tokens/generate (::setup/props cfg) {:iss :team-invitation :exp valid-until :profile-id profile-id @@ -702,7 +703,7 @@ (defn- create-profile-identity-token [cfg profile] - (tokens/generate (::main/props cfg) + (tokens/generate (::setup/props cfg) {:iss :profile-identity :profile-id (:id profile) :exp (dt/in-future {:days 30})})) diff --git a/backend/src/app/rpc/commands/verify_token.clj b/backend/src/app/rpc/commands/verify_token.clj index 49c76c110..e072c90d6 100644 --- a/backend/src/app/rpc/commands/verify_token.clj +++ b/backend/src/app/rpc/commands/verify_token.clj @@ -18,6 +18,7 @@ [app.rpc.doc :as-alias doc] [app.rpc.helpers :as rph] [app.rpc.quotes :as quotes] + [app.setup :as-alias setup] [app.tokens :as tokens] [app.tokens.spec.team-invitation :as-alias spec.team-invitation] [app.util.services :as sv] @@ -38,7 +39,7 @@ ::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}) + (let [claims (tokens/verify (::setup/props cfg) {:token token}) cfg (assoc cfg :conn conn)] (process-token cfg params claims)))) diff --git a/backend/src/app/setup.clj b/backend/src/app/setup.clj index 8e889e2b4..d187f3e5f 100644 --- a/backend/src/app/setup.clj +++ b/backend/src/app/setup.clj @@ -50,16 +50,15 @@ :cause cause)))) instance-id))) -(s/def ::main/key ::us/string) -(s/def ::main/props - (s/map-of ::us/keyword some?)) +(s/def ::key ::us/string) +(s/def ::props (s/map-of ::us/keyword some?)) (defmethod ig/pre-init-spec ::props [_] (s/keys :req [::db/pool] - :opt [::main/key])) + :opt [::key])) (defmethod ig/init-key ::props - [_ {:keys [::db/pool ::main/key] :as cfg}] + [_ {:keys [::db/pool ::key] :as cfg}] (db/with-atomic [conn pool] (db/xact-lock! conn 0) (when-not key diff --git a/backend/src/app/tasks/telemetry.clj b/backend/src/app/tasks/telemetry.clj index d040a08f9..43c0b26f9 100644 --- a/backend/src/app/tasks/telemetry.clj +++ b/backend/src/app/tasks/telemetry.clj @@ -15,6 +15,7 @@ [app.db :as db] [app.http.client :as http] [app.main :as-alias main] + [app.setup :as-alias setup] [app.util.json :as json] [clojure.spec.alpha :as s] [integrant.core :as ig] @@ -32,10 +33,10 @@ (defmethod ig/pre-init-spec ::handler [_] (s/keys :req [::http/client ::db/pool - ::main/props])) + ::setup/props])) (defmethod ig/init-key ::handler - [_ {:keys [::db/pool ::main/props] :as cfg}] + [_ {:keys [::db/pool ::setup/props] :as cfg}] (fn [{:keys [send? enabled?] :or {send? true enabled? false}}] (let [subs {:newsletter-updates (get-subscriptions-newsletter-updates pool) :newsletter-news (get-subscriptions-newsletter-news pool)} diff --git a/backend/test/backend_tests/bounce_handling_test.clj b/backend/test/backend_tests/bounce_handling_test.clj index 61a322084..13774e042 100644 --- a/backend/test/backend_tests/bounce_handling_test.clj +++ b/backend/test/backend_tests/bounce_handling_test.clj @@ -102,7 +102,7 @@ (t/deftest test-parse-bounce-report (let [profile (th/create-profile* 1) props (:app.setup/props th/*system*) - cfg {:app.main/props props} + cfg {:app.setup/props props} report (bounce-report {:token (tokens/generate props {:iss :profile-identity :profile-id (:id profile)})}) @@ -118,7 +118,7 @@ (t/deftest test-parse-complaint-report (let [profile (th/create-profile* 1) props (:app.setup/props th/*system*) - cfg {:app.main/props props} + cfg {:app.setup/props props} report (complaint-report {:token (tokens/generate props {:iss :profile-identity :profile-id (:id profile)})}) @@ -132,7 +132,7 @@ (t/deftest test-parse-complaint-report-without-token (let [props (:app.setup/props th/*system*) - cfg {:app.main/props props} + cfg {:app.setup/props props} report (complaint-report {:token ""}) result (#'awsns/parse-notification cfg report)] (t/is (= "complaint" (:type result))) @@ -145,7 +145,7 @@ (let [profile (th/create-profile* 1) props (:app.setup/props th/*system*) pool (:app.db/pool th/*system*) - cfg {:app.main/props props :app.db/pool pool} + cfg {:app.setup/props props :app.db/pool pool} report (bounce-report {:token (tokens/generate props {:iss :profile-identity :profile-id (:id profile)})}) @@ -172,7 +172,7 @@ (let [profile (th/create-profile* 1) props (:app.setup/props th/*system*) pool (:app.db/pool th/*system*) - cfg {:app.main/props props + cfg {:app.setup/props props :app.db/pool pool} report (complaint-report {:token (tokens/generate props {:iss :profile-identity @@ -202,7 +202,7 @@ (let [profile (th/create-profile* 1) props (:app.setup/props th/*system*) pool (:app.db/pool th/*system*) - cfg {:app.main/props props :app.db/pool pool} + cfg {:app.setup/props props :app.db/pool pool} report (bounce-report {:email (:email profile) :token (tokens/generate props {:iss :profile-identity @@ -224,7 +224,7 @@ (let [profile (th/create-profile* 1) props (:app.setup/props th/*system*) pool (:app.db/pool th/*system*) - cfg {:app.main/props props :app.db/pool pool} + cfg {:app.setup/props props :app.db/pool pool} report (complaint-report {:email (:email profile) :token (tokens/generate props {:iss :profile-identity From 1a12e630274c3c352712036a06f448c6528e8eb8 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 14 Mar 2024 12:53:26 +0100 Subject: [PATCH 2/2] :recycle: Simplify audit events code --- frontend/deps.edn | 4 +- frontend/src/app/main/data/comments.cljs | 124 +++++++++----- frontend/src/app/main/data/dashboard.cljs | 73 ++++++--- frontend/src/app/main/data/events.cljs | 152 ++++-------------- frontend/src/app/main/data/fonts.cljs | 37 ++++- frontend/src/app/main/data/modal.cljs | 9 +- frontend/src/app/main/data/users.cljs | 25 ++- frontend/src/app/main/data/workspace.cljs | 7 +- .../src/app/main/data/workspace/comments.cljs | 4 +- .../src/app/main/data/workspace/guides.cljs | 20 ++- .../src/app/main/data/workspace/layout.cljs | 4 +- .../app/main/data/workspace/libraries.cljs | 56 +++++-- .../app/main/data/workspace/selection.cljs | 4 + .../src/app/main/ui/dashboard/projects.cljs | 20 +-- frontend/src/app/util/router.cljs | 11 +- 15 files changed, 320 insertions(+), 230 deletions(-) diff --git a/frontend/deps.edn b/frontend/deps.edn index f4a152eae..3cd46d85a 100644 --- a/frontend/deps.edn +++ b/frontend/deps.edn @@ -9,8 +9,8 @@ funcool/okulary {:mvn/version "2022.04.11-16"} funcool/potok2 - {:git/tag "v2.0" - :git/sha "2bb377b" + {:git/tag "v2.1" + :git/sha "84c97b9" :git/url "https://github.com/funcool/potok.git"} funcool/beicon2 diff --git a/frontend/src/app/main/data/comments.cljs b/frontend/src/app/main/data/comments.cljs index 5762229d4..981f78336 100644 --- a/frontend/src/app/main/data/comments.cljs +++ b/frontend/src/app/main/data/comments.cljs @@ -12,6 +12,7 @@ [app.common.schema :as sm] [app.common.types.shape-tree :as ctst] [app.common.uuid :as uuid] + [app.main.data.events :as ev] [app.main.data.workspace.state-helpers :as wsh] [app.main.repo :as rp] [beicon.v2.core :as rx] @@ -61,13 +62,23 @@ (ptk/reify ::created-thread-on-workspace ptk/UpdateEvent (update [_ state] - (-> state - (update :comment-threads assoc id (dissoc thread :comment)) - (update-in [:workspace-data :pages-index page-id :options :comment-threads-position] assoc id (select-keys thread [:position :frame-id])) - (update :comments-local assoc :open id) - (update :comments-local dissoc :draft) - (update :workspace-drawing dissoc :comment) - (update-in [:comments id] assoc (:id comment) comment))))) + (let [position (select-keys thread [:position :frame-id])] + (-> state + (update :comment-threads assoc id (dissoc thread :comment)) + (update-in [:workspace-data :pages-index page-id :options :comment-threads-position] assoc id position) + (update :comments-local assoc :open id) + (update :comments-local dissoc :draft) + (update :workspace-drawing dissoc :comment) + (update-in [:comments id] assoc (:id comment) comment)))) + + ptk/WatchEvent + (watch [_ _ _] + (rx/of (ptk/data-event ::ev/event + {::ev/name "create-comment-thread" + ::ev/origin "workspace" + :id id + :content-size (count (:content comment))}))))) + (def ^:private @@ -81,8 +92,7 @@ (defn create-thread-on-workspace [params] - (dm/assert! - (sm/check! schema:create-thread-on-workspace params)) + (dm/assert! (sm/check! schema:create-thread-on-workspace params)) (ptk/reify ::create-thread-on-workspace ptk/WatchEvent @@ -105,13 +115,22 @@ (ptk/reify ::created-thread-on-viewer ptk/UpdateEvent (update [_ state] - (-> state - (update :comment-threads assoc id (dissoc thread :comment)) - (update-in [:viewer :pages page-id :options :comment-threads-position] assoc id (select-keys thread [:position :frame-id])) - (update :comments-local assoc :open id) - (update :comments-local dissoc :draft) - (update :workspace-drawing dissoc :comment) - (update-in [:comments id] assoc (:id comment) comment))))) + (let [position (select-keys thread [:position :frame-id])] + (-> state + (update :comment-threads assoc id (dissoc thread :comment)) + (update-in [:viewer :pages page-id :options :comment-threads-position] assoc id position) + (update :comments-local assoc :open id) + (update :comments-local dissoc :draft) + (update :workspace-drawing dissoc :comment) + (update-in [:comments id] assoc (:id comment) comment)))) + + ptk/WatchEvent + (watch [_ _ _] + (rx/of (ptk/data-event ::ev/event + {::ev/name "create-comment-thread" + ::ev/origin "viewer" + :id id + :content-size (count (:content comment))}))))) (def ^:private schema:create-thread-on-viewer @@ -191,21 +210,27 @@ "expected valid content" (string? content)) - (letfn [(created [comment state] - (update-in state [:comments (:id thread)] assoc (:id comment) comment))] - (ptk/reify ::create-comment - ptk/WatchEvent - (watch [_ state _] - (let [share-id (-> state :viewer-local :share-id)] - (rx/concat - (->> (rp/cmd! :create-comment {:thread-id (:id thread) :content content :share-id share-id}) - (rx/map #(partial created %)) - (rx/catch (fn [{:keys [type code] :as cause}] - (if (and (= type :restriction) - (= code :max-quote-reached)) - (rx/throw cause) - (rx/throw {:type :comment-error}))))) - (rx/of (refresh-comment-thread thread)))))))) + (ptk/reify ::create-comment + ev/Event + (-data [_] + {:thread-id (:id thread) + :file-id (:file-id thread) + :content-size (count content)}) + + ptk/WatchEvent + (watch [_ state _] + (let [share-id (-> state :viewer-local :share-id) + created (fn [comment state] + (update-in state [:comments (:id thread)] assoc (:id comment) comment))] + (rx/concat + (->> (rp/cmd! :create-comment {:thread-id (:id thread) :content content :share-id share-id}) + (rx/map (fn [comment] (partial created comment))) + (rx/catch (fn [{:keys [type code] :as cause}] + (if (and (= type :restriction) + (= code :max-quote-reached)) + (rx/throw cause) + (rx/throw {:type :comment-error}))))) + (rx/of (refresh-comment-thread thread))))))) (defn update-comment [{:keys [id content thread-id] :as comment}] @@ -214,6 +239,12 @@ (check-comment! comment)) (ptk/reify ::update-comment + ev/Event + (-data [_] + {:thread-id thread-id + :id id + :content-size (count content)}) + ptk/UpdateEvent (update [_ state] (d/update-in-when state [:comments thread-id id] assoc :content content)) @@ -241,9 +272,14 @@ ptk/WatchEvent (watch [_ _ _] - (->> (rp/cmd! :delete-comment-thread {:id id}) - (rx/catch #(rx/throw {:type :comment-error})) - (rx/ignore))))) + (rx/concat + (->> (rp/cmd! :delete-comment-thread {:id id}) + (rx/catch #(rx/throw {:type :comment-error})) + (rx/ignore)) + (rx/of (ptk/data-event ::ev/event + {::ev/name "delete-comment-thread" + ::ev/origin "workspace" + :id id})))))) (defn delete-comment-thread-on-viewer [{:keys [id] :as thread}] @@ -262,16 +298,24 @@ ptk/WatchEvent (watch [_ state _] (let [share-id (-> state :viewer-local :share-id)] - (->> (rp/cmd! :delete-comment-thread {:id id :share-id share-id}) - (rx/catch #(rx/throw {:type :comment-error})) - (rx/ignore)))))) - + (rx/concat + (->> (rp/cmd! :delete-comment-thread {:id id :share-id share-id}) + (rx/catch #(rx/throw {:type :comment-error})) + (rx/ignore)) + (rx/of (ptk/data-event ::ev/event + {::ev/name "delete-comment-thread" + ::ev/origin "viewer" + :id id}))))))) (defn delete-comment [{:keys [id thread-id] :as comment}] (dm/assert! "expected valid comment" (check-comment! comment)) (ptk/reify ::delete-comment + ev/Event + (-data [_] + {:thread-id thread-id}) + ptk/UpdateEvent (update [_ state] (-> state @@ -375,6 +419,10 @@ "expected valid comment thread" (check-comment-thread! thread)) (ptk/reify ::open-comment-thread + ev/Event + (-data [_] + {:thread-id id}) + ptk/UpdateEvent (update [_ state] (-> state diff --git a/frontend/src/app/main/data/dashboard.cljs b/frontend/src/app/main/data/dashboard.cljs index b75fddfc9..bde91339d 100644 --- a/frontend/src/app/main/data/dashboard.cljs +++ b/frontend/src/app/main/data/dashboard.cljs @@ -469,7 +469,11 @@ (rx/map prepare) (rx/mapcat #(rp/cmd! :update-team-photo %)) (rx/tap on-success) - (rx/map du/fetch-teams) + (rx/mapcat (fn [_] + (rx/of (du/fetch-teams) + (ptk/data-event ::ev/event + {::ev/name "update-team-photo" + :team-id team-id})))) (rx/catch on-error)))))) (defn update-team-member-role @@ -484,7 +488,12 @@ (->> (rp/cmd! :update-team-member-role params) (rx/mapcat (fn [_] (rx/of (fetch-team-members team-id) - (du/fetch-teams))))))))) + (du/fetch-teams) + (ptk/data-event ::ev/event + {::ev/name "update-team-member-role" + :team-id team-id + :role role + :member-id member-id}))))))))) (defn delete-team-member [{:keys [member-id] :as params}] @@ -497,7 +506,11 @@ (->> (rp/cmd! :delete-team-member params) (rx/mapcat (fn [_] (rx/of (fetch-team-members team-id) - (du/fetch-teams))))))))) + (du/fetch-teams) + (ptk/data-event ::ev/event + {::ev/name "delete-team-member" + :team-id team-id + :member-id member-id}))))))))) (defn leave-team [{:keys [reassign-to] :as params}] @@ -516,6 +529,11 @@ (assoc :reassign-to reassign-to))] (->> (rp/cmd! :leave-team params) (rx/tap #(tm/schedule on-success)) + (rx/map (fn [_] + (ptk/data-event ::ev/event + {::ev/name "leave-team" + :reassign-to reassign-to + :team-id team-id}))) (rx/catch on-error)))))) (defn invite-team-members @@ -528,8 +546,11 @@ (sm/check-set-of-emails! emails)) (ptk/reify ::invite-team-members - IDeref - (-deref [_] {:role role :team-id team-id :resend? resend?}) + ev/Event + (-data [_] + {:role role + :team-id team-id + :resend resend?}) ptk/WatchEvent (watch [_ _ _] @@ -727,6 +748,11 @@ [{:keys [id name] :as params}] (dm/assert! (uuid? id)) (ptk/reify ::duplicate-project + ev/Event + (-data [_] + {:project-id id + :name name}) + ptk/WatchEvent (watch [_ _ _] (let [{:keys [on-success on-error] @@ -744,10 +770,12 @@ [{:keys [id team-id] :as params}] (dm/assert! (uuid? id)) (dm/assert! (uuid? team-id)) + (ptk/reify ::move-project - IDeref - (-deref [_] - {:id id :team-id team-id}) + ev/Event + (-data [_] + {:id id + :team-id team-id}) ptk/WatchEvent (watch [_ _ _] @@ -834,9 +862,11 @@ (defn rename-file [{:keys [id name] :as params}] (ptk/reify ::rename-file - IDeref - (-deref [_] - {::ev/origin "dashboard" :id id :name name}) + ev/Event + (-data [_] + {::ev/origin "dashboard" + :id id + :name name}) ptk/UpdateEvent (update [_ state] @@ -856,9 +886,11 @@ (defn set-file-shared [{:keys [id is-shared] :as params}] (ptk/reify ::set-file-shared - IDeref - (-deref [_] - {::ev/origin "dashboard" :id id :shared is-shared}) + ev/Event + (-data [_] + {::ev/origin "dashboard" + :id id + :shared is-shared}) ptk/UpdateEvent (update [_ state] @@ -912,9 +944,8 @@ [{:keys [project-id] :as params}] (dm/assert! (uuid? project-id)) (ptk/reify ::create-file - - IDeref - (-deref [_] {:project-id project-id}) + ev/Event + (-data [_] {:project-id project-id}) ptk/WatchEvent (watch [it state _] @@ -967,8 +998,8 @@ (sm/check-set-of-uuid! ids)) (ptk/reify ::move-files - IDeref - (-deref [_] + ev/Event + (-data [_] {:num-files (count ids) :project-id project-id}) @@ -998,8 +1029,8 @@ [{:keys [template-id project-id] :as params}] (dm/assert! (uuid? project-id)) (ptk/reify ::clone-template - IDeref - (-deref [_] + ev/Event + (-data [_] {:template-id template-id :project-id project-id}) diff --git a/frontend/src/app/main/data/events.cljs b/frontend/src/app/main/data/events.cljs index f80883672..ec217339c 100644 --- a/frontend/src/app/main/data/events.cljs +++ b/frontend/src/app/main/data/events.cljs @@ -75,71 +75,23 @@ ;; --- EVENT TRANSLATION -(derive :app.main.data.comments/create-comment ::generic-action) -(derive :app.main.data.comments/create-comment-thread ::generic-action) -(derive :app.main.data.comments/delete-comment ::generic-action) -(derive :app.main.data.comments/delete-comment-thread ::generic-action) -(derive :app.main.data.comments/open-comment-thread ::generic-action) -(derive :app.main.data.comments/update-comment ::generic-action) -(derive :app.main.data.comments/update-comment-thread ::generic-action) -(derive :app.main.data.comments/update-comment-thread-status ::generic-action) -(derive :app.main.data.dashboard/delete-team-member ::generic-action) -(derive :app.main.data.dashboard/duplicate-project ::generic-action) -(derive :app.main.data.dashboard/create-file ::generic-action) -(derive :app.main.data.dashboard/invite-team-members ::generic-action) -(derive :app.main.data.dashboard/leave-team ::generic-action) -(derive :app.main.data.dashboard/move-files ::generic-action) -(derive :app.main.data.dashboard/move-project ::generic-action) -(derive :app.main.data.dashboard/rename-file ::generic-action) -(derive :app.main.data.dashboard/set-file-shared ::generic-action) -(derive :app.main.data.dashboard/update-team-member-role ::generic-action) -(derive :app.main.data.dashboard/update-team-photo ::generic-action) -(derive :app.main.data.dashboard/clone-template ::generic-action) -(derive :app.main.data.fonts/add-font ::generic-action) -(derive :app.main.data.fonts/delete-font ::generic-action) -(derive :app.main.data.fonts/delete-font-variant ::generic-action) -(derive :app.main.data.modal/show-modal ::generic-action) -(derive :app.main.data.users/logout ::generic-action) -(derive :app.main.data.users/request-email-change ::generic-action) -(derive :app.main.data.users/update-password ::generic-action) -(derive :app.main.data.users/update-photo ::generic-action) -(derive :app.main.data.workspace.comments/open-comment-thread ::generic-action) -(derive :app.main.data.workspace.guides/update-guides ::generic-action) -(derive :app.main.data.workspace.libraries/add-color ::generic-action) -(derive :app.main.data.workspace.libraries/add-media ::generic-action) -(derive :app.main.data.workspace.libraries/add-typography ::generic-action) -(derive :app.main.data.workspace.libraries/delete-color ::generic-action) -(derive :app.main.data.workspace.libraries/delete-media ::generic-action) -(derive :app.main.data.workspace.libraries/delete-typography ::generic-action) -(derive :app.main.data.workspace.persistence/attach-library ::generic-action) -(derive :app.main.data.workspace.persistence/detach-library ::generic-action) -(derive :app.main.data.workspace.persistence/set-file-shard ::generic-action) -(derive :app.main.data.workspace.selection/toggle-focus-mode ::generic-action) -(derive :app.main.data.workspace/create-page ::generic-action) -(derive :app.main.data.workspace/set-workspace-layout ::generic-action) -(derive :app.main.data.workspace/toggle-layout-flag ::generic-action) - (defprotocol Event (-data [_] "Get event data")) (defn- simplify-props "Removes complex data types from props." [data] - (into {} - (comp - (remove (fn [[_ v]] (nil? v))) - (map (fn [[k v :as kv]] - (cond - (map? v) [k :placeholder/map] - (vector? v) [k :placeholder/vec] - (set? v) [k :placeholder/set] - (coll? v) [k :placeholder/coll] - (fn? v) [k :placeholder/fn] - :else kv)))) - data)) - - -(defmulti process-event-by-type ptk/type) + (reduce-kv (fn [data k v] + (cond + (map? v) (assoc data k :placeholder/map) + (vector? v) (assoc data k :placeholder/vec) + (set? v) (assoc data k :placeholder/set) + (coll? v) (assoc data k :placeholder/coll) + (fn? v) (assoc data k :placeholder/fn) + (nil? v) (dissoc data k) + :else data)) + data + data)) (defn- process-event-by-proto [event] @@ -158,72 +110,30 @@ :context context :props props})) +(defn- process-data-event + [event] + (let [data (deref event) + name (::name data)] + + (when (string? name) + (let [type (::type data "action") + context (-> (::context data) + (assoc :event-origin (::origin data)) + (d/without-nils)) + props (-> data d/without-qualified simplify-props)] + {:type type + :name name + :context context + :props props})))) + (defn- process-event [event] - (if (satisfies? Event event) + (cond + (satisfies? Event event) (process-event-by-proto event) - (process-event-by-type event))) -(defmethod process-event-by-type :default [_] nil) - -(defmethod process-event-by-type ::event - [event] - (let [data (deref event) - context (-> (::context data) - (assoc :event-origin (::origin data)) - (d/without-nils)) - props (-> data d/without-qualified simplify-props)] - - {:type (::type data "action") - :name (::name data "unnamed") - :context context - :props props})) - -(defmethod process-event-by-type ::generic-action - [event] - (let [type (ptk/type event) - data (if (satisfies? IDeref event) - (deref event) - {}) - data (d/deep-merge data (meta event))] - - {:type "action" - :name (or (::name data) (name type)) - :props (-> (d/without-qualified data) - (simplify-props)) - :context (d/without-nils - {:event-origin (::origin data) - :event-namespace (namespace type) - :event-symbol (name type)})})) - -(defmethod process-event-by-type :app.util.router/navigated - [event] - (let [match (deref event) - route (get-in match [:data :name]) - props {:route (name route) - :team-id (get-in match [:path-params :team-id]) - :file-id (get-in match [:path-params :file-id]) - :project-id (get-in match [:path-params :project-id])}] - {:name "navigate" - :type "action" - :props (simplify-props props)})) - -(defmethod process-event-by-type :app.main.data.users/logged-in - [event] - (let [data (deref event) - mdata (meta data) - props {:signin-source (::source mdata) - :email (:email data) - :auth-backend (:auth-backend data) - :fullname (:fullname data) - :is-muted (:is-muted data) - :default-team-id (str (:default-team-id data)) - :default-project-id (str (:default-project-id data))}] - - {:name "signin" - :type "identify" - :profile-id (:id data) - :props (simplify-props props)})) + (ptk/data-event? event) + (process-data-event event))) ;; --- MAIN LOOP diff --git a/frontend/src/app/main/data/fonts.cljs b/frontend/src/app/main/data/fonts.cljs index bb8fe193f..b7150b033 100644 --- a/frontend/src/app/main/data/fonts.cljs +++ b/frontend/src/app/main/data/fonts.cljs @@ -12,6 +12,7 @@ [app.common.logging :as log] [app.common.media :as cm] [app.common.uuid :as uuid] + [app.main.data.events :as ev] [app.main.data.messages :as msg] [app.main.fonts :as fonts] [app.main.repo :as rp] @@ -236,12 +237,19 @@ (defn add-font [font] (ptk/reify ::add-font - IDeref - (-deref [_] (select-keys font [:font-family :font-style :font-weight])) - ptk/UpdateEvent (update [_ state] - (update state :dashboard-fonts assoc (:id font) font)))) + (update state :dashboard-fonts assoc (:id font) font)) + + ptk/WatchEvent + (watch [_ state _] + (let [team-id (:current-team-id state)] + (rx/of (ptk/data-event ::ev/event {::ev/name "add-font" + :team-id team-id + :font-id (:id font) + :font-family (:font-family font) + :font-style (:font-style font) + :font-weight (:font-weight font)})))))) (defn update-font [{:keys [id name] :as params}] @@ -271,6 +279,10 @@ [font-id] (dm/assert! (uuid? font-id)) (ptk/reify ::delete-font + ev/Event + (-data [_] + {:id font-id}) + ptk/UpdateEvent (update [_ state] (update state :dashboard-fonts @@ -280,8 +292,12 @@ ptk/WatchEvent (watch [_ state _] (let [team-id (:current-team-id state)] - (->> (rp/cmd! :delete-font {:id font-id :team-id team-id}) - (rx/ignore)))))) + (rx/concat + (->> (rp/cmd! :delete-font {:id font-id :team-id team-id}) + (rx/ignore)) + (rx/of (ptk/data-event ::ev/event {::ev/name "delete-font" + :team-id team-id + :font-id font-id}))))))) (defn delete-font-variant [id] @@ -297,8 +313,13 @@ ptk/WatchEvent (watch [_ state _] (let [team-id (:current-team-id state)] - (->> (rp/cmd! :delete-font-variant {:id id :team-id team-id}) - (rx/ignore)))))) + (rx/concat + (->> (rp/cmd! :delete-font-variant {:id id :team-id team-id}) + (rx/ignore)) + (rx/of (ptk/data-event ::ev/event {::ev/name "delete-font-variant" + :id id + :team-id team-id}))))))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Workspace related events diff --git a/frontend/src/app/main/data/modal.cljs b/frontend/src/app/main/data/modal.cljs index 5b5b79524..1055014c2 100644 --- a/frontend/src/app/main/data/modal.cljs +++ b/frontend/src/app/main/data/modal.cljs @@ -8,6 +8,7 @@ (:refer-clojure :exclude [update]) (:require [app.common.uuid :as uuid] + [app.main.data.events :as ev] [app.main.store :as st] [cljs.core :as c] [potok.v2.core :as ptk])) @@ -23,9 +24,11 @@ (show (uuid/next) type props)) ([id type props] (ptk/reify ::show-modal - IDeref - (-deref [_] - (merge (dissoc props :type) {:name type})) + ev/Event + (-data [_] + (-> props + (dissoc :type) + (assoc :name type))) ptk/UpdateEvent (update [_ state] diff --git a/frontend/src/app/main/data/users.cljs b/frontend/src/app/main/data/users.cljs index 64142d327..392c6e055 100644 --- a/frontend/src/app/main/data/users.cljs +++ b/frontend/src/app/main/data/users.cljs @@ -161,8 +161,16 @@ (rt/nav' :dashboard-projects {:team-id team-id}))))] (ptk/reify ::logged-in - IDeref - (-deref [_] profile) + ev/Event + (-data [_] + {::ev/name "signing" + ::ev/type "identify" + :email (:email profile) + :auth-backend (:auth-backend profile) + :fullname (:fullname profile) + :is-muted (:is-muted profile) + :default-team-id (:default-team-id profile) + :default-project-id (:default-project-id profile)}) ptk/WatchEvent (watch [_ _ _] @@ -288,6 +296,9 @@ ([] (logout {})) ([params] (ptk/reify ::logout + ev/Event + (-data [_] {}) + ptk/WatchEvent (watch [_ _ _] (->> (rp/cmd! :logout) @@ -360,6 +371,10 @@ [{:keys [email] :as data}] (dm/assert! ::us/email email) (ptk/reify ::request-email-change + ev/Event + (-data [_] + {:email email}) + ptk/WatchEvent (watch [_ _ _] (let [{:keys [on-error on-success] @@ -395,6 +410,9 @@ (sm/check! schema:update-password data)) (ptk/reify ::update-password + ev/Event + (-data [_] {}) + ptk/WatchEvent (watch [_ _ _] (let [{:keys [on-error on-success] @@ -458,6 +476,9 @@ (di/blob? file)) (ptk/reify ::update-photo + ev/Event + (-data [_] {}) + ptk/WatchEvent (watch [_ _ _] (let [on-success di/notify-finished-loading diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 41fdb90ba..da8ac8eab 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -458,9 +458,10 @@ [{:keys [file-id]}] (let [id (uuid/next)] (ptk/reify ::create-page - IDeref - (-deref [_] - {:id id :file-id file-id}) + ev/Event + (-data [_] + {:id id + :file-id file-id}) ptk/WatchEvent (watch [it state _] diff --git a/frontend/src/app/main/data/workspace/comments.cljs b/frontend/src/app/main/data/workspace/comments.cljs index 3d1457d56..246034878 100644 --- a/frontend/src/app/main/data/workspace/comments.cljs +++ b/frontend/src/app/main/data/workspace/comments.cljs @@ -13,6 +13,7 @@ [app.common.schema :as sm] [app.common.types.shape-tree :as ctst] [app.main.data.comments :as dcm] + [app.main.data.events :as ev] [app.main.data.workspace.changes :as dch] [app.main.data.workspace.common :as dwco] [app.main.data.workspace.drawing :as dwd] @@ -118,7 +119,8 @@ (rx/take 1) (rx/mapcat #(rx/of (center-to-comment-thread thread) (dwd/select-for-drawing :comments) - (dcm/open-thread thread))))))))) + (with-meta (dcm/open-thread thread) + {::ev/origin "workspace"}))))))))) (defn update-comment-thread-position ([thread [new-x new-y]] diff --git a/frontend/src/app/main/data/workspace/guides.cljs b/frontend/src/app/main/data/workspace/guides.cljs index 222921010..2c7c6c2c0 100644 --- a/frontend/src/app/main/data/workspace/guides.cljs +++ b/frontend/src/app/main/data/workspace/guides.cljs @@ -11,23 +11,30 @@ [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] [app.common.types.page :as ctp] + [app.main.data.events :as ev] [app.main.data.workspace.changes :as dch] [app.main.data.workspace.state-helpers :as wsh] [beicon.v2.core :as rx] [potok.v2.core :as ptk])) -(defn make-update-guide [guide] +(defn make-update-guide + [guide] (fn [other] (cond-> other (= (:id other) (:id guide)) (merge guide)))) -(defn update-guides [guide] +(defn update-guides + [guide] (dm/assert! "expected valid guide" (ctp/check-page-guide! guide)) (ptk/reify ::update-guides + ev/Event + (-data [_] + (assoc guide ::ev/name "update-guide")) + ptk/WatchEvent (watch [it state _] (let [page (wsh/lookup-page state) @@ -37,17 +44,20 @@ (pcb/update-page-option :guides assoc (:id guide) guide))] (rx/of (dch/commit-changes changes)))))) -(defn remove-guide [guide] +(defn remove-guide + [guide] (dm/assert! "expected valid guide" (ctp/check-page-guide! guide)) (ptk/reify ::remove-guide + ev/Event + (-data [_] guide) + ptk/UpdateEvent (update [_ state] (let [sdisj (fnil disj #{})] - (-> state - (update-in [:workspace-guides :hover] sdisj (:id guide))))) + (update-in state [:workspace-guides :hover] sdisj (:id guide)))) ptk/WatchEvent (watch [it state _] diff --git a/frontend/src/app/main/data/workspace/layout.cljs b/frontend/src/app/main/data/workspace/layout.cljs index 24cfc6779..750653c2a 100644 --- a/frontend/src/app/main/data/workspace/layout.cljs +++ b/frontend/src/app/main/data/workspace/layout.cljs @@ -82,8 +82,8 @@ (defn toggle-layout-flag [flag & {:keys [force?] :as opts}] (ptk/reify ::toggle-layout-flag - IDeref - (-deref [_] {:name flag}) + ev/Event + (-data [_] {:name flag}) ptk/UpdateEvent (update [_ state] diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index 448997208..9f4867ace 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -108,8 +108,8 @@ (uc/gradient-type->string (get-in color [:gradient :type])))))] (dm/assert! ::ctc/color color) (ptk/reify ::add-color - IDeref - (-deref [_] color) + ev/Event + (-data [_] color) ptk/WatchEvent (watch [it _ _] @@ -185,6 +185,9 @@ [{:keys [id] :as params}] (dm/assert! (uuid? id)) (ptk/reify ::delete-color + ev/Event + (-data [_] {:id id}) + ptk/WatchEvent (watch [it state _] (let [data (get state :workspace-data) @@ -200,6 +203,9 @@ (ctf/check-media-object! media)) (ptk/reify ::add-media + ev/Event + (-data [_] media) + ptk/WatchEvent (watch [it _ _] (let [obj (select-keys media [:id :name :width :height :mtype]) @@ -230,6 +236,9 @@ [{:keys [id] :as params}] (dm/assert! (uuid? id)) (ptk/reify ::delete-media + ev/Event + (-data [_] {:id id}) + ptk/WatchEvent (watch [it state _] (let [data (get state :workspace-data) @@ -247,8 +256,8 @@ (ctt/check-typography! typography)) (ptk/reify ::add-typography - IDeref - (-deref [_] typography) + ev/Event + (-data [_] typography) ptk/WatchEvent (watch [it _ _] @@ -291,6 +300,9 @@ (dm/assert! (uuid? id)) (dm/assert! (string? new-name)) (ptk/reify ::rename-typography + ev/Event + (-data [_] {:id id :name new-name}) + ptk/WatchEvent (watch [it state _] (when (and (some? new-name) (not= "" new-name)) @@ -304,6 +316,9 @@ [id] (dm/assert! (uuid? id)) (ptk/reify ::delete-typography + ev/Event + (-data [_] {:id id}) + ptk/WatchEvent (watch [it state _] (let [data (get state :workspace-data) @@ -316,8 +331,10 @@ "This is the second step of the component creation." [selected components-v2] (ptk/reify ::add-component2 - IDeref - (-deref [_] {:num-shapes (count selected)}) + ev/Event + (-data [_] + {::ev/name "add-component" + :shapes (count selected)}) ptk/WatchEvent (watch [it state _] @@ -369,9 +386,10 @@ selected-objects (map #(get objects %) selected) ;; We don't want to change the structure of component copies can-make-component (every? true? (map #(ctn/valid-shape-for-component? objects %) selected-objects)) - added-components (map - #(add-component2 [%] components-v2) - selected) + added-components (map (fn [id] + (with-meta (add-component2 [id] components-v2) + {:multiple true})) + selected) undo-id (js/Symbol)] (when can-make-component (rx/concat @@ -1266,9 +1284,11 @@ [id is-shared] {:pre [(uuid? id) (boolean? is-shared)]} (ptk/reify ::set-file-shared - IDeref - (-deref [_] - {::ev/origin "workspace" :id id :shared is-shared}) + ev/Event + (-data [_] + {::ev/origin "workspace" + :id id + :shared is-shared}) ptk/UpdateEvent (update [_ state] @@ -1302,6 +1322,12 @@ (defn link-file-to-library [file-id library-id] (ptk/reify ::attach-library + ev/Event + (-data [_] + {::ev/name "attach-library" + :file-id file-id + :library-id library-id}) + ;; NOTE: this event implements UpdateEvent protocol for perform an ;; optimistic update state for make the UI feel more responsive. ptk/UpdateEvent @@ -1331,6 +1357,12 @@ (defn unlink-file-from-library [file-id library-id] (ptk/reify ::detach-library + ev/Event + (-data [_] + {::ev/name "detach-library" + :file-id file-id + :library-id library-id}) + ptk/UpdateEvent (update [_ state] (d/dissoc-in state [:workspace-libraries library-id])) diff --git a/frontend/src/app/main/data/workspace/selection.cljs b/frontend/src/app/main/data/workspace/selection.cljs index 56b4e6800..825cfedab 100644 --- a/frontend/src/app/main/data/workspace/selection.cljs +++ b/frontend/src/app/main/data/workspace/selection.cljs @@ -24,6 +24,7 @@ [app.common.types.shape.interactions :as ctsi] [app.common.types.shape.layout :as ctl] [app.common.uuid :as uuid] + [app.main.data.events :as ev] [app.main.data.modal :as md] [app.main.data.workspace.changes :as dch] [app.main.data.workspace.collapse :as dwc] @@ -791,6 +792,9 @@ (defn toggle-focus-mode [] (ptk/reify ::toggle-focus-mode + ev/Event + (-data [_] {}) + ptk/UpdateEvent (update [_ state] (let [selected (wsh/lookup-selected state)] diff --git a/frontend/src/app/main/ui/dashboard/projects.cljs b/frontend/src/app/main/ui/dashboard/projects.cljs index 931ac0604..fd855f4b1 100644 --- a/frontend/src/app/main/ui/dashboard/projects.cljs +++ b/frontend/src/app/main/ui/dashboard/projects.cljs @@ -385,24 +385,24 @@ (mf/use-fn (fn [] (st/emit! (du/update-profile-props {:team-hero? false}) - (ptk/event ::ev/event {::ev/name "dont-show-team-up-hero" - ::ev/origin "dashboard"})))) + (ptk/data-event ::ev/event {::ev/name "dont-show-team-up-hero" + ::ev/origin "dashboard"})))) close-tutorial (mf/use-fn (fn [] (st/emit! (du/update-profile-props {:viewed-tutorial? true}) - (ptk/event ::ev/event {::ev/name "dont-show" - ::ev/origin "get-started-hero-block" - :type "tutorial" - :section "dashboard"})))) + (ptk/data-event ::ev/event {::ev/name "dont-show-tutorial" + ::ev/origin "get-started-hero" + :type "tutorial" + :section "dashboard"})))) close-walkthrough (mf/use-fn (fn [] (st/emit! (du/update-profile-props {:viewed-walkthrough? true}) - (ptk/event ::ev/event {::ev/name "dont-show" - ::ev/origin "get-started-hero-block" - :type "walkthrough" - :section "dashboard"}))))] + (ptk/data-event ::ev/event {::ev/name "dont-show-walkthrough" + ::ev/origin "get-started-hero" + :type "walkthrough" + :section "dashboard"}))))] (mf/with-effect [team] (let [tname (if (:is-default team) diff --git a/frontend/src/app/util/router.cljs b/frontend/src/app/util/router.cljs index 50a9bb0fd..c4d541cfd 100644 --- a/frontend/src/app/util/router.cljs +++ b/frontend/src/app/util/router.cljs @@ -7,8 +7,10 @@ (ns app.util.router (:refer-clojure :exclude [resolve]) (:require + [app.common.data.macros :as dm] [app.common.uri :as u] [app.config :as cf] + [app.main.data.events :as ev] [app.util.browser-history :as bhistory] [app.util.dom :as dom] [app.util.timers :as ts] @@ -59,8 +61,13 @@ (defn navigated [match] (ptk/reify ::navigated - IDeref - (-deref [_] match) + ev/Event + (-data [_] + (let [route (dm/get-in match [:data :name]) + params (get match :path-params)] + (assoc params + ::ev/name "navigate" + :route (name route)))) ptk/UpdateEvent (update [_ state]