♻️ Refactor email validations & tokens service.

This commit is contained in:
Andrey Antukh 2020-09-21 16:01:49 +02:00 committed by Alonso Torres
parent dda6a96407
commit 7d9fdc34be
20 changed files with 369 additions and 398 deletions

View file

@ -146,10 +146,7 @@
on-success identity}} (meta data)]
(->> (rp/mutation :register-profile data)
(rx/tap on-success)
(rx/map #(login data))
(rx/catch (fn [err]
(on-error err)
(rx/empty))))))))
(rx/catch on-error))))))
;; --- Request Account Deletion

View file

@ -114,10 +114,7 @@
on-success identity}} (meta data)]
(->> (rp/mutation :request-email-change data)
(rx/tap on-success)
(rx/map (constantly fetch-profile))
(rx/catch (fn [err]
(on-error err)
(rx/empty))))))))
(rx/catch on-error))))))
;; --- Cancel Email Change

View file

@ -9,23 +9,23 @@
(ns app.main.ui.auth
(:require
[cljs.spec.alpha :as s]
[beicon.core :as rx]
[rumext.alpha :as mf]
[app.main.ui.icons :as i]
[app.main.data.auth :as da]
[app.main.data.users :as du]
[app.main.data.messages :as dm]
[app.main.data.users :as du]
[app.main.repo :as rp]
[app.main.store :as st]
[app.main.ui.auth.login :refer [login-page]]
[app.main.ui.auth.recovery :refer [recovery-page]]
[app.main.ui.auth.recovery-request :refer [recovery-request-page]]
[app.main.ui.auth.register :refer [register-page]]
[app.main.repo :as rp]
[app.util.timers :as ts]
[app.main.ui.icons :as i]
[app.util.forms :as fm]
[app.util.i18n :as i18n :refer [tr t]]
[app.util.router :as rt]))
[app.util.router :as rt]
[app.util.timers :as ts]
[beicon.core :as rx]
[cljs.spec.alpha :as s]
[rumext.alpha :as mf]))
(mf/defc goodbye-page
[{:keys [locale] :as props}]
@ -50,24 +50,30 @@
:auth-recovery [:& recovery-page {:locale locale
:params (:query-params route)}])]]))
(defn- handle-email-verified
(defmulti handle-token (fn [token] (:iss token)))
(defmethod handle-token :verify-email
[data]
(let [msg (tr "settings.notifications.email-verified-successfully")]
(ts/schedule 100 #(st/emit! (dm/success msg)))
(st/emit! (rt/nav :settings-profile)
du/fetch-profile)))
(st/emit! (rt/nav :auth-login))))
(defn- handle-email-changed
(defmethod handle-token :change-email
[data]
(let [msg (tr "settings.notifications.email-changed-successfully")]
(ts/schedule 100 #(st/emit! (dm/success msg)))
(st/emit! (rt/nav :settings-profile)
du/fetch-profile)))
(defn- handle-authentication
(defmethod handle-token :auth
[tdata]
(st/emit! (da/login-from-token tdata)))
(defmethod handle-token :default
[tdata]
(js/console.log "Unhandled token:" (pr-str tdata))
(st/emit! (rt/nav :auth-login)))
(mf/defc verify-token
[{:keys [route] :as props}]
(let [token (get-in route [:query-params :token])]
@ -76,21 +82,22 @@
(->> (rp/mutation :verify-profile-token {:token token})
(rx/subs
(fn [tdata]
(case (:type tdata)
:verify-email (handle-email-verified tdata)
:change-email (handle-email-changed tdata)
:authentication (handle-authentication tdata)
nil))
(handle-token tdata))
(fn [error]
(case (:code error)
:app.services.mutations.profile/email-already-exists
:email-already-exists
(let [msg (tr "errors.email-already-exists")]
(ts/schedule 100 #(st/emit! (dm/error msg)))
(st/emit! (rt/nav :settings-profile)))
(st/emit! (rt/nav :auth-login)))
:email-already-validated
(let [msg (tr "errors.email-already-validated")]
(ts/schedule 100 #(st/emit! (dm/warn msg)))
(st/emit! (rt/nav :auth-login)))
(let [msg (tr "errors.generic")]
(ts/schedule 100 #(st/emit! (dm/error msg)))
(st/emit! (rt/nav :settings-profile)))))))))
(st/emit! (rt/nav :auth-login)))))))))
[:div.verify-token
i/loader-pencil]))

View file

@ -9,21 +9,22 @@
(ns app.main.ui.auth.register
(:require
[cljs.spec.alpha :as s]
[cuerdas.core :as str]
[rumext.alpha :as mf]
[app.config :as cfg]
[app.main.ui.icons :as i]
[app.main.data.auth :as uda]
[app.main.store :as st]
[app.main.data.auth :as da]
[app.main.data.auth :as uda]
[app.main.data.messages :as dm]
[app.main.store :as st]
[app.main.ui.components.forms :refer [input submit-button form]]
[app.main.ui.icons :as i]
[app.main.ui.messages :as msgs]
[app.util.dom :as dom]
[app.util.forms :as fm]
[app.util.i18n :refer [tr t]]
[app.util.router :as rt]))
[app.util.router :as rt]
[app.util.timers :as tm]
[cljs.spec.alpha :as s]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
(mf/defc demo-warning
[_]
@ -43,14 +44,20 @@
(defn- on-error
[form error]
(case (:code error)
:app.services.mutations.profile/registration-disabled
(st/emit! (tr "errors.registration-disabled"))
:registration-disabled
(st/emit! (dm/error (tr "errors.registration-disabled")))
:app.services.mutations.profile/email-already-exists
:email-already-exists
(swap! form assoc-in [:errors :email]
{:message "errors.email-already-exists"})
(st/emit! (tr "errors.unexpected-error"))))
(st/emit! (dm/error (tr "errors.unexpected-error")))))
(defn- on-success
[form data]
(let [msg (tr "auth.notifications.validation-email-sent" (:email data))]
(st/emit! (rt/nav :auth-login)
(dm/success msg))))
(defn- validate
[data]
@ -61,7 +68,8 @@
(defn- on-submit
[form event]
(let [data (with-meta (:clean-data form)
{:on-error (partial on-error form)})]
{:on-error (partial on-error form)
:on-success (partial on-success form)})]
(st/emit! (uda/register data))))
(mf/defc register-form

View file

@ -51,51 +51,33 @@
(= "drafts" project-id)
(assoc :project-id (:default-project-id profile)))))
(declare global-notifications)
(mf/defc dashboard
[{:keys [route] :as props}]
(let [profile (mf/deref refs/profile)
page (get-in route [:data :name])
{:keys [search-term team-id project-id] :as params}
(parse-params route profile)]
[:*
[:& global-notifications {:profile profile}]
[:section.dashboard-layout
[:div.main-logo
[:a {:on-click #(st/emit! (rt/nav :dashboard-team {:team-id team-id}))}
i/logo-icon]]
[:& profile-section {:profile profile}]
[:& sidebar {:team-id team-id
:project-id project-id
:section page
:search-term search-term}]
[:div.dashboard-content
(case page
:dashboard-search
[:& search-page {:team-id team-id :search-term search-term}]
page (get-in route [:data :name])
{:keys [search-term team-id project-id] :as params} (parse-params route profile)]
[:section.dashboard-layout
[:div.main-logo
[:a {:on-click #(st/emit! (rt/nav :dashboard-team {:team-id team-id}))}
i/logo-icon]]
[:& profile-section {:profile profile}]
[:& sidebar {:team-id team-id
:project-id project-id
:section page
:search-term search-term}]
[:div.dashboard-content
(case page
:dashboard-search
[:& search-page {:team-id team-id :search-term search-term}]
:dashboard-team
[:& recent-files-page {:team-id team-id}]
:dashboard-team
[:& recent-files-page {:team-id team-id}]
:dashboard-libraries
[:& libraries-page {:team-id team-id}]
:dashboard-libraries
[:& libraries-page {:team-id team-id}]
:dashboard-project
[:& project-page {:team-id team-id
:project-id project-id}])]]]))
:dashboard-project
[:& project-page {:team-id team-id
:project-id project-id}])]]))
(mf/defc global-notifications
[{:keys [profile] :as props}]
(let [locale (mf/deref i18n/locale)]
(when (and profile
(not= uuid/zero (:id profile))
(= (:pending-email profile)
(:email profile)))
[:section.banner.error.quick
[:div.content
[:div.icon i/msg-warning]
[:span (t locale "settings.notifications.email-not-verified" (:email profile))]]])))

View file

@ -23,9 +23,9 @@
(defonce components (atom {}))
(defn show!
([type props]
(let [id (random-uuid)]
(st/emit! (mdm/show-modal id type props)))))
[type props]
(let [id (random-uuid)]
(st/emit! (mdm/show-modal id type props))))
(defn allow-click-outside! []
(st/emit! (mdm/update-modal {:allow-click-outside true})))
@ -37,6 +37,8 @@
[]
(st/emit! (mdm/hide-modal)))
(def hide (mdm/hide-modal))
(defn- on-esc-clicked
[event]
(when (k/esc? event)

View file

@ -9,9 +9,7 @@
(ns app.main.ui.settings.change-email
(:require
[cljs.spec.alpha :as s]
[cuerdas.core :as str]
[rumext.alpha :as mf]
[app.common.spec :as us]
[app.main.data.auth :as da]
[app.main.data.messages :as dm]
[app.main.data.users :as du]
@ -21,12 +19,13 @@
[app.main.ui.icons :as i]
[app.main.ui.messages :as msgs]
[app.main.ui.modal :as modal]
[app.util.dom :as dom]
[app.util.forms :as fm]
[app.util.i18n :as i18n :refer [tr t]]))
[app.util.i18n :as i18n :refer [tr t]]
[cljs.spec.alpha :as s]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
(s/def ::email-1 ::fm/email)
(s/def ::email-2 ::fm/email)
(s/def ::email-1 ::us/email)
(s/def ::email-2 ::us/email)
(defn- email-equality
[data]
@ -42,7 +41,7 @@
(defn- on-error
[form error]
(cond
(= (:code error) :app.services.mutations.profile/email-already-exists)
(= (:code error) :email-already-exists)
(swap! form (fn [data]
(let [error {:message (tr "errors.email-already-exists")}]
(assoc-in data [:errors :email-1] error))))
@ -51,10 +50,16 @@
(let [msg (tr "errors.unexpected-error")]
(st/emit! (dm/error msg)))))
(defn- on-success
[profile data]
(let [msg (tr "auth.notifications.validation-email-sent" (:email profile))]
(st/emit! (dm/info msg) modal/hide)))
(defn- on-submit
[form event]
[profile form event]
(let [data (with-meta {:email (get-in form [:clean-data :email-1])}
{:on-error (partial on-error form)})]
{:on-error (partial on-error form)
:on-success (partial on-success profile)})]
(st/emit! (du/request-email-change data))))
(mf/defc change-email-form
@ -66,7 +71,7 @@
{:type :info
:content (t locale "settings.change-email-info" (:email profile))}]
[:& form {:on-submit on-submit
[:& form {:on-submit (partial on-submit profile)
:spec ::email-change-form
:validators [email-equality]
:initial {}}
@ -83,29 +88,14 @@
[:& submit-button
{:label (t locale "settings.change-email-submit-label")}]]])
(mf/defc change-email-confirmation
[{:keys [locale profile] :as locale}]
[:section.modal-content.generic-form.confirmation
[:h2 (t locale "settings.verification-sent-title")]
[:& msgs/inline-banner
{:type :info
:content (t locale "settings.change-email-info2" (:email profile))}]
[:button.btn-primary.btn-large
{:on-click #(modal/hide!)}
(t locale "settings.close-modal-label")]])
(mf/defc change-email-modal
{::mf/register modal/components
::mf/register-as :change-email}
[props]
(let [locale (mf/deref i18n/locale)
(let [locale (mf/deref i18n/locale)
profile (mf/deref refs/profile)]
[:div.modal-overlay
[:div.generic-modal.change-email-modal
[:span.close {:on-click #(modal/hide!)} i/close]
(if (:pending-email profile)
[:& change-email-confirmation {:locale locale :profile profile}]
[:& change-email-form {:locale locale :profile profile}])]]))
[:& change-email-form {:locale locale :profile profile}]]]))