0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-18 13:04:38 -05:00

🐛 Properly handle invitations on login

This commit is contained in:
Andrey Antukh 2022-02-28 12:08:31 +01:00
parent eb57c2f980
commit f64b1d3651
4 changed files with 52 additions and 37 deletions

View file

@ -170,13 +170,15 @@
(get-redirect-event)) (get-redirect-event))
(rx/observe-on :async))))))) (rx/observe-on :async)))))))
(s/def ::invitation-token ::us/not-empty-string)
(s/def ::login-params (s/def ::login-params
(s/keys :req-un [::email ::password])) (s/keys :req-un [::email ::password]
:opt-un [::invitation-token]))
(declare login-from-register) (declare login-from-register)
(defn login (defn login
[{:keys [email password] :as data}] [{:keys [email password invitation-token] :as data}]
(us/verify ::login-params data) (us/verify ::login-params data)
(ptk/reify ::login (ptk/reify ::login
ptk/WatchEvent ptk/WatchEvent
@ -184,9 +186,10 @@
(let [{:keys [on-error on-success] (let [{:keys [on-error on-success]
:or {on-error rx/throw :or {on-error rx/throw
on-success identity}} (meta data) on-success identity}} (meta data)
params {:email email params {:email email
:password password :password password
:scope "webapp"}] :invitation-token invitation-token}]
;; NOTE: We can't take the profile value from login because ;; NOTE: We can't take the profile value from login because
;; there are cases when login is successfull but the cookie is ;; there are cases when login is successfull but the cookie is
@ -197,31 +200,32 @@
;; the returned profile is an NOT authenticated profile, we ;; the returned profile is an NOT authenticated profile, we
;; proceed to logout and show an error message. ;; proceed to logout and show an error message.
(rx/merge (->> (rp/mutation :login (d/without-nils params))
(->> (rp/mutation :login params) (rx/merge-map (fn [data]
(rx/map fetch-profile) (rx/merge
(rx/catch on-error)) (rx/of (fetch-profile))
(->> stream
(rx/filter profile-fetched?)
(rx/take 1)
(rx/map deref)
(rx/filter (complement is-authenticated?))
(rx/tap on-error)
(rx/map #(ex/raise :type :authentication))
(rx/observe-on :async))
(->> stream (->> stream
(rx/filter profile-fetched?) (rx/filter profile-fetched?)
(rx/take 1) (rx/take 1)
(rx/map deref) (rx/map deref)
(rx/filter (complement is-authenticated?)) (rx/filter is-authenticated?)
(rx/tap on-error) (rx/map (fn [profile]
(rx/map #(ex/raise :type :authentication)) (with-meta (merge data profile)
(rx/observe-on :async)) {::ev/source "login"})))
(rx/tap on-success)
(rx/map logged-in)
(rx/observe-on :async)))))
(rx/catch on-error))))))
(->> stream
(rx/filter profile-fetched?)
(rx/take 1)
(rx/map deref)
(rx/filter is-authenticated?)
(rx/map (fn [profile]
(with-meta profile
{::ev/source "login"})))
(rx/tap on-success)
(rx/map logged-in)
(rx/observe-on :async)))))))
(defn login-from-token (defn login-from-token
[{:keys [profile] :as tdata}] [{:keys [profile] :as tdata}]

View file

@ -30,9 +30,11 @@
(s/def ::email ::us/email) (s/def ::email ::us/email)
(s/def ::password ::us/not-empty-string) (s/def ::password ::us/not-empty-string)
(s/def ::invitation-token ::us/not-empty-string)
(s/def ::login-form (s/def ::login-form
(s/keys :req-un [::email ::password])) (s/keys :req-un [::email ::password]
:opt-un [::invitation-token]))
(defn- login-with-oauth (defn- login-with-oauth
[event provider params] [event provider params]
@ -62,29 +64,39 @@
(mf/defc login-form (mf/defc login-form
[{:keys [params] :as props}] [{:keys [params] :as props}]
(let [error (mf/use-state false) (let [initial (mf/use-memo (mf/deps params) (constantly params))
form (fm/use-form :spec ::login-form
:inital {}) error (mf/use-state false)
form (fm/use-form :spec ::login-form :initial initial)
on-error on-error
(fn [_] (fn [_]
(reset! error (tr "errors.wrong-credentials"))) (reset! error (tr "errors.wrong-credentials")))
on-succes
(fn [data]
(prn "SUCCESS" data)
(when-let [token (:invitation-token data)]
(st/emit! (rt/nav :auth-verify-token {} {:token token}))))
on-submit on-submit
(mf/use-callback (mf/use-callback
(mf/deps form) (fn [form _event]
(fn [_]
(reset! error nil) (reset! error nil)
(let [params (with-meta (:clean-data @form) (let [params (with-meta (:clean-data @form)
{:on-error on-error})] {:on-error on-error
:on-success on-succes})]
(st/emit! (du/login params))))) (st/emit! (du/login params)))))
on-submit-ldap on-submit-ldap
(mf/use-callback (mf/use-callback
(mf/deps form) (mf/deps form)
(fn [event] (fn [event]
(let [params (merge (:clean-data @form) params)] (reset! error nil)
(login-with-ldap event (with-meta params {:on-error on-error})))))] (let [params (:clean-data @form)]
(login-with-ldap event (with-meta params
{:on-error on-error
:on-success on-succes})))))]
[:* [:*
(when-let [message @error] (when-let [message @error]

View file

@ -60,7 +60,7 @@
:email-already-exists :email-already-exists
(swap! form assoc-in [:errors :email] (swap! form assoc-in [:errors :email]
{:message "errors.email-already-exists"}) {:message "errors.email-already-exists"})
:email-as-password :email-as-password
(swap! form assoc-in [:errors :password] (swap! form assoc-in [:errors :password]
{:message "errors.email-as-password"}) {:message "errors.email-as-password"})

View file

@ -174,7 +174,6 @@
[{:keys [options label form default data-test] :as props [{:keys [options label form default data-test] :as props
:or {default ""}}] :or {default ""}}]
(let [input-name (get props :name) (let [input-name (get props :name)
form (or form (mf/use-ctx form-ctx)) form (or form (mf/use-ctx form-ctx))
value (or (get-in @form [:data input-name]) default) value (or (get-in @form [:data input-name]) default)
cvalue (d/seek #(= value (:value %)) options) cvalue (d/seek #(= value (:value %)) options)