;; 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) KALEIDOS INC (ns app.main.ui.settings.password (:require-macros [app.main.style :as stl]) (:require [app.common.spec :as us] [app.main.data.messages :as msg] [app.main.data.users :as udu] [app.main.store :as st] [app.main.ui.components.forms :as fm] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [t tr]] [cljs.spec.alpha :as s] [rumext.v2 :as mf])) (defn- on-error [form error] (case (:code (ex-data error)) :old-password-not-match (swap! form assoc-in [:errors :password-old] {:message (tr "errors.wrong-old-password")}) :email-as-password (swap! form assoc-in [:errors :password-1] {:message (tr "errors.email-as-password")}) (let [msg (tr "generic.error")] (st/emit! (msg/error msg))))) (defn- on-success [form] (reset! form nil) (let [password-old-node (dom/get-element "password-old") msg (tr "dashboard.notifications.password-saved")] (dom/clean-value! password-old-node) (dom/focus! password-old-node) (st/emit! (msg/success msg)))) (defn- on-submit [form event] (dom/prevent-default event) (let [params (with-meta (:clean-data @form) {:on-success (partial on-success form) :on-error (partial on-error form)})] (st/emit! (udu/update-password params)))) (s/def ::password-1 ::us/not-empty-string) (s/def ::password-2 ::us/not-empty-string) (s/def ::password-old (s/nilable ::us/string)) (defn- password-equality [errors data] (let [password-1 (:password-1 data) password-2 (:password-2 data)] (cond-> errors (and password-1 password-2 (not= password-1 password-2)) (assoc :password-2 {:message (tr "errors.password-invalid-confirmation")}) (and password-1 (> 8 (count password-1))) (assoc :password-1 {:message (tr "errors.password-too-short")})))) (s/def ::password-form (s/keys :req-un [::password-1 ::password-2 ::password-old])) (mf/defc password-form [{:keys [locale] :as props}] (let [initial (mf/use-memo (constantly {:password-old nil})) form (fm/use-form :spec ::password-form :validators [(fm/validate-not-all-spaces :password-old (tr "auth.password-not-empty")) (fm/validate-not-empty :password-1 (tr "auth.password-not-empty")) (fm/validate-not-empty :password-2 (tr "auth.password-not-empty")) password-equality] :initial initial)] [:& fm/form {:class (stl/css :password-form) :on-submit on-submit :form form} [:div {:class (stl/css :fields-row)} [:& fm/input {:type "password" :name :password-old :auto-focus? true :label (t locale "labels.old-password")}]] [:div {:class (stl/css :fields-row)} [:& fm/input {:type "password" :name :password-1 :show-success? true :label (t locale "labels.new-password")}]] [:div {:class (stl/css :fields-row)} [:& fm/input {:type "password" :name :password-2 :show-success? true :label (t locale "labels.confirm-password")}]] [:> fm/submit-button* {:label (t locale "dashboard.password-change") :data-testid "submit-password" :class (stl/css :update-btn)}]])) ;; --- Password Page (mf/defc password-page [{:keys [locale]}] (mf/use-effect #(dom/set-html-title (tr "title.settings.password"))) [:section {:class (stl/css :dashboard-settings)} [:div {:class (stl/css :form-container)} [:h2 (t locale "dashboard.password-change")] [:& password-form {:locale locale}]]])