mirror of
https://github.com/penpot/penpot.git
synced 2026-09-16 00:49:21 +00:00
✨ Disable newsletter telemetry fallback on official hosts
Skip the limited newsletter report when the public-uri host belongs to penpot.dev or penpot.app, so the SaaS never sends subscriber emails to its own telemetry endpoint. Defer the subscriptions query with delay so it only runs when a report is actually going to be sent. AI-assisted-by: muse-spark-1.3-contributor
This commit is contained in:
parent
37f7ba4833
commit
e5f375edbc
@ -298,6 +298,18 @@
|
||||
[:ssrf-allowed-hosts {:optional true} [::sm/set :string]]
|
||||
[:ssrf-extra-blocked-cidrs {:optional true} [::sm/set :string]]]))
|
||||
|
||||
(defn telemetry-excluded-host?
|
||||
"Returns true when the given host belongs to the official SaaS
|
||||
instances, where telemetry must be fully disabled."
|
||||
[host]
|
||||
(let [host (some-> host (str/lower) (str/trim))]
|
||||
(and (string? host)
|
||||
(not (str/blank? host))
|
||||
(or (= host "penpot.dev")
|
||||
(= host "penpot.app")
|
||||
(str/ends-with? host ".penpot.dev")
|
||||
(str/ends-with? host ".penpot.app")))))
|
||||
|
||||
(defn- parse-flags
|
||||
[config]
|
||||
(let [public-uri (c/get config :public-uri)
|
||||
@ -386,6 +398,15 @@
|
||||
([key default]
|
||||
(c/get config key default)))
|
||||
|
||||
(defn telemetry-excluded?
|
||||
"Returns true when telemetry must be fully disabled because the
|
||||
public-uri host points to an official instance (penpot.dev or
|
||||
penpot.app). When true, no telemetry data is collected or sent,
|
||||
not even the limited newsletter report."
|
||||
[]
|
||||
(let [host (some-> (c/get config :public-uri) (u/uri) :host)]
|
||||
(telemetry-excluded-host? host)))
|
||||
|
||||
(defn logging-context
|
||||
[]
|
||||
{:backend/version (:full version)})
|
||||
|
||||
@ -26,7 +26,8 @@
|
||||
(let [sql "SELECT email FROM profile where props->>'~:newsletter-updates' = 'true'"]
|
||||
(db/run! cfg (fn [{:keys [::db/conn]}]
|
||||
(->> (db/exec! conn [sql])
|
||||
(mapv :email))))))
|
||||
(into [] (map :email))
|
||||
(not-empty))))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; LEGACY DATA COLLECTION
|
||||
@ -312,8 +313,9 @@
|
||||
send? (get params :send? true)
|
||||
enabled? (or (get params :enabled? false)
|
||||
(contains? cf/flags :telemetry))
|
||||
subs (get-subscriptions cfg)]
|
||||
|
||||
;; Deferred so the query runs only when a report is
|
||||
;; actually going to be sent.
|
||||
subs (delay (get-subscriptions cfg))]
|
||||
|
||||
;; If we have telemetry enabled, then proceed the normal
|
||||
;; operation sending legacy report
|
||||
@ -327,7 +329,7 @@
|
||||
|
||||
(try
|
||||
(let [stats (db/run! cfg get-legacy-stats)]
|
||||
(send-legacy-data cfg stats subs))
|
||||
(send-legacy-data cfg stats @subs))
|
||||
(catch Exception cause
|
||||
(l/wrn :hint "unable to send legacy report"
|
||||
:cause cause)))
|
||||
@ -346,7 +348,10 @@
|
||||
;; onboarding dialog or the profile section, then proceed to
|
||||
;; send a limited telemetry data, that consists in the list of
|
||||
;; subscribed emails and the running penpot version.
|
||||
(when (and send? (seq subs))
|
||||
;; Official instances (penpot.dev / penpot.app) are excluded:
|
||||
;; they must never send subscriber emails to the telemetry
|
||||
;; endpoint (which is ourselves).
|
||||
(when (and (not (cf/telemetry-excluded?)) send? @subs)
|
||||
(px/sleep (rand-int 10000))
|
||||
(ex/ignoring
|
||||
(send-legacy-data cfg nil subs)))))))
|
||||
(send-legacy-data cfg nil @subs)))))))
|
||||
|
||||
@ -135,6 +135,58 @@
|
||||
(th/run-task! :telemetry {:send? false :enabled? true})
|
||||
(t/is (not (:called? @mock))))))
|
||||
|
||||
(t/deftest test-telemetry-excluded-host-predicate
|
||||
(t/is (true? (cf/telemetry-excluded-host? "penpot.app")))
|
||||
(t/is (true? (cf/telemetry-excluded-host? "penpot.dev")))
|
||||
(t/is (true? (cf/telemetry-excluded-host? "design.penpot.app")))
|
||||
(t/is (true? (cf/telemetry-excluded-host? "design.penpot.dev")))
|
||||
(t/is (true? (cf/telemetry-excluded-host? "DESIGN.PENPOT.APP")))
|
||||
(t/is (false? (cf/telemetry-excluded-host? "localhost")))
|
||||
(t/is (false? (cf/telemetry-excluded-host? "example.com")))
|
||||
(t/is (false? (cf/telemetry-excluded-host? "mypenpot.app.example.com")))
|
||||
(t/is (false? (cf/telemetry-excluded-host? nil)))
|
||||
(t/is (false? (cf/telemetry-excluded-host? ""))))
|
||||
|
||||
(t/deftest test-telemetry-disabled-on-official-host-newsletter-only
|
||||
;; The limited newsletter report must not be sent from official
|
||||
;; instances, even when subscriptions exist.
|
||||
(doseq [[idx public-uri] (map-indexed vector ["https://design.penpot.app"
|
||||
"https://penpot.app"
|
||||
"https://design.penpot.dev"
|
||||
"https://penpot.dev"])]
|
||||
(with-mocks [mock {:target 'app.tasks.telemetry/make-legacy-request
|
||||
:return nil}]
|
||||
(with-redefs [cf/flags #{}
|
||||
cf/config (assoc cf/config :public-uri public-uri)]
|
||||
(th/create-profile* (+ 10 idx) {:is-active true
|
||||
:props {:newsletter-updates true}})
|
||||
(th/run-task! :telemetry {:send? true})
|
||||
(t/is (not (:called? @mock)) (str "newsletter report must not send for " public-uri))))))
|
||||
|
||||
(t/deftest test-telemetry-excluded-skips-subscriptions-query
|
||||
;; On official hosts the subscriptions query must not even run,
|
||||
;; since nothing is going to be sent.
|
||||
(with-mocks [mock {:target 'app.tasks.telemetry/get-subscriptions
|
||||
:return []}]
|
||||
(with-redefs [cf/flags #{}
|
||||
cf/config (assoc cf/config :public-uri "https://design.penpot.app")]
|
||||
(th/create-profile* 1 {:is-active true
|
||||
:props {:newsletter-updates true}})
|
||||
(th/run-task! :telemetry {:send? true})
|
||||
(t/is (not (:called? @mock))))))
|
||||
|
||||
(t/deftest test-telemetry-enabled-still-sends-on-official-host
|
||||
;; An explicitly enabled telemetry still reports on official hosts;
|
||||
;; only the implicit newsletter fallback is excluded.
|
||||
(with-mocks [mock {:target 'app.tasks.telemetry/make-legacy-request
|
||||
:return nil}]
|
||||
(with-redefs [cf/flags #{:telemetry}
|
||||
cf/config (assoc cf/config :public-uri "https://design.penpot.app")]
|
||||
(th/create-profile* 1 {:is-active true
|
||||
:props {:newsletter-updates true}})
|
||||
(th/run-task! :telemetry {:send? true :enabled? true})
|
||||
(t/is (:called? @mock)))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; AUDIT-EVENT BATCH COLLECTION TESTS
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user