penpot/src/uxbox/main/data/auth.cljs
Andrey Antukh 507e2b1d38
Merge uxbox.common and uxbox.util modules.
Under uxbox.util.
2016-06-30 19:57:39 +03:00

180 lines
5.0 KiB
Clojure

;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2015-2016 Andrey Antukh <niwi@niwi.nz>
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
(ns uxbox.main.data.auth
(:require [beicon.core :as rx]
[promesa.core :as p]
[uxbox.main.repo :as rp]
[uxbox.util.rstore :as rs]
[uxbox.util.router :as rt]
[uxbox.main.state :as st]
[uxbox.util.schema :as us]
[uxbox.util.i18n :refer (tr)]
[uxbox.main.data.projects :as udp]
[uxbox.main.data.users :as udu]
[uxbox.main.data.messages :as udm]
[uxbox.main.data.forms :as udf]
[uxbox.util.storage :refer (storage)]))
;; --- Logged In
(defrecord LoggedIn [data]
rs/UpdateEvent
(-apply-update [this state]
(assoc state :auth data))
rs/WatchEvent
(-apply-watch [this state s]
(swap! storage assoc :uxbox/auth data)
(rx/of (udu/fetch-profile)
(rt/navigate :dashboard/projects))))
(defn logged-in?
[v]
(instance? LoggedIn v))
(defn logged-in
[data]
(LoggedIn. data))
;; --- Login
(defrecord Login [username password]
rs/UpdateEvent
(-apply-update [_ state]
(merge state (dissoc (st/initial-state) :route)))
rs/WatchEvent
(-apply-watch [this state s]
(let [params {:username username
:password password
:scope "webapp"}
on-error #(udm/error (tr "errors.auth.unauthorized"))]
(->> (rp/req :fetch/token params)
(rx/map :payload)
(rx/map logged-in)
(rx/catch rp/client-error? on-error)))))
(defn login
[params]
(map->Login params))
;; --- Logout
(defrecord Logout []
rs/UpdateEvent
(-apply-update [_ state]
(swap! storage dissoc :uxbox/auth)
(merge state (dissoc (st/initial-state) :route)))
rs/WatchEvent
(-apply-watch [_ state s]
(rx/of (rt/navigate :auth/login))))
(defn logout
[]
(->Logout))
;; --- Register
(defrecord Register [data]
rs/WatchEvent
(-apply-watch [_ state stream]
(letfn [(on-error [{payload :payload}]
(->> (:payload payload)
(udf/assign-errors :register)
(rx/of)))]
(rx/merge
(->> (rp/req :auth/register data)
(rx/map :payload)
(rx/map (constantly ::registered))
(rx/catch rp/client-error? on-error))
(->> stream
(rx/filter #(= % ::registered))
(rx/take 1)
(rx/map #(login data)))
(->> stream
(rx/filter logged-in?)
(rx/take 1)
(rx/map #(udf/clean :register)))))))
(def register-schema
{:username [us/required us/string]
:fullname [us/required us/string]
:email [us/required us/email]
:password [us/required us/string]})
(defn register
"Create a register event instance."
[data]
(let [[errors data] (us/validate data register-schema)]
(if errors
(udf/assign-errors :register errors)
(Register. data))))
;; --- Recovery Request
(defrecord RecoveryRequest [data]
rs/WatchEvent
(-apply-watch [_ state stream]
(letfn [(on-error [{payload :payload}]
(println "on-error" payload)
(->> (:payload payload)
(udf/assign-errors :recovery-request)
(rx/of)))]
(rx/merge
(->> (rp/req :auth/recovery-request data)
(rx/map (constantly ::recovery-requested))
(rx/catch rp/client-error? on-error))
(->> stream
(rx/filter #(= % ::recovery-requested))
(rx/take 1)
(rx/do #(udm/info! (tr "auth.message.recovery-token-sent")))
(rx/map #(udf/clean :recovery-request)))))))
(defn recovery-request
[data]
(RecoveryRequest. data))
;; --- Check Recovery Token
(defrecord ValidateRecoveryToken [token]
rs/WatchEvent
(-apply-watch [_ state stream]
(letfn [(on-error [{payload :payload}]
(rx/of
(rt/navigate :auth/login)
(udm/show-error (tr "errors.auth.invalid-recovery-token"))))]
(->> (rp/req :auth/validate-recovery-token token)
(rx/ignore)
(rx/catch rp/client-error? on-error)))))
(defn validate-recovery-token
[data]
(ValidateRecoveryToken. data))
;; --- Recovery (Password)
(defrecord Recovery [token password]
rs/WatchEvent
(-apply-watch [_ state stream]
(letfn [(on-error [{payload :payload}]
(udm/error (tr "errors.auth.invalid-recovery-token")))
(on-success [{payload :payload}]
(rx/of
(rt/navigate :auth/login)
(udm/show-info (tr "auth.message.password-recovered"))))]
(->> (rp/req :auth/recovery {:token token :password password})
(rx/mapcat on-success)
(rx/catch rp/client-error? on-error)))))
(defn recovery
[{:keys [token password]}]
(Recovery. token password))