mirror of
https://github.com/penpot/penpot.git
synced 2026-05-13 12:04:06 +00:00
🚧 WIP
This commit is contained in:
parent
d58c1b88a9
commit
a04a6dd34c
@ -31,6 +31,25 @@
|
||||
jakarta.mail.Transport
|
||||
java.util.Properties))
|
||||
|
||||
(defn clean
|
||||
"Clean and normalizes email address string"
|
||||
[email]
|
||||
(let [email (str/lower email)
|
||||
email (if (str/starts-with? email "mailto:")
|
||||
(subs email 7)
|
||||
email)
|
||||
email (if (or (str/starts-with? email "<")
|
||||
(str/ends-with? email ">"))
|
||||
(str/trim email "<>")
|
||||
email)]
|
||||
email))
|
||||
|
||||
(defn get-domain
|
||||
[email]
|
||||
(let [email (clean email)
|
||||
[_ domain] (str/split email "@" 2)]
|
||||
domain))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; EMAIL IMPL
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
[app.common.uuid :as uuid]
|
||||
[app.config :as cf]
|
||||
[app.db :as db]
|
||||
[app.email :as email]
|
||||
[app.http :as-alias http]
|
||||
[app.http.access-token :as-alias actoken]
|
||||
[app.loggers.audit.tasks :as-alias tasks]
|
||||
@ -33,6 +34,23 @@
|
||||
;; HELPERS
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(def profile-props
|
||||
[:id
|
||||
:is-active
|
||||
:is-muted
|
||||
:auth-backend
|
||||
:email
|
||||
:default-team-id
|
||||
:default-project-id
|
||||
:fullname
|
||||
:lang])
|
||||
|
||||
(def reserved-props
|
||||
#{:session-id
|
||||
:password
|
||||
:old-password
|
||||
:token})
|
||||
|
||||
(defn extract-utm-params
|
||||
"Extracts additional data from params and namespace them under
|
||||
`penpot` ns."
|
||||
@ -47,17 +65,6 @@
|
||||
(assoc (->> sk str/kebab (keyword "penpot")) v))))]
|
||||
(reduce-kv process-param {} params)))
|
||||
|
||||
(def profile-props
|
||||
[:id
|
||||
:is-active
|
||||
:is-muted
|
||||
:auth-backend
|
||||
:email
|
||||
:default-team-id
|
||||
:default-project-id
|
||||
:fullname
|
||||
:lang])
|
||||
|
||||
(defn profile->props
|
||||
[profile]
|
||||
(-> profile
|
||||
@ -65,12 +72,6 @@
|
||||
(merge (:props profile))
|
||||
(d/without-nils)))
|
||||
|
||||
(def reserved-props
|
||||
#{:session-id
|
||||
:password
|
||||
:old-password
|
||||
:token})
|
||||
|
||||
(defn clean-props
|
||||
[props]
|
||||
(into {}
|
||||
@ -238,15 +239,17 @@
|
||||
(some? tnow)
|
||||
(assoc :tracked-at tnow))))
|
||||
|
||||
(def ^:private xf:filter-safe-props
|
||||
(def ^:private xf:filter-telemetry-props
|
||||
"Transducer that keeps only map entries whose values are UUIDs."
|
||||
(filter (fn [[_ v]] (uuid? v))))
|
||||
(filter (fn [[k v]]
|
||||
(and (simple-keyword? k)
|
||||
(or (uuid? v) (boolean? v) (number? v))))))
|
||||
|
||||
(defn filter-safe-props
|
||||
(defn filter-telemetry-props
|
||||
"Return only UUID-valued keys from a props map. This preserves
|
||||
object relations while maintaining anonymity."
|
||||
[props]
|
||||
(into {} xf:filter-safe-props props))
|
||||
(into {} xf:filter-telemetry-props props))
|
||||
|
||||
(defn- append-audit-entry
|
||||
[cfg params]
|
||||
@ -256,6 +259,32 @@
|
||||
(update :ip-addr db/inet))]
|
||||
(db/insert! cfg :audit-log params)))
|
||||
|
||||
(defn- get-telemetry-context
|
||||
"Get a telemetry ready safe context"
|
||||
[{:keys [context]}]
|
||||
(select-keys context [:initiator
|
||||
:version
|
||||
:client-version
|
||||
:client-user-agent]))
|
||||
|
||||
(defn- get-telemetry-props
|
||||
"A telemetry specific safe props"
|
||||
[{:keys [name props] :as params}]
|
||||
(cond
|
||||
(or (= name "login-with-oidc")
|
||||
(= name "login-with-password")
|
||||
(= name "register-profile")
|
||||
(= name "update-profile"))
|
||||
(-> (select-keys props profile-props)
|
||||
(filter-telemetry-props)
|
||||
(assoc :lang (:lang props))
|
||||
(assoc :auth-backend (:auth-backend props))
|
||||
(assoc :email-domain (email/get-domain (:email props)))
|
||||
(d/without-nils))
|
||||
|
||||
:else
|
||||
(filter-telemetry-props props)))
|
||||
|
||||
(defn- handle-event!
|
||||
[cfg event]
|
||||
(let [tnow (ct/now)
|
||||
@ -291,20 +320,15 @@
|
||||
;; kept: initiator, version, client-version and client-user-agent.
|
||||
;; Timestamps are truncated to day precision to avoid leaking exact
|
||||
;; event timing.
|
||||
(let [tday (ct/truncate tnow :days)
|
||||
safe-context (-> (:context params {})
|
||||
(select-keys [:initiator
|
||||
:version
|
||||
:client-version
|
||||
:client-user-agent]))
|
||||
safe-props (filter-safe-props (:props params {}))
|
||||
params (-> params
|
||||
(assoc :source "telemetry:backend")
|
||||
(assoc :props safe-props)
|
||||
(assoc :context safe-context)
|
||||
(assoc :ip-addr (db/inet "0.0.0.0"))
|
||||
(assoc :created-at tday)
|
||||
(assoc :tracked-at tday))]
|
||||
(let [event-name (get params :name)
|
||||
tday (ct/truncate tnow :days)
|
||||
params (-> params
|
||||
(assoc :source "telemetry:backend")
|
||||
(assoc :props (get-telemetry-props params))
|
||||
(assoc :context (get-telemetry-context params))
|
||||
(assoc :ip-addr (db/inet "0.0.0.0"))
|
||||
(assoc :created-at tday)
|
||||
(assoc :tracked-at tday))]
|
||||
(append-audit-entry cfg params))))
|
||||
|
||||
(when (and (contains? cf/flags :webhooks)
|
||||
|
||||
@ -124,8 +124,12 @@
|
||||
(comp
|
||||
(map adjust-timestamp)
|
||||
(map (fn [event]
|
||||
(let [tday (ct/truncate (::audit/created-at event) :days)
|
||||
safe-props (audit/filter-safe-props (::audit/props event {}))]
|
||||
(let [tday (-> (::audit/created-at event)
|
||||
(ct/truncate :days))
|
||||
safe-props (-> (::audit/props event {})
|
||||
(audit/filter-telemetry-props))
|
||||
safe-context (-> (::audit/context event)
|
||||
(select-keys safe-context-keys))]
|
||||
[(::audit/id event)
|
||||
(::audit/name event)
|
||||
"telemetry:frontend"
|
||||
@ -135,7 +139,7 @@
|
||||
(::audit/profile-id event)
|
||||
(db/inet "0.0.0.0")
|
||||
(db/tjson safe-props)
|
||||
(db/tjson (filter-safe-context (::audit/context event {})))])))))
|
||||
(db/tjson safe-context)])))))
|
||||
|
||||
(defn- handle-events
|
||||
[{:keys [::db/pool] :as cfg} params]
|
||||
|
||||
@ -61,26 +61,30 @@
|
||||
(rx/of (dcm/go-to-dashboard-recent {:team-id team-id})))))))]
|
||||
|
||||
(ptk/reify ::logged-in
|
||||
ev/Event
|
||||
(-data [_]
|
||||
{::ev/name "signin"
|
||||
::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 [_ _ stream]
|
||||
(cf/initialize-external-context-info)
|
||||
|
||||
|
||||
(->> (rx/merge
|
||||
(rx/of (dp/set-profile profile)
|
||||
(ws/initialize)
|
||||
(dtm/fetch-teams))
|
||||
|
||||
;; We schedule this event to be executed a bit later,
|
||||
;; when the profile is already set
|
||||
(->> (rx/of (ev/event {::ev/name "signin"
|
||||
::ev/type "identify"
|
||||
:id (:id profile)
|
||||
: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)}))
|
||||
(rx/observe-on :async))
|
||||
|
||||
|
||||
(->> stream
|
||||
(rx/filter (ptk/type? ::dtm/teams-fetched))
|
||||
(rx/take 1)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user