mirror of
https://github.com/penpot/penpot.git
synced 2025-05-12 22:26:38 +02:00
🎉 Add 'email-verification' flag enabled by default
The main idea is deprecating the `insecure-register` flag with the more general `email-verification` flag.
This commit is contained in:
parent
41134f22e9
commit
2348146f00
7 changed files with 88 additions and 19 deletions
|
@ -23,6 +23,10 @@
|
||||||
- Add Libraries & Templates carousel [Taiga #3860](https://tree.taiga.io/project/penpot/us/3860)
|
- Add Libraries & Templates carousel [Taiga #3860](https://tree.taiga.io/project/penpot/us/3860)
|
||||||
- Ungroup frames [Taiga #4012](https://tree.taiga.io/project/penpot/us/4012)
|
- Ungroup frames [Taiga #4012](https://tree.taiga.io/project/penpot/us/4012)
|
||||||
- Newsletter Opt-in options for subscription categories [Taiga #3242](https://tree.taiga.io/project/penpot/us/3242)
|
- Newsletter Opt-in options for subscription categories [Taiga #3242](https://tree.taiga.io/project/penpot/us/3242)
|
||||||
|
- Print emails to console by default if smtp is disabled
|
||||||
|
- Add `email-verification` flag for enable/disable email verification
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### :bug: Bugs fixed
|
### :bug: Bugs fixed
|
||||||
|
|
||||||
|
@ -51,6 +55,7 @@
|
||||||
- Fix issue when scaling to value 0 [#2252](https://github.com/penpot/penpot/issues/2252)
|
- Fix issue when scaling to value 0 [#2252](https://github.com/penpot/penpot/issues/2252)
|
||||||
- Fix problem when moving shapes inside nested frames [Taiga #4113](https://tree.taiga.io/project/penpot/issue/4113)
|
- Fix problem when moving shapes inside nested frames [Taiga #4113](https://tree.taiga.io/project/penpot/issue/4113)
|
||||||
|
|
||||||
|
|
||||||
## 1.15.3-beta
|
## 1.15.3-beta
|
||||||
|
|
||||||
### :bug: Bugs fixed
|
### :bug: Bugs fixed
|
||||||
|
|
|
@ -317,7 +317,8 @@
|
||||||
(def default-flags
|
(def default-flags
|
||||||
[:enable-backend-api-doc
|
[:enable-backend-api-doc
|
||||||
:enable-backend-worker
|
:enable-backend-worker
|
||||||
:enable-secure-session-cookies])
|
:enable-secure-session-cookies
|
||||||
|
:enable-email-verification])
|
||||||
|
|
||||||
(defn- parse-flags
|
(defn- parse-flags
|
||||||
[config]
|
[config]
|
||||||
|
|
|
@ -417,6 +417,7 @@
|
||||||
(ig/prep)
|
(ig/prep)
|
||||||
(ig/init))))
|
(ig/init))))
|
||||||
(l/info :msg "welcome to penpot"
|
(l/info :msg "welcome to penpot"
|
||||||
|
:worker? (contains? cf/flags :backend-worker)
|
||||||
:version (:full cf/version)))
|
:version (:full cf/version)))
|
||||||
|
|
||||||
(defn stop
|
(defn stop
|
||||||
|
|
|
@ -324,17 +324,25 @@
|
||||||
params (merge params claims)]
|
params (merge params claims)]
|
||||||
(check-profile-existence! conn params)
|
(check-profile-existence! conn params)
|
||||||
(let [is-active (or (:is-active params)
|
(let [is-active (or (:is-active params)
|
||||||
|
(not (contains? cf/flags :email-verification))
|
||||||
|
|
||||||
|
;; DEPRECATED: v1.15
|
||||||
(contains? cf/flags :insecure-register))
|
(contains? cf/flags :insecure-register))
|
||||||
|
|
||||||
profile (->> (assoc params :is-active is-active)
|
profile (->> (assoc params :is-active is-active)
|
||||||
(create-profile conn)
|
(create-profile conn)
|
||||||
(create-profile-relations conn)
|
(create-profile-relations conn)
|
||||||
(profile/decode-profile-row))
|
(profile/decode-profile-row))
|
||||||
|
|
||||||
invitation (when-let [token (:invitation-token params)]
|
invitation (when-let [token (:invitation-token params)]
|
||||||
(tokens/verify sprops {:token token :iss :team-invitation}))]
|
(tokens/verify sprops {:token token :iss :team-invitation}))]
|
||||||
(cond
|
(cond
|
||||||
;; If invitation token comes in params, this is because the user comes from team-invitation process;
|
;; If invitation token comes in params, this is because the
|
||||||
;; in this case, regenerate token and send back to the user a new invitation token (and mark current
|
;; user comes from team-invitation process; in this case,
|
||||||
;; session as logged). This happens only if the invitation email matches with the register email.
|
;; regenerate token and send back to the user a new invitation
|
||||||
|
;; token (and mark current session as logged). This happens
|
||||||
|
;; only if the invitation email matches with the register
|
||||||
|
;; email.
|
||||||
(and (some? invitation) (= (:email profile) (:member-email invitation)))
|
(and (some? invitation) (= (:email profile) (:member-email invitation)))
|
||||||
(let [claims (assoc invitation :member-id (:id profile))
|
(let [claims (assoc invitation :member-id (:id profile))
|
||||||
token (tokens/generate sprops claims)
|
token (tokens/generate sprops claims)
|
||||||
|
|
|
@ -419,26 +419,51 @@
|
||||||
(ex/raise :type :validation
|
(ex/raise :type :validation
|
||||||
:code :member-is-muted
|
:code :member-is-muted
|
||||||
:email email
|
:email email
|
||||||
:hint "looks like the profile has reported repeatedly as spam or has permanent bounces"))
|
:hint "the profile has reported repeatedly as spam or has bounces"))
|
||||||
|
|
||||||
;; Secondly check if the invited member email is part of the global spam/bounce report.
|
;; Secondly check if the invited member email is part of the global spam/bounce report.
|
||||||
(when (eml/has-bounce-reports? conn email)
|
(when (eml/has-bounce-reports? conn email)
|
||||||
(ex/raise :type :validation
|
(ex/raise :type :validation
|
||||||
:code :email-has-permanent-bounces
|
:code :email-has-permanent-bounces
|
||||||
:email email
|
:email email
|
||||||
:hint "looks like the email you invite has been repeatedly reported as spam or permanent bounce"))
|
:hint "the email you invite has been repeatedly reported as spam or bounce"))
|
||||||
|
|
||||||
(db/exec-one! conn [sql:upsert-team-invitation
|
;; When we have email verification disabled and invitation user is
|
||||||
(:id team) (str/lower email) (name role) token-exp (name role) token-exp])
|
;; already present in the database, we proceed to add it to the
|
||||||
|
;; team as-is, without email roundtrip.
|
||||||
|
|
||||||
(eml/send! {::eml/conn conn
|
;; TODO: if member does not exists and email verification is
|
||||||
::eml/factory eml/invite-to-team
|
;; disabled, we should proceed to create the profile (?)
|
||||||
:public-uri (:public-uri cfg)
|
(if (and (not (contains? cf/flags :email-verification))
|
||||||
:to email
|
(some? member))
|
||||||
:invited-by (:fullname profile)
|
(let [params (merge {:team-id (:id team)
|
||||||
:team (:name team)
|
:profile-id (:id member)}
|
||||||
:token itoken
|
(role->params role))]
|
||||||
:extra-data ptoken})))
|
|
||||||
|
;; Insert the invited member to the team
|
||||||
|
(db/insert! conn :team-profile-rel params {:on-conflict-do-nothing true})
|
||||||
|
|
||||||
|
;; If profile is not yet verified, mark it as verified because
|
||||||
|
;; accepting an invitation link serves as verification.
|
||||||
|
(when-not (:is-active member)
|
||||||
|
(db/update! conn :profile
|
||||||
|
{:is-active true}
|
||||||
|
{:id (:id member)}))
|
||||||
|
|
||||||
|
(assoc member :is-active true))
|
||||||
|
|
||||||
|
(do
|
||||||
|
(db/exec-one! conn [sql:upsert-team-invitation
|
||||||
|
(:id team) (str/lower email) (name role)
|
||||||
|
token-exp (name role) token-exp])
|
||||||
|
(eml/send! {::eml/conn conn
|
||||||
|
::eml/factory eml/invite-to-team
|
||||||
|
:public-uri (:public-uri cfg)
|
||||||
|
:to email
|
||||||
|
:invited-by (:fullname profile)
|
||||||
|
:team (:name team)
|
||||||
|
:token itoken
|
||||||
|
:extra-data ptoken})))))
|
||||||
|
|
||||||
;; --- Mutation: Create Team & Invite Members
|
;; --- Mutation: Create Team & Invite Members
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,37 @@
|
||||||
|
|
||||||
)))
|
)))
|
||||||
|
|
||||||
|
|
||||||
|
(t/deftest invite-team-member-with-email-verification-disabled
|
||||||
|
(with-mocks [mock {:target 'app.emails/send! :return nil}]
|
||||||
|
(let [profile1 (th/create-profile* 1 {:is-active true})
|
||||||
|
profile2 (th/create-profile* 2 {:is-active true})
|
||||||
|
profile3 (th/create-profile* 3 {:is-active true :is-muted true})
|
||||||
|
|
||||||
|
team (th/create-team* 1 {:profile-id (:id profile1)})
|
||||||
|
|
||||||
|
pool (:app.db/pool th/*system*)
|
||||||
|
data {::th/type :invite-team-member
|
||||||
|
:team-id (:id team)
|
||||||
|
:role :editor
|
||||||
|
:profile-id (:id profile1)}]
|
||||||
|
|
||||||
|
;; invite internal user without complaints
|
||||||
|
(with-redefs [app.config/flags #{}]
|
||||||
|
(th/reset-mock! mock)
|
||||||
|
(let [data (assoc data :email (:email profile2))
|
||||||
|
out (th/mutation! data)]
|
||||||
|
(t/is (= {} (:result out)))
|
||||||
|
(t/is (= 0 (:call-count (deref mock)))))
|
||||||
|
|
||||||
|
|
||||||
|
(let [members (db/query pool :team-profile-rel
|
||||||
|
{:team-id (:id team)
|
||||||
|
:profile-id (:id profile2)})]
|
||||||
|
(t/is (= 1 (count members)))
|
||||||
|
(t/is (true? (-> members first :can-edit))))))))
|
||||||
|
|
||||||
|
|
||||||
(t/deftest test-deletion
|
(t/deftest test-deletion
|
||||||
(let [task (:app.tasks.objects-gc/handler th/*system*)
|
(let [task (:app.tasks.objects-gc/handler th/*system*)
|
||||||
profile1 (th/create-profile* 1 {:is-active true})
|
profile1 (th/create-profile* 1 {:is-active true})
|
||||||
|
|
|
@ -6,11 +6,10 @@
|
||||||
## setting.
|
## setting.
|
||||||
|
|
||||||
PENPOT_PUBLIC_URI=http://localhost:9001
|
PENPOT_PUBLIC_URI=http://localhost:9001
|
||||||
PENPOT_TENANT=pro
|
|
||||||
|
|
||||||
## Feature flags.
|
## Feature flags.
|
||||||
|
|
||||||
PENPOT_FLAGS="enable-registration enable-login"
|
PENPOT_FLAGS="enable-registration enable-login disable-email-verification"
|
||||||
|
|
||||||
## Temporal workaround because of bad builtin default
|
## Temporal workaround because of bad builtin default
|
||||||
|
|
||||||
|
@ -43,7 +42,6 @@ PENPOT_TELEMETRY_ENABLED=true
|
||||||
## console, but for production usage is recommended to setup a real
|
## console, but for production usage is recommended to setup a real
|
||||||
## SMTP provider. Emails are used to confirm user registrations.
|
## SMTP provider. Emails are used to confirm user registrations.
|
||||||
|
|
||||||
PENPOT_SMTP_ENABLED=false
|
|
||||||
PENPOT_SMTP_DEFAULT_FROM=no-reply@example.com
|
PENPOT_SMTP_DEFAULT_FROM=no-reply@example.com
|
||||||
PENPOT_SMTP_DEFAULT_REPLY_TO=no-reply@example.com
|
PENPOT_SMTP_DEFAULT_REPLY_TO=no-reply@example.com
|
||||||
# PENPOT_SMTP_HOST=
|
# PENPOT_SMTP_HOST=
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue