mirror of
https://github.com/status-im/status-react.git
synced 2025-01-25 18:29:37 +00:00
Change password inside new settings (#19474)
* feat: added change-password screen Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: pw verification error not shown Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * feat: added changing password with confirmation and loading Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: adjusted flow Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: added minimum waiting time when loading Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * ref: moved events to change-password Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: added styles where missing Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * ref: moved header out Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * ref: moved forms into separate namespaces Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: linter promesa alias issue Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * feat: added password-tips quo-component Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: validation message Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: removed bottom-sheet event Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * removed temp file Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: addressed review comments Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: addressed @seanstrom's review comments Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: address @ilmotta's review comments Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: addressed @vkjr's review comments Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: buttom button alignment with keyboard Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: addressed review comments Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: keyboard behavior Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: navigation to loader Signed-off-by: Lungu Cristian <lungucristian95@gmail.com> * fix: use-theme usage * fix: button alignment due to alert banner --------- Signed-off-by: Lungu Cristian <lungucristian95@gmail.com>
This commit is contained in:
parent
245b3fcf57
commit
161ba2713f
@ -2,6 +2,7 @@
|
|||||||
(:require
|
(:require
|
||||||
["react-native" :as react-native]
|
["react-native" :as react-native]
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
|
[native-module.utils :as native-utils]
|
||||||
[react-native.platform :as platform]
|
[react-native.platform :as platform]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[utils.transforms :as types]))
|
[utils.transforms :as types]))
|
||||||
@ -543,13 +544,21 @@
|
|||||||
(when platform/android?
|
(when platform/android?
|
||||||
(.resetKeyboardInputCursor ^js (ui-helper) input selection)))
|
(.resetKeyboardInputCursor ^js (ui-helper) input selection)))
|
||||||
|
|
||||||
;; passwords are hashed
|
|
||||||
(defn reset-password
|
(defn reset-password
|
||||||
[key-uid current-password# new-password# callback]
|
([key-uid current-password-hashed new-password-hashed]
|
||||||
|
(native-utils/promisify-native-module-call reset-password
|
||||||
|
key-uid
|
||||||
|
current-password-hashed
|
||||||
|
new-password-hashed))
|
||||||
|
([key-uid current-password-hashed new-password-hashed callback]
|
||||||
(log/debug "[native-module] change-database-password")
|
(log/debug "[native-module] change-database-password")
|
||||||
(init-keystore
|
(init-keystore
|
||||||
key-uid
|
key-uid
|
||||||
#(.reEncryptDbAndKeystore ^js (encryption) key-uid current-password# new-password# callback)))
|
#(.reEncryptDbAndKeystore ^js (encryption)
|
||||||
|
key-uid
|
||||||
|
current-password-hashed
|
||||||
|
new-password-hashed
|
||||||
|
callback))))
|
||||||
|
|
||||||
(defn convert-to-keycard-account
|
(defn convert-to-keycard-account
|
||||||
[{:keys [key-uid] :as multiaccount-data} settings current-password# new-password callback]
|
[{:keys [key-uid] :as multiaccount-data} settings current-password# new-password callback]
|
||||||
|
23
src/native_module/utils.cljs
Normal file
23
src/native_module/utils.cljs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
(ns native-module.utils
|
||||||
|
(:require
|
||||||
|
[clojure.string :as string]
|
||||||
|
[promesa.core :as promesa]
|
||||||
|
[utils.transforms :as types]))
|
||||||
|
|
||||||
|
(defn- promisify-callback
|
||||||
|
[res rej]
|
||||||
|
(fn [result]
|
||||||
|
(let [native-error (let [{:keys [error]} (types/json->clj result)]
|
||||||
|
(when-not (string/blank? error)
|
||||||
|
error))]
|
||||||
|
(if native-error
|
||||||
|
(rej (ex-info "Native module call error" {:error native-error}))
|
||||||
|
(res result)))))
|
||||||
|
|
||||||
|
(defn promisify-native-module-call
|
||||||
|
[f & args]
|
||||||
|
(promesa/create
|
||||||
|
(fn [res rej]
|
||||||
|
(->> [(promisify-callback res rej)]
|
||||||
|
(concat args)
|
||||||
|
(apply f)))))
|
6
src/quo/components/password/password_tips/style.cljs
Normal file
6
src/quo/components/password/password_tips/style.cljs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
(ns quo.components.password.password-tips.style)
|
||||||
|
|
||||||
|
(def password-tips
|
||||||
|
{:flex-direction :row
|
||||||
|
:margin-horizontal 20
|
||||||
|
:justify-content :space-between})
|
30
src/quo/components/password/password_tips/view.cljs
Normal file
30
src/quo/components/password/password_tips/view.cljs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
(ns quo.components.password.password-tips.view
|
||||||
|
(:require [quo.components.password.password-tips.style :as style]
|
||||||
|
[quo.components.password.tips.view :as tips]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[schema.core :as schema]
|
||||||
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
|
(def ?schema
|
||||||
|
[:=>
|
||||||
|
[:cat
|
||||||
|
[:map {:closed true}
|
||||||
|
[:lower-case? :boolean]
|
||||||
|
[:upper-case? :boolean]
|
||||||
|
[:numbers? :boolean]
|
||||||
|
[:symbols? :boolean]]
|
||||||
|
[:any]]])
|
||||||
|
|
||||||
|
(defn- view-internal
|
||||||
|
[{:keys [lower-case? upper-case? numbers? symbols?]}]
|
||||||
|
[rn/view {:style style/password-tips}
|
||||||
|
[tips/view {:completed? lower-case?}
|
||||||
|
(i18n/label :t/password-creation-tips-1)]
|
||||||
|
[tips/view {:completed? upper-case?}
|
||||||
|
(i18n/label :t/password-creation-tips-2)]
|
||||||
|
[tips/view {:completed? numbers?}
|
||||||
|
(i18n/label :t/password-creation-tips-3)]
|
||||||
|
[tips/view {:completed? symbols?}
|
||||||
|
(i18n/label :t/password-creation-tips-4)]])
|
||||||
|
|
||||||
|
(def view (schema/instrument #'view-internal ?schema))
|
@ -37,18 +37,17 @@
|
|||||||
[{:keys [title title-accessibility-label input counter-top counter-bottom
|
[{:keys [title title-accessibility-label input counter-top counter-bottom
|
||||||
title-right title-right-props]
|
title-right title-right-props]
|
||||||
avatar-props :avatar}]
|
avatar-props :avatar}]
|
||||||
(let [avatar-props (when avatar-props
|
(let [title-props (assoc title-right-props
|
||||||
(assoc avatar-props :size :size-32))
|
|
||||||
title-props (assoc title-right-props
|
|
||||||
:title title
|
:title title
|
||||||
:right title-right
|
:right title-right
|
||||||
:accessibility-label title-accessibility-label)]
|
:accessibility-label title-accessibility-label)]
|
||||||
[rn/view {:style style/header}
|
[rn/view {:style style/header}
|
||||||
[rn/view {:style style/header-title}
|
[rn/view {:style style/header-title}
|
||||||
(when avatar-props
|
(when avatar-props
|
||||||
|
(let [avatar-props (assoc avatar-props :size :size-32)]
|
||||||
(if (:group? avatar-props)
|
(if (:group? avatar-props)
|
||||||
[group-avatar/view avatar-props]
|
[group-avatar/view avatar-props]
|
||||||
[channel-avatar/view avatar-props]))
|
[channel-avatar/view avatar-props])))
|
||||||
[standard-title/view title-props]]
|
[standard-title/view title-props]]
|
||||||
(when (= input :recovery-phrase)
|
(when (= input :recovery-phrase)
|
||||||
[header-counter counter-top counter-bottom])]))
|
[header-counter counter-top counter-bottom])]))
|
||||||
|
@ -111,6 +111,7 @@
|
|||||||
quo.components.numbered-keyboard.numbered-keyboard.view
|
quo.components.numbered-keyboard.numbered-keyboard.view
|
||||||
quo.components.onboarding.small-option-card.view
|
quo.components.onboarding.small-option-card.view
|
||||||
quo.components.overlay.view
|
quo.components.overlay.view
|
||||||
|
quo.components.password.password-tips.view
|
||||||
quo.components.password.tips.view
|
quo.components.password.tips.view
|
||||||
quo.components.profile.collectible-list-item.view
|
quo.components.profile.collectible-list-item.view
|
||||||
quo.components.profile.collectible.view
|
quo.components.profile.collectible.view
|
||||||
@ -356,6 +357,7 @@
|
|||||||
|
|
||||||
;;;; Password
|
;;;; Password
|
||||||
(def tips quo.components.password.tips.view/view)
|
(def tips quo.components.password.tips.view/view)
|
||||||
|
(def password-tips quo.components.password.password-tips.view/view)
|
||||||
|
|
||||||
;;;; Profile
|
;;;; Profile
|
||||||
(def collectible quo.components.profile.collectible.view/collectible)
|
(def collectible quo.components.profile.collectible.view/collectible)
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
|
|
||||||
(defn save-user-password!
|
(defn save-user-password!
|
||||||
[key-uid password]
|
[key-uid password]
|
||||||
(keychain/save-credentials key-uid key-uid (security/safe-unmask-data password) #()))
|
(keychain/save-credentials key-uid key-uid (security/safe-unmask-data password)))
|
||||||
|
|
||||||
(defn get-user-password!
|
(defn get-user-password!
|
||||||
[key-uid callback]
|
[key-uid callback]
|
||||||
|
@ -123,11 +123,20 @@
|
|||||||
(def ^:const profile-pictures-visibility-none 3)
|
(def ^:const profile-pictures-visibility-none 3)
|
||||||
|
|
||||||
(def ^:const min-password-length 6)
|
(def ^:const min-password-length 6)
|
||||||
|
(def ^:const new-password-min-length 10)
|
||||||
(def ^:const max-group-chat-participants 20)
|
(def ^:const max-group-chat-participants 20)
|
||||||
(def ^:const max-group-chat-name-length 24)
|
(def ^:const max-group-chat-name-length 24)
|
||||||
(def ^:const default-number-of-messages 20)
|
(def ^:const default-number-of-messages 20)
|
||||||
(def ^:const default-number-of-pin-messages 3)
|
(def ^:const default-number-of-pin-messages 3)
|
||||||
|
|
||||||
|
(def ^:const password-tips [:lower-case? :upper-case? :numbers? :symbols?])
|
||||||
|
(def ^:const strength-status
|
||||||
|
{1 :very-weak
|
||||||
|
2 :weak
|
||||||
|
3 :okay
|
||||||
|
4 :strong
|
||||||
|
5 :very-strong})
|
||||||
|
|
||||||
(def ^:const mailserver-password "status-offline-inbox")
|
(def ^:const mailserver-password "status-offline-inbox")
|
||||||
|
|
||||||
(def ^:const send-transaction-failed-parse-response 1)
|
(def ^:const send-transaction-failed-parse-response 1)
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.safe-area :as safe-area]
|
[react-native.safe-area :as safe-area]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
|
[status-im.constants :as constants]
|
||||||
[status-im.contexts.onboarding.create-password.style :as style]
|
[status-im.contexts.onboarding.create-password.style :as style]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
@ -80,18 +81,11 @@
|
|||||||
:on-focus on-input-focus
|
:on-focus on-input-focus
|
||||||
:on-blur on-blur-repeat-password}]]))
|
:on-blur on-blur-repeat-password}]]))
|
||||||
|
|
||||||
(def strength-status
|
|
||||||
{1 :very-weak
|
|
||||||
2 :weak
|
|
||||||
3 :okay
|
|
||||||
4 :strong
|
|
||||||
5 :very-strong})
|
|
||||||
|
|
||||||
(defn help
|
(defn help
|
||||||
[{{:keys [lower-case? upper-case? numbers? symbols?]} :validations
|
[{{:keys [lower-case? upper-case? numbers? symbols?]} :validations
|
||||||
password-strength :password-strength}]
|
password-strength :password-strength}]
|
||||||
[rn/view
|
[rn/view
|
||||||
[quo/strength-divider {:type (strength-status password-strength :info)}
|
[quo/strength-divider {:type (constants/strength-status password-strength :info)}
|
||||||
(i18n/label :t/password-creation-tips-title)]
|
(i18n/label :t/password-creation-tips-title)]
|
||||||
[rn/view {:style style/password-tips}
|
[rn/view {:style style/password-tips}
|
||||||
[quo/tips {:completed? lower-case?}
|
[quo/tips {:completed? lower-case?}
|
||||||
@ -109,16 +103,16 @@
|
|||||||
utils.string/has-upper-case?
|
utils.string/has-upper-case?
|
||||||
utils.string/has-numbers?
|
utils.string/has-numbers?
|
||||||
utils.string/has-symbols?
|
utils.string/has-symbols?
|
||||||
#(utils.string/at-least-n-chars? % 10))]
|
#(utils.string/at-least-n-chars? % constants/new-password-min-length))]
|
||||||
(->> password
|
(->> password
|
||||||
(validations)
|
validations
|
||||||
(zipmap [:lower-case? :upper-case? :numbers? :symbols? :long-enough?]))))
|
(zipmap (conj constants/password-tips :long-enough?)))))
|
||||||
|
|
||||||
(defn calc-password-strength
|
(defn calc-password-strength
|
||||||
[validations]
|
[validations]
|
||||||
(->> (vals validations)
|
(->> (vals validations)
|
||||||
(filter true?)
|
(filter true?)
|
||||||
(count)))
|
count))
|
||||||
|
|
||||||
(defn password-form
|
(defn password-form
|
||||||
[]
|
[]
|
||||||
|
@ -136,6 +136,7 @@
|
|||||||
numbered-keyboard]
|
numbered-keyboard]
|
||||||
[status-im.contexts.preview.quo.onboarding.small-option-card :as
|
[status-im.contexts.preview.quo.onboarding.small-option-card :as
|
||||||
small-option-card]
|
small-option-card]
|
||||||
|
[status-im.contexts.preview.quo.password.password-tips :as password-tips]
|
||||||
[status-im.contexts.preview.quo.password.tips :as tips]
|
[status-im.contexts.preview.quo.password.tips :as tips]
|
||||||
[status-im.contexts.preview.quo.profile.collectible :as collectible]
|
[status-im.contexts.preview.quo.profile.collectible :as collectible]
|
||||||
[status-im.contexts.preview.quo.profile.collectible-list-item :as collectible-list-item]
|
[status-im.contexts.preview.quo.profile.collectible-list-item :as collectible-list-item]
|
||||||
@ -425,7 +426,9 @@
|
|||||||
:onboarding [{:name :small-option-card
|
:onboarding [{:name :small-option-card
|
||||||
:component small-option-card/view}]
|
:component small-option-card/view}]
|
||||||
:password [{:name :tips
|
:password [{:name :tips
|
||||||
:component tips/view}]
|
:component tips/view}
|
||||||
|
{:name :password-tips
|
||||||
|
:component password-tips/view}]
|
||||||
:profile [{:name :collectible
|
:profile [{:name :collectible
|
||||||
:component collectible/view}
|
:component collectible/view}
|
||||||
{:name :collectible-list-item
|
{:name :collectible-list-item
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
(ns status-im.contexts.preview.quo.password.password-tips
|
||||||
|
(:require
|
||||||
|
[quo.core :as quo]
|
||||||
|
[quo.foundations.colors :as colors]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[status-im.constants :as constant]
|
||||||
|
[status-im.contexts.preview.quo.preview :as preview]))
|
||||||
|
|
||||||
|
(def init-state
|
||||||
|
(reduce (fn [acc tip] (assoc acc tip false)) {} constant/password-tips))
|
||||||
|
|
||||||
|
(defn- make-tip-descriptor
|
||||||
|
[tip]
|
||||||
|
{:key tip
|
||||||
|
:type :boolean})
|
||||||
|
|
||||||
|
(def descriptor
|
||||||
|
(map make-tip-descriptor constant/password-tips))
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[]
|
||||||
|
(let [state (reagent/atom init-state)]
|
||||||
|
(fn []
|
||||||
|
[preview/preview-container
|
||||||
|
{:state state
|
||||||
|
:descriptor descriptor
|
||||||
|
:component-container-style {:padding 20
|
||||||
|
:background-color colors/neutral-95}}
|
||||||
|
[quo/password-tips @state]])))
|
@ -23,7 +23,7 @@
|
|||||||
:blur? true
|
:blur? true
|
||||||
:action :arrow}
|
:action :arrow}
|
||||||
{:title (i18n/label :t/password)
|
{:title (i18n/label :t/password)
|
||||||
:on-press #(rf/dispatch [:open-modal :settings-password])
|
:on-press #(rf/dispatch [:open-modal :screen/settings-password])
|
||||||
:image-props :i/password
|
:image-props :i/password
|
||||||
:image :icon
|
:image :icon
|
||||||
:blur? true
|
:blur? true
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
(ns status-im.contexts.profile.settings.screens.password.change-password.effects
|
||||||
|
(:require [native-module.core :as native-module]
|
||||||
|
[promesa.core :as promesa]
|
||||||
|
[status-im.common.keychain.events :as keychain]
|
||||||
|
[utils.re-frame :as rf]
|
||||||
|
[utils.security.core :as security]))
|
||||||
|
|
||||||
|
(rf/reg-fx :effects.change-password/change-password
|
||||||
|
(fn [{:keys [key-uid old-password new-password on-success on-fail]}]
|
||||||
|
(let [hash-masked-password (fn [password]
|
||||||
|
(-> password security/hash-masked-password security/safe-unmask-data))
|
||||||
|
old-password-hashed (hash-masked-password old-password)
|
||||||
|
new-password-hashed (hash-masked-password new-password)]
|
||||||
|
(-> (native-module/reset-password key-uid old-password-hashed new-password-hashed)
|
||||||
|
(promesa/then #(keychain/save-user-password! key-uid new-password-hashed))
|
||||||
|
(promesa/then on-success)
|
||||||
|
(promesa/catch on-fail)))))
|
@ -0,0 +1,68 @@
|
|||||||
|
(ns status-im.contexts.profile.settings.screens.password.change-password.events
|
||||||
|
(:require [status-im.contexts.profile.settings.screens.password.change-password.effects]
|
||||||
|
[taoensso.timbre :as log]
|
||||||
|
[utils.re-frame :as rf]
|
||||||
|
[utils.security.core :as security]))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :change-password/verify-old-password
|
||||||
|
(fn [_ [entered-password]]
|
||||||
|
(let [hashed-password (-> entered-password
|
||||||
|
security/hash-masked-password
|
||||||
|
security/safe-unmask-data)]
|
||||||
|
{:json-rpc/call [{:method "accounts_verifyPassword"
|
||||||
|
:params [hashed-password]
|
||||||
|
:on-success (fn [valid?]
|
||||||
|
(rf/dispatch [:change-password/password-verify-success valid?
|
||||||
|
entered-password]))
|
||||||
|
:on-error (fn [error]
|
||||||
|
(log/error "accounts_verifyPassword error"
|
||||||
|
{:error error
|
||||||
|
:event :password-settings/change-password}))}]})))
|
||||||
|
(rf/reg-event-fx :change-password/password-verify-success
|
||||||
|
(fn [{:keys [db]} [valid? old-password]]
|
||||||
|
{:db (if valid?
|
||||||
|
(-> db
|
||||||
|
(assoc-in [:settings/change-password :old-password] old-password)
|
||||||
|
(assoc-in [:settings/change-password :current-step] :new-password))
|
||||||
|
(assoc-in db [:settings/change-password :verify-error] true))}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :change-password/reset-error
|
||||||
|
(fn [{:keys [db]}]
|
||||||
|
{:db (assoc-in db [:settings/change-password :verify-error] false)}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :change-password/reset
|
||||||
|
(fn [{:keys [db]}]
|
||||||
|
{:db (assoc db :settings/change-password {})}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :change-password/confirm-new-password
|
||||||
|
(fn [{:keys [db]} [new-password]]
|
||||||
|
{:db (assoc-in db [:settings/change-password :new-password] new-password)
|
||||||
|
:fx [[:dispatch [:change-password/submit]]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :change-password/submit
|
||||||
|
(fn [{:keys [db]}]
|
||||||
|
(let [key-uid (get-in db [:profile/profile :key-uid])
|
||||||
|
{:keys [new-password old-password]} (get db :settings/change-password)]
|
||||||
|
{:db (assoc-in db [:settings/change-password :loading?] true)
|
||||||
|
:fx [[:dispatch [:dismiss-keyboard]]
|
||||||
|
[:dispatch [:open-modal :screen/change-password-loading]]
|
||||||
|
[:effects.change-password/change-password
|
||||||
|
{:key-uid key-uid
|
||||||
|
:old-password old-password
|
||||||
|
:new-password new-password
|
||||||
|
:on-success (fn []
|
||||||
|
(rf/dispatch [:change-password/submit-success]))
|
||||||
|
:on-fail (fn [error]
|
||||||
|
(rf/dispatch [:change-password/submit-fail error]))}]]})))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :change-password/submit-fail
|
||||||
|
(fn [_ [error]]
|
||||||
|
(log/error "failed to change the password"
|
||||||
|
{:error error
|
||||||
|
:event :change-password/submit})
|
||||||
|
{:fx [[:dispatch [:change-password/reset]]
|
||||||
|
[:dispatch [:navigate-back]]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :change-password/submit-success
|
||||||
|
(fn [{:keys [db]}]
|
||||||
|
{:db (assoc-in db [:settings/change-password :loading?] false)}))
|
@ -0,0 +1,19 @@
|
|||||||
|
(ns status-im.contexts.profile.settings.screens.password.change-password.header
|
||||||
|
(:require [quo.core :as quo]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[status-im.contexts.profile.settings.screens.password.change-password.style :as style]
|
||||||
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[]
|
||||||
|
[rn/view {:style style/heading}
|
||||||
|
[quo/text
|
||||||
|
{:style style/heading-title
|
||||||
|
:weight :semi-bold
|
||||||
|
:size :heading-1}
|
||||||
|
(i18n/label :t/change-password)]
|
||||||
|
[quo/text
|
||||||
|
{:style style/heading-subtitle
|
||||||
|
:weight :regular
|
||||||
|
:size :paragraph-1}
|
||||||
|
(i18n/label :t/change-password-description)]])
|
@ -0,0 +1,54 @@
|
|||||||
|
(ns status-im.contexts.profile.settings.screens.password.change-password.loading
|
||||||
|
(:require [quo.core :as quo]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[react-native.safe-area :as safe-area]
|
||||||
|
[status-im.contexts.profile.settings.screens.password.change-password.style :as style]
|
||||||
|
[utils.i18n :as i18n]
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
;; NOTE: The duration of the password change depends on the device hardware, so to avoid
|
||||||
|
;; quick changes in UI when mounted, we're waiting for a bit.
|
||||||
|
(def ^:private minimum-loading-time 5000)
|
||||||
|
|
||||||
|
(defn- handle-logout
|
||||||
|
[]
|
||||||
|
(rf/dispatch [:multiaccounts.logout.ui/logout-pressed])
|
||||||
|
(rf/dispatch [:change-password/reset]))
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[]
|
||||||
|
(let [insets (safe-area/get-insets)
|
||||||
|
[minimum-loading-timeout-done?
|
||||||
|
set-minimum-loading-timeout-done] (rn/use-state false)
|
||||||
|
loading? (rf/sub [:settings/change-password-loading])
|
||||||
|
done? (and (not loading?) minimum-loading-timeout-done?)]
|
||||||
|
(rn/use-mount (fn []
|
||||||
|
(js/setTimeout
|
||||||
|
#(set-minimum-loading-timeout-done true)
|
||||||
|
minimum-loading-time)))
|
||||||
|
[quo/overlay {:type :shell}
|
||||||
|
[rn/view
|
||||||
|
{:key :change-password-loading
|
||||||
|
:style (style/loading-container insets)}
|
||||||
|
[quo/page-nav]
|
||||||
|
[quo/page-top
|
||||||
|
{:description :text
|
||||||
|
:title (if done?
|
||||||
|
(i18n/label :t/change-password-done-header)
|
||||||
|
(i18n/label :t/change-password-loading-header))
|
||||||
|
:description-text (if done?
|
||||||
|
(i18n/label :t/change-password-done-description)
|
||||||
|
(i18n/label :t/change-password-loading-description))}]
|
||||||
|
[rn/view
|
||||||
|
{:style style/loading-content}
|
||||||
|
(when-not done?
|
||||||
|
[quo/information-box
|
||||||
|
{:type :error
|
||||||
|
:style {:margin-top 12}
|
||||||
|
:icon :i/info}
|
||||||
|
(i18n/label :t/change-password-loading-warning)])]
|
||||||
|
(when done?
|
||||||
|
[quo/logout-button
|
||||||
|
{:container-style style/logout-container
|
||||||
|
:on-press handle-logout}])]]))
|
||||||
|
|
@ -0,0 +1,157 @@
|
|||||||
|
(ns status-im.contexts.profile.settings.screens.password.change-password.new-password-form
|
||||||
|
(:require
|
||||||
|
[clojure.string :as string]
|
||||||
|
[quo.core :as quo]
|
||||||
|
[quo.foundations.colors :as colors]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[status-im.constants :as constant]
|
||||||
|
[status-im.contexts.profile.settings.screens.password.change-password.events]
|
||||||
|
[status-im.contexts.profile.settings.screens.password.change-password.header :as header]
|
||||||
|
[status-im.contexts.profile.settings.screens.password.change-password.style :as style]
|
||||||
|
[utils.i18n :as i18n]
|
||||||
|
[utils.re-frame :as rf]
|
||||||
|
[utils.security.core :as security]
|
||||||
|
[utils.string :as utils.string]))
|
||||||
|
|
||||||
|
(defn- password-with-hint
|
||||||
|
[{{:keys [text status shown?]} :hint :as input-props}]
|
||||||
|
[:<>
|
||||||
|
[quo/input
|
||||||
|
(-> input-props
|
||||||
|
(dissoc :hint)
|
||||||
|
(assoc :type :password
|
||||||
|
:blur? true))]
|
||||||
|
[rn/view {:style style/info-message}
|
||||||
|
(when shown?
|
||||||
|
[quo/info-message
|
||||||
|
(cond-> {:type status
|
||||||
|
:size :default}
|
||||||
|
(not= :success status) (assoc :icon :i/info)
|
||||||
|
(= :success status) (assoc :icon :i/positive-state)
|
||||||
|
(= :default status) (assoc :text-color colors/white-70-blur
|
||||||
|
:icon-color colors/white-70-blur))
|
||||||
|
text])]])
|
||||||
|
|
||||||
|
(defn- calc-password-strength
|
||||||
|
[validations]
|
||||||
|
(->> (vals validations)
|
||||||
|
(filter true?)
|
||||||
|
count))
|
||||||
|
|
||||||
|
(defn- help
|
||||||
|
[{:keys [validations]}]
|
||||||
|
(let [{:keys [lower-case? upper-case? numbers? symbols?]} validations
|
||||||
|
password-strength (calc-password-strength validations)]
|
||||||
|
[rn/view
|
||||||
|
[quo/strength-divider {:type (constant/strength-status password-strength :info)}
|
||||||
|
(i18n/label :t/password-creation-tips-title)]
|
||||||
|
[rn/view {:style style/password-tips}
|
||||||
|
[quo/tips {:completed? lower-case?}
|
||||||
|
(i18n/label :t/password-creation-tips-1)]
|
||||||
|
[quo/tips {:completed? upper-case?}
|
||||||
|
(i18n/label :t/password-creation-tips-2)]
|
||||||
|
[quo/tips {:completed? numbers?}
|
||||||
|
(i18n/label :t/password-creation-tips-3)]
|
||||||
|
[quo/tips {:completed? symbols?}
|
||||||
|
(i18n/label :t/password-creation-tips-4)]]]))
|
||||||
|
|
||||||
|
(defn- password-validations
|
||||||
|
[password]
|
||||||
|
{:lower-case? (utils.string/has-lower-case? password)
|
||||||
|
:upper-case? (utils.string/has-upper-case? password)
|
||||||
|
:numbers? (utils.string/has-numbers? password)
|
||||||
|
:symbols? (utils.string/has-symbols? password)})
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[]
|
||||||
|
(let [customization-color (rf/sub [:profile/customization-color])
|
||||||
|
[password set-password] (rn/use-state "")
|
||||||
|
[repeat-password set-repeat-password] (rn/use-state "")
|
||||||
|
[disclaimer-accepted? set-disclaimer-accepted] (rn/use-state false)
|
||||||
|
[focused? set-focused] (rn/use-state false)
|
||||||
|
[show-validation? set-show-validation] (rn/use-state false)
|
||||||
|
|
||||||
|
;; validations
|
||||||
|
not-blank? (complement string/blank?)
|
||||||
|
validations (password-validations password)
|
||||||
|
long-enough? (utils.string/at-least-n-chars?
|
||||||
|
password
|
||||||
|
constant/new-password-min-length)
|
||||||
|
empty-password? (string/blank? password)
|
||||||
|
same-passwords? (and (not empty-password?)
|
||||||
|
(= password repeat-password))
|
||||||
|
meet-requirements? (and (not empty-password?)
|
||||||
|
long-enough?
|
||||||
|
same-passwords?
|
||||||
|
disclaimer-accepted?)
|
||||||
|
error? (and show-validation?
|
||||||
|
(not same-passwords?)
|
||||||
|
(not empty-password?))
|
||||||
|
|
||||||
|
;; handlers
|
||||||
|
on-change-password (fn [new-value]
|
||||||
|
(set-password new-value)
|
||||||
|
(when (and (not-blank? new-value)
|
||||||
|
(= (count new-value)
|
||||||
|
(count repeat-password)))
|
||||||
|
(set-show-validation true)))
|
||||||
|
on-change-repeat-password (fn [new-value]
|
||||||
|
(set-repeat-password new-value)
|
||||||
|
(when (and (not-blank? new-value)
|
||||||
|
(= (count new-value)
|
||||||
|
(count password)))
|
||||||
|
(set-show-validation true)))
|
||||||
|
on-blur-repeat-password (fn []
|
||||||
|
(if empty-password?
|
||||||
|
(set-show-validation false)
|
||||||
|
(set-show-validation true)))
|
||||||
|
on-input-focus (fn [] (set-focused true))
|
||||||
|
on-disclaimer-change (fn []
|
||||||
|
(set-disclaimer-accepted
|
||||||
|
(not disclaimer-accepted?)))
|
||||||
|
on-submit (fn []
|
||||||
|
(rf/dispatch
|
||||||
|
[:change-password/confirm-new-password
|
||||||
|
(security/mask-data password)]))]
|
||||||
|
[:<>
|
||||||
|
[rn/scroll-view {:style style/form-container}
|
||||||
|
[header/view]
|
||||||
|
[password-with-hint
|
||||||
|
{:hint {:text (i18n/label :t/password-creation-hint)
|
||||||
|
:status (if long-enough? :success :default)
|
||||||
|
:shown? true}
|
||||||
|
:placeholder (i18n/label :t/change-password-new-password-placeholder)
|
||||||
|
:label (i18n/label :t/change-password-new-password-label)
|
||||||
|
:on-change-text on-change-password
|
||||||
|
:on-focus on-input-focus
|
||||||
|
:auto-focus true}]
|
||||||
|
[rn/view {:style style/space-between-inputs}]
|
||||||
|
[password-with-hint
|
||||||
|
{:hint {:text (if same-passwords?
|
||||||
|
(i18n/label :t/password-creation-match)
|
||||||
|
(i18n/label :t/password-creation-dont-match))
|
||||||
|
:status (if same-passwords? :success :error)
|
||||||
|
:shown? (and (not empty-password?)
|
||||||
|
show-validation?)}
|
||||||
|
:error? error?
|
||||||
|
:placeholder (i18n/label :t/change-password-repeat-password-placeholder)
|
||||||
|
:on-change-text on-change-repeat-password
|
||||||
|
:on-focus on-input-focus
|
||||||
|
:on-blur on-blur-repeat-password}]]
|
||||||
|
[rn/view {:style style/bottom-part}
|
||||||
|
(when same-passwords?
|
||||||
|
[rn/view {:style style/disclaimer-container}
|
||||||
|
[quo/disclaimer
|
||||||
|
{:blur? true
|
||||||
|
:on-change on-disclaimer-change
|
||||||
|
:checked? disclaimer-accepted?}
|
||||||
|
(i18n/label :t/password-creation-disclaimer)]])
|
||||||
|
(when (and focused? (not same-passwords?))
|
||||||
|
[help
|
||||||
|
{:validations validations}])
|
||||||
|
[rn/view {:style style/button-container}
|
||||||
|
[quo/button
|
||||||
|
{:disabled? (not meet-requirements?)
|
||||||
|
:customization-color customization-color
|
||||||
|
:on-press on-submit}
|
||||||
|
(i18n/label :t/password-creation-confirm)]]]]))
|
@ -0,0 +1,63 @@
|
|||||||
|
(ns status-im.contexts.profile.settings.screens.password.change-password.old-password-form
|
||||||
|
(:require
|
||||||
|
[clojure.string :as string]
|
||||||
|
[quo.core :as quo]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[status-im.constants :as constant]
|
||||||
|
[status-im.contexts.profile.settings.screens.password.change-password.events]
|
||||||
|
[status-im.contexts.profile.settings.screens.password.change-password.header :as header]
|
||||||
|
[status-im.contexts.profile.settings.screens.password.change-password.style :as style]
|
||||||
|
[utils.i18n :as i18n]
|
||||||
|
[utils.re-frame :as rf]
|
||||||
|
[utils.security.core :as security]
|
||||||
|
[utils.string :as utils.string]))
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[]
|
||||||
|
(let [error (rf/sub [:settings/change-password-error])
|
||||||
|
customization-color (rf/sub [:profile/customization-color])
|
||||||
|
[password set-password] (rn/use-state "")
|
||||||
|
on-change-password (fn [new-value]
|
||||||
|
(when error
|
||||||
|
(rf/dispatch [:change-password/reset-error]))
|
||||||
|
(set-password new-value))
|
||||||
|
meet-requirements? (and ((complement string/blank?) password)
|
||||||
|
(utils.string/at-least-n-chars? password
|
||||||
|
constant/min-password-length))
|
||||||
|
on-submit (fn []
|
||||||
|
(when meet-requirements?
|
||||||
|
(rf/dispatch
|
||||||
|
[:change-password/verify-old-password
|
||||||
|
(security/mask-data password)])))]
|
||||||
|
[:<>
|
||||||
|
[rn/scroll-view {:content-container-style style/form-container}
|
||||||
|
[header/view]
|
||||||
|
[quo/input
|
||||||
|
{:placeholder (i18n/label :t/change-password-old-password-placeholder)
|
||||||
|
:label (i18n/label :t/change-password-old-password-label)
|
||||||
|
:on-change-text on-change-password
|
||||||
|
:auto-focus true
|
||||||
|
:type :password
|
||||||
|
:blur? true}]
|
||||||
|
[rn/view
|
||||||
|
{:style style/error-container}
|
||||||
|
(when error
|
||||||
|
[quo/info-message
|
||||||
|
{:type :error
|
||||||
|
:size :default
|
||||||
|
:icon :i/info}
|
||||||
|
(i18n/label :t/oops-wrong-password)])]
|
||||||
|
[quo/information-box
|
||||||
|
{:type :error
|
||||||
|
:style style/warning-container
|
||||||
|
:icon :i/info}
|
||||||
|
(i18n/label :t/change-password-confirm-warning)]]
|
||||||
|
[rn/view
|
||||||
|
{:style (assoc style/bottom-part
|
||||||
|
:margin-horizontal 20
|
||||||
|
:margin-top 12)}
|
||||||
|
[quo/button
|
||||||
|
{:disabled? (not meet-requirements?)
|
||||||
|
:customization-color customization-color
|
||||||
|
:on-press on-submit}
|
||||||
|
(i18n/label :t/continue)]]]))
|
@ -0,0 +1,60 @@
|
|||||||
|
(ns status-im.contexts.profile.settings.screens.password.change-password.style
|
||||||
|
(:require
|
||||||
|
[quo.foundations.colors :as colors]
|
||||||
|
[react-native.safe-area :as safe-area]))
|
||||||
|
|
||||||
|
(def form-container
|
||||||
|
{:margin-horizontal 20})
|
||||||
|
|
||||||
|
(def heading
|
||||||
|
{:margin-bottom 20
|
||||||
|
:margin-top 12})
|
||||||
|
|
||||||
|
(def heading-subtitle {:color colors/white})
|
||||||
|
|
||||||
|
(def heading-title (assoc heading-subtitle :margin-bottom 8))
|
||||||
|
|
||||||
|
(def info-message
|
||||||
|
{:margin-top 8})
|
||||||
|
|
||||||
|
(def space-between-inputs {:height 16})
|
||||||
|
|
||||||
|
(def error-container
|
||||||
|
{:margin-top 8
|
||||||
|
:flex-direction :row
|
||||||
|
:align-items :center})
|
||||||
|
|
||||||
|
(def warning-container
|
||||||
|
{:margin-top 12})
|
||||||
|
|
||||||
|
(defn loading-container
|
||||||
|
[{:keys [top bottom]}]
|
||||||
|
{:flex 1
|
||||||
|
:justify-content :space-between
|
||||||
|
:padding-top top
|
||||||
|
:padding-bottom bottom})
|
||||||
|
|
||||||
|
(def loading-content
|
||||||
|
{:flex 1
|
||||||
|
:padding-horizontal 20})
|
||||||
|
|
||||||
|
(def logout-container
|
||||||
|
{:margin-vertical 12
|
||||||
|
:margin-horizontal 20})
|
||||||
|
|
||||||
|
(def password-tips
|
||||||
|
{:flex-direction :row
|
||||||
|
:margin-horizontal 20
|
||||||
|
:justify-content :space-between})
|
||||||
|
|
||||||
|
(def bottom-part
|
||||||
|
{:margin-bottom (- (safe-area/get-bottom) 12)
|
||||||
|
:justify-content :flex-end})
|
||||||
|
|
||||||
|
(def disclaimer-container
|
||||||
|
{:margin-horizontal 20
|
||||||
|
:margin-vertical 4})
|
||||||
|
|
||||||
|
(def button-container
|
||||||
|
{:margin-top 12
|
||||||
|
:margin-horizontal 20})
|
@ -0,0 +1,40 @@
|
|||||||
|
(ns status-im.contexts.profile.settings.screens.password.change-password.view
|
||||||
|
(:require
|
||||||
|
[quo.core :as quo]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[react-native.platform :as platform]
|
||||||
|
[react-native.safe-area :as safe-area]
|
||||||
|
[status-im.contexts.profile.settings.screens.password.change-password.events]
|
||||||
|
[status-im.contexts.profile.settings.screens.password.change-password.new-password-form :as
|
||||||
|
new-password-form]
|
||||||
|
[status-im.contexts.profile.settings.screens.password.change-password.old-password-form :as
|
||||||
|
old-password-form]
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(defn- navigate-back
|
||||||
|
[]
|
||||||
|
(rf/dispatch [:navigate-back]))
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[]
|
||||||
|
(let [{:keys [top]} (safe-area/get-insets)
|
||||||
|
alert-banners-top-margin (rf/sub [:alert-banners/top-margin])
|
||||||
|
current-step (rf/sub [:settings/change-password-current-step])]
|
||||||
|
(rn/use-unmount #(rf/dispatch [:change-password/reset]))
|
||||||
|
[quo/overlay {:type :shell}
|
||||||
|
[rn/pressable
|
||||||
|
{:key :change-password
|
||||||
|
:on-press rn/dismiss-keyboard!
|
||||||
|
:accessible false
|
||||||
|
:style {:flex 1}}
|
||||||
|
[quo/page-nav
|
||||||
|
{:margin-top top
|
||||||
|
:background :blur
|
||||||
|
:icon-name :i/arrow-left
|
||||||
|
:on-press navigate-back}]
|
||||||
|
[rn/keyboard-avoiding-view
|
||||||
|
{:style {:flex 1}
|
||||||
|
:keyboardVerticalOffset (if platform/ios? alert-banners-top-margin 0)}
|
||||||
|
(condp = current-step
|
||||||
|
:old-password [old-password-form/view]
|
||||||
|
:new-password [new-password-form/view])]]]))
|
@ -2,8 +2,6 @@
|
|||||||
(:require [quo.core :as quo]
|
(:require [quo.core :as quo]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[status-im.common.biometric.utils :as biometric]
|
[status-im.common.biometric.utils :as biometric]
|
||||||
[status-im.common.not-implemented :as not-implemented]
|
|
||||||
[status-im.config :as config]
|
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
@ -47,13 +45,12 @@
|
|||||||
|
|
||||||
(defn- get-change-password-item
|
(defn- get-change-password-item
|
||||||
[]
|
[]
|
||||||
(when config/show-not-implemented-features?
|
|
||||||
{:title (i18n/label :t/change-password)
|
{:title (i18n/label :t/change-password)
|
||||||
:on-press not-implemented/alert
|
:on-press #(rf/dispatch [:open-modal :screen/change-password])
|
||||||
:blur? true
|
:blur? true
|
||||||
:image :icon
|
:image :icon
|
||||||
:image-props :i/password
|
:image-props :i/password
|
||||||
:action :arrow}))
|
:action :arrow})
|
||||||
|
|
||||||
(defn- navigate-back
|
(defn- navigate-back
|
||||||
[]
|
[]
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
:registry {}
|
:registry {}
|
||||||
:visibility-status-updates {}
|
:visibility-status-updates {}
|
||||||
:stickers/packs-pending #{}
|
:stickers/packs-pending #{}
|
||||||
|
:settings/change-password {}
|
||||||
:keycard {:nfc-enabled? false
|
:keycard {:nfc-enabled? false
|
||||||
:pin {:original []
|
:pin {:original []
|
||||||
:confirmation []
|
:confirmation []
|
||||||
|
@ -52,6 +52,9 @@
|
|||||||
[status-im.contexts.profile.settings.screens.messages.blocked-users.view :as
|
[status-im.contexts.profile.settings.screens.messages.blocked-users.view :as
|
||||||
settings.blocked-users]
|
settings.blocked-users]
|
||||||
[status-im.contexts.profile.settings.screens.messages.view :as settings.messages]
|
[status-im.contexts.profile.settings.screens.messages.view :as settings.messages]
|
||||||
|
[status-im.contexts.profile.settings.screens.password.change-password.loading :as
|
||||||
|
change-password-loading]
|
||||||
|
[status-im.contexts.profile.settings.screens.password.change-password.view :as change-password]
|
||||||
[status-im.contexts.profile.settings.screens.password.view :as settings-password]
|
[status-im.contexts.profile.settings.screens.password.view :as settings-password]
|
||||||
[status-im.contexts.profile.settings.view :as settings]
|
[status-im.contexts.profile.settings.view :as settings]
|
||||||
[status-im.contexts.settings.wallet.saved-addresses.view :as saved-addresses-settings]
|
[status-im.contexts.settings.wallet.saved-addresses.view :as saved-addresses-settings]
|
||||||
@ -485,7 +488,7 @@
|
|||||||
|
|
||||||
;; Settings
|
;; Settings
|
||||||
|
|
||||||
{:name :settings-password
|
{:name :screen/settings-password
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component settings-password/view}
|
:component settings-password/view}
|
||||||
|
|
||||||
@ -503,7 +506,20 @@
|
|||||||
|
|
||||||
{:name :screen/settings-blocked-users
|
{:name :screen/settings-blocked-users
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component settings.blocked-users/view}]
|
:component settings.blocked-users/view}
|
||||||
|
|
||||||
|
{:name :screen/change-password
|
||||||
|
:options (assoc options/transparent-modal-screen-options :theme :dark)
|
||||||
|
:component change-password/view}
|
||||||
|
|
||||||
|
{:name :screen/change-password-loading
|
||||||
|
:options (assoc
|
||||||
|
options/transparent-modal-screen-options
|
||||||
|
:theme :dark
|
||||||
|
:popGesture false
|
||||||
|
:hardwareBackButton {:dismissModalOnPress false
|
||||||
|
:popStackOnPress false})
|
||||||
|
:component change-password-loading/view}]
|
||||||
|
|
||||||
[{:name :shell
|
[{:name :shell
|
||||||
:options {:theme :dark}}]
|
:options {:theme :dark}}]
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
status-im.subs.onboarding
|
status-im.subs.onboarding
|
||||||
status-im.subs.pairing
|
status-im.subs.pairing
|
||||||
status-im.subs.profile
|
status-im.subs.profile
|
||||||
|
status-im.subs.settings
|
||||||
status-im.subs.shell
|
status-im.subs.shell
|
||||||
status-im.subs.wallet.activities
|
status-im.subs.wallet.activities
|
||||||
status-im.subs.wallet.collectibles
|
status-im.subs.wallet.collectibles
|
||||||
@ -167,6 +168,9 @@
|
|||||||
;;biometrics
|
;;biometrics
|
||||||
(reg-root-key-sub :biometrics :biometrics)
|
(reg-root-key-sub :biometrics :biometrics)
|
||||||
|
|
||||||
|
;;settings
|
||||||
|
(reg-root-key-sub :settings/change-password :settings/change-password)
|
||||||
|
|
||||||
;;debug
|
;;debug
|
||||||
(when js/goog.DEBUG
|
(when js/goog.DEBUG
|
||||||
(reg-root-key-sub :dev/previewed-component :dev/previewed-component))
|
(reg-root-key-sub :dev/previewed-component :dev/previewed-component))
|
||||||
|
17
src/status_im/subs/settings.cljs
Normal file
17
src/status_im/subs/settings.cljs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
(ns status-im.subs.settings
|
||||||
|
(:require [re-frame.core :as rf]))
|
||||||
|
|
||||||
|
(rf/reg-sub :settings/change-password-current-step
|
||||||
|
:<- [:settings/change-password]
|
||||||
|
(fn [change-password]
|
||||||
|
(or (get change-password :current-step) :old-password)))
|
||||||
|
|
||||||
|
(rf/reg-sub :settings/change-password-loading
|
||||||
|
:<- [:settings/change-password]
|
||||||
|
(fn [change-password]
|
||||||
|
(get change-password :loading?)))
|
||||||
|
|
||||||
|
(rf/reg-sub :settings/change-password-error
|
||||||
|
:<- [:settings/change-password]
|
||||||
|
(fn [change-password]
|
||||||
|
(get change-password :verify-error)))
|
@ -146,6 +146,19 @@
|
|||||||
"change-logging-enabled": "Are you sure you want to {{enable}} logging?",
|
"change-logging-enabled": "Are you sure you want to {{enable}} logging?",
|
||||||
"change-passcode": "Change Passcode",
|
"change-passcode": "Change Passcode",
|
||||||
"change-password": "Change password",
|
"change-password": "Change password",
|
||||||
|
"change-password-confirm-description": "Your data must now be re-encrypted with your new password. Please do not quit the app or turn off your device.",
|
||||||
|
"change-password-confirm-warning": "Re-encrypting data after changing password may take up to 3 min. Closing the app or locking phone while re-encryption is in progress will lead to data corruption and loss of your Status profile.",
|
||||||
|
"change-password-description": "Change password used to log in to Status and sign transactions",
|
||||||
|
"change-password-loading-header": "Keep app open on screen!",
|
||||||
|
"change-password-loading-description": "Data is now being re-encrypted with your new password, this may take up to 3min.",
|
||||||
|
"change-password-done-header": "Re-encryption complete!",
|
||||||
|
"change-password-done-description": "Please log out Status and log in using your new password",
|
||||||
|
"change-password-loading-warning": "Do not quit the app or turn off your device while in-progress.\n \nClosing the app or locking your phone while re-encryption is taking place will lead to data corruption and the loss of your Status profile.",
|
||||||
|
"change-password-new-password-label": "New password",
|
||||||
|
"change-password-new-password-placeholder": "Enter new password",
|
||||||
|
"change-password-old-password-label": "Current password",
|
||||||
|
"change-password-old-password-placeholder": "Enter current password",
|
||||||
|
"change-password-repeat-password-placeholder": "Repeat new password",
|
||||||
"change-pin": "Change 6-digit passcode",
|
"change-pin": "Change 6-digit passcode",
|
||||||
"change-puk": "Change 12-digit PUK",
|
"change-puk": "Change 12-digit PUK",
|
||||||
"change-pairing": "Change pairing code",
|
"change-pairing": "Change pairing code",
|
||||||
@ -1211,7 +1224,9 @@
|
|||||||
"puk-mismatch": "Wrong PUK code",
|
"puk-mismatch": "Wrong PUK code",
|
||||||
"quiet-days": "{{quiet-days}} days",
|
"quiet-days": "{{quiet-days}} days",
|
||||||
"quiet-hours": "{{quiet-hours}} hours",
|
"quiet-hours": "{{quiet-hours}} hours",
|
||||||
|
"re-encrypt": "Re-encrypt",
|
||||||
"re-encrypt-key": "Re-encrypt your keys",
|
"re-encrypt-key": "Re-encrypt your keys",
|
||||||
|
"re-encrypt-data": "Re-encrypt your data",
|
||||||
"receive": "Receive",
|
"receive": "Receive",
|
||||||
"receive-transaction": "Receive transaction",
|
"receive-transaction": "Receive transaction",
|
||||||
"recent": "Recent",
|
"recent": "Recent",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user