0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-12 18:18:24 -05:00

🐛 Fix incorrect message on sending invitation to a member

This commit is contained in:
Andrey Antukh 2023-07-10 16:56:34 +02:00
parent ea753da0ae
commit 23c8043f34
4 changed files with 52 additions and 49 deletions

View file

@ -57,6 +57,7 @@
- Fix focus handling on comments edition [Taiga #5560](https://tree.taiga.io/project/penpot/issue/5560)
- Fix incorrect fullname use on registring user after OIDC authentication [Taiga #5517](https://tree.taiga.io/project/penpot/issue/5517)
- Fix incorrect modified-at on project after import file [Taiga #5268](https://tree.taiga.io/project/penpot/issue/5268)
- Fix incorrect message after sending invitation to already member [Taiga 5599](https://tree.taiga.io/project/penpot/issue/5599)
### :arrow_up: Deps updates

View file

@ -10,6 +10,7 @@
[app.common.data.macros :as dm]
[app.common.exceptions :as ex]
[app.common.logging :as l]
[app.common.schema :as sm]
[app.common.spec :as us]
[app.common.uuid :as uuid]
[app.config :as cf]
@ -719,29 +720,22 @@
itoken))))
(s/def ::email ::us/email)
(s/def ::emails ::us/set-of-valid-emails)
(s/def ::create-team-invitations
(s/keys :req [::rpc/profile-id]
:req-un [::team-id ::role]
:opt-un [::email ::emails]))
(def ^:private schema:create-team-invitations
[:map {:title "create-team-invitations"}
[:team-id ::sm/uuid]
[:role [::sm/one-of #{:owner :admin :editor}]]
[:emails ::sm/set-of-emails]])
(sv/defmethod ::create-team-invitations
"A rpc call that allow to send a single or multiple invitations to
join the team."
{::doc/added "1.17"}
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id team-id email emails role] :as params}]
{::doc/added "1.17"
::sm/params schema:create-team-invitations}
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id team-id emails role] :as params}]
(db/with-atomic [conn pool]
(let [perms (get-permissions conn profile-id team-id)
profile (db/get-by-id conn :profile profile-id)
team (db/get-by-id conn :team team-id)
;; Members emails. We don't re-send inviation to already existing members
member? (into #{}
(map :email)
(db/exec! conn [sql:team-members team-id]))
emails (cond-> (or emails #{}) (string? email) (conj email))]
team (db/get-by-id conn :team team-id)]
(run! (partial quotes/check-quote! conn)
(list {::quotes/id ::quotes/invitations-per-team
@ -764,9 +758,13 @@
:hint "looks like the profile has reported repeatedly as spam or has permanent bounces"))
(let [cfg (assoc cfg ::db/conn conn)
invitations (into []
members (->> (db/exec! conn [sql:team-members team-id])
(into #{} (map :email)))
invitations (into #{}
(comp
(remove member?)
;; We don't re-send inviation to already existing members
(remove (partial contains? members))
(map (fn [email]
{:email (str/lower email)
:team team
@ -774,7 +772,8 @@
:role role}))
(keep (partial create-invitation cfg)))
emails)]
(with-meta invitations
(with-meta {:total (count invitations)
:invitations invitations}
{::audit/props {:invitations (count invitations)}})))))

View file

@ -37,7 +37,7 @@
:role :editor}]
;; invite external user without complaints
(let [data (assoc data :email "foo@bar.com")
(let [data (assoc data :emails ["foo@bar.com"])
out (th/command! data)
;; retrieve the value from the database and check its content
invitation (db/exec-one!
@ -52,7 +52,7 @@
;; invite internal user without complaints
(th/reset-mock! mock)
(let [data (assoc data :email (:email profile2))
(let [data (assoc data :emails [(:email profile2)])
out (th/command! data)]
(t/is (th/success? out))
(t/is (= 1 (:call-count (deref mock)))))
@ -60,7 +60,7 @@
;; invite user with complaint
(th/create-global-complaint-for pool {:type :complaint :email "foo@bar.com"})
(th/reset-mock! mock)
(let [data (assoc data :email "foo@bar.com")
(let [data (assoc data :emails ["foo@bar.com"])
out (th/command! data)]
(t/is (th/success? out))
(t/is (= 1 (:call-count (deref mock)))))
@ -79,7 +79,7 @@
(th/reset-mock! mock)
(th/create-global-complaint-for pool {:type :bounce :email "foo@bar.com"})
(let [data (assoc data :email "foo@bar.com")
(let [data (assoc data :emails ["foo@bar.com"])
out (th/command! data)]
(t/is (not (th/success? out)))
@ -92,7 +92,7 @@
;; invite internal user that is muted
(th/reset-mock! mock)
(let [data (assoc data :email (:email profile3))
(let [data (assoc data :emails [(:email profile3)])
out (th/command! data)]
(t/is (not (th/success? out)))
@ -118,7 +118,7 @@
;; Try to invite a not existing user
(let [data {::th/type :create-team-invitations
::rpc/profile-id (:id profile1)
:email "notexisting@example.com"
:emails ["notexisting@example.com"]
:team-id (:id team)
:role :editor}
out (th/command! data)]
@ -126,15 +126,15 @@
;; (th/print-result! out)
(t/is (th/success? out))
(t/is (= 1 (:call-count @mock)))
(t/is (= 1 (-> out :result count)))
(t/is (= 1 (-> out :result :total)))
(let [token (-> out :result first)
(let [token (-> out :result :invitations first)
claims (tokens/decode sprops token)]
(t/is (= :team-invitation (:iss claims)))
(t/is (= (:id profile1) (:profile-id claims)))
(t/is (= :editor (:role claims)))
(t/is (= (:id team) (:team-id claims)))
(t/is (= (:email data) (:member-email claims)))
(t/is (= (first (:emails data)) (:member-email claims)))
(t/is (nil? (:member-id claims)))))
(th/reset-mock! mock)
@ -142,7 +142,7 @@
;; Try to invite existing user
(let [data {::th/type :create-team-invitations
::rpc/profile-id (:id profile1)
:email (:email profile2)
:emails [(:email profile2)]
:team-id (:id team)
:role :editor}
out (th/command! data)]
@ -150,15 +150,15 @@
;; (th/print-result! out)
(t/is (th/success? out))
(t/is (= 1 (:call-count @mock)))
(t/is (= 1 (-> out :result count)))
(t/is (= 1 (-> out :result :total)))
(let [token (-> out :result first)
(let [token (-> out :result :invitations first)
claims (tokens/decode sprops token)]
(t/is (= :team-invitation (:iss claims)))
(t/is (= (:id profile1) (:profile-id claims)))
(t/is (= :editor (:role claims)))
(t/is (= (:id team) (:team-id claims)))
(t/is (= (:email data) (:member-email claims)))
(t/is (= (first (:emails data)) (:member-email claims)))
(t/is (= (:id profile2) (:member-id claims)))))
)))
@ -264,7 +264,7 @@
;; invite internal user without complaints
(with-redefs [app.config/flags #{}]
(th/reset-mock! mock)
(let [data (assoc data :email (:email profile2))
(let [data (assoc data :emails [(:email profile2)])
out (th/command! data)]
(t/is (th/success? out))
(t/is (= 0 (:call-count (deref mock)))))

View file

@ -31,8 +31,9 @@
[rumext.v2 :as mf]))
(mf/defc header
{::mf/wrap [mf/memo]}
[{:keys [section team] :as props}]
{::mf/wrap [mf/memo]
::mf/wrap-props false}
[{:keys [section team]}]
(let [go-members (mf/use-fn #(st/emit! (dd/go-to-team-members)))
go-settings (mf/use-fn #(st/emit! (dd/go-to-team-settings)))
go-invitations (mf/use-fn #(st/emit! (dd/go-to-team-invitations)))
@ -98,27 +99,29 @@
(mf/defc invite-members-modal
{::mf/register modal/components
::mf/register-as :invite-members}
::mf/register-as :invite-members
::mf/wrap-props false}
[{:keys [team origin]}]
(let [members-map (mf/deref refs/dashboard-team-members)
perms (:permissions team)
perms (:permissions team)
roles (mf/use-memo (mf/deps perms) #(get-available-roles perms))
initial (mf/use-memo (constantly {:role "editor" :team-id (:id team)}))
form (fm/use-form :spec ::invite-member-form
:initial initial)
error-text (mf/use-state "")
on-success
(fn []
(st/emit! (msg/success (tr "notifications.invitation-email-sent"))
(modal/hide)
(dd/fetch-team-invitations)))
roles (mf/use-memo (mf/deps perms) #(get-available-roles perms))
initial (mf/use-memo (constantly {:role "editor" :team-id (:id team)}))
form (fm/use-form :spec ::invite-member-form
:initial initial)
error-text (mf/use-state "")
current-data-emails (into #{} (dm/get-in @form [:clean-data :emails]))
current-members-emails (into #{} (map (comp :email second)) members-map)
on-success
(fn [form {:keys [total]}]
(when (pos? total)
(st/emit! (msg/success (tr "notifications.invitation-email-sent"))))
(st/emit! (modal/hide)
(dd/fetch-team-invitations)))
on-error
(fn [{:keys [type code] :as error}]
(cond