Allow to enter bip39 password on account recovery

This commit is contained in:
Roman Volosovskyi 2021-05-05 09:41:42 +03:00
parent ec528f98cc
commit a7660754fb
No known key found for this signature in database
GPG Key ID: 0238A4B5ECEE70DE
5 changed files with 86 additions and 47 deletions

View File

@ -37,6 +37,7 @@
:Linking {} :Linking {}
:TouchableWithoutFeedback {} :TouchableWithoutFeedback {}
:TouchableHighlight {} :TouchableHighlight {}
:Pressable {}
:TouchableOpacity {} :TouchableOpacity {}
:ActivityIndicator {} :ActivityIndicator {}
:StyleSheet {:create (fn [])} :StyleSheet {:create (fn [])}

View File

@ -163,7 +163,8 @@
(popover/show-popover cofx {:view :custom-seed-phrase}) (popover/show-popover cofx {:view :custom-seed-phrase})
(when (mnemonic/valid-length? passphrase) (when (mnemonic/valid-length? passphrase)
{::import-multiaccount {:passphrase (mnemonic/sanitize-passphrase passphrase) {::import-multiaccount {:passphrase (mnemonic/sanitize-passphrase passphrase)
:password password :password (when password
(security/safe-unmask-data password))
:success-event ::import-multiaccount-success}})))) :success-event ::import-multiaccount-success}}))))
(fx/defn seed-phrase-next-pressed (fx/defn seed-phrase-next-pressed
@ -263,3 +264,10 @@
(set-phrase input) (set-phrase input)
(count-words) (count-words)
(run-validation))) (run-validation)))
(fx/defn enter-passphrase-input-changed
{:events [:multiaccounts.recover/enter-passphrase-input-changed]}
[{:keys [db]} masked-passphrase]
{:db (update db :intro-wizard assoc
:password masked-passphrase
:password-error nil)})

View File

@ -53,6 +53,7 @@
[switch-class props]) [switch-class props])
(def touchable-highlight-class (reagent/adapt-react-class (.-TouchableHighlight react-native))) (def touchable-highlight-class (reagent/adapt-react-class (.-TouchableHighlight react-native)))
(def pressable-class (reagent/adapt-react-class (.-Pressable react-native)))
(def touchable-without-feedback-class (reagent/adapt-react-class (.-TouchableWithoutFeedback react-native))) (def touchable-without-feedback-class (reagent/adapt-react-class (.-TouchableWithoutFeedback react-native)))
(def touchable-opacity-class (reagent/adapt-react-class (.-TouchableOpacity react-native))) (def touchable-opacity-class (reagent/adapt-react-class (.-TouchableOpacity react-native)))
(def activity-indicator-class (reagent/adapt-react-class (.-ActivityIndicator react-native))) (def activity-indicator-class (reagent/adapt-react-class (.-ActivityIndicator react-native)))
@ -175,6 +176,9 @@
(merge {:underlay-color :transparent} props) (merge {:underlay-color :transparent} props)
content]) content])
(defn pressable [props content]
[pressable-class props content])
(defn touchable-without-feedback [props content] (defn touchable-without-feedback [props content]
[touchable-without-feedback-class [touchable-without-feedback-class
props props

View File

@ -19,7 +19,8 @@
[status-im.utils.debounce :refer [dispatch-and-chill]] [status-im.utils.debounce :refer [dispatch-and-chill]]
[quo.core :as quo] [quo.core :as quo]
[status-im.ui.screens.intro.carousel :as carousel] [status-im.ui.screens.intro.carousel :as carousel]
[status-im.utils.utils :as utils]) [status-im.utils.utils :as utils]
[status-im.utils.datetime :as datetime])
(:require-macros [status-im.utils.views :refer [defview letsubs]])) (:require-macros [status-im.utils.views :refer [defview letsubs]]))
(defview intro [] (defview intro []
@ -228,50 +229,74 @@
(step-kw-to-num step)))))] (step-kw-to-num step)))))]
:else nil)])) :else nil)]))
(defn enter-phrase [{:keys [processing? (defn enter-phrase [_]
passphrase-word-count (let [show-bip39-password? (reagent.core/atom false)
next-button-disabled? pressed-in-at (atom nil)]
passphrase-error]}] (fn [{:keys [processing?
[react/keyboard-avoiding-view {:flex 1 passphrase-word-count
:background-color colors/white} next-button-disabled?
[react/view {:background-color colors/white passphrase-error]}]
:flex 1 [react/keyboard-avoiding-view {:flex 1
:justify-content :center :background-color colors/white}
:padding-horizontal 16} [react/pressable
[quo/text-input {:style {:background-color colors/white
{:on-change-text #(re-frame/dispatch [:multiaccounts.recover/enter-phrase-input-changed (security/mask-data %)]) :flex 1
:auto-focus true :justify-content :center
:error (when passphrase-error (i18n/label passphrase-error)) :padding-horizontal 16}
:accessibility-label :passphrase-input ;; BIP39 password input will be shown only after pressing on screen
:placeholder (i18n/label :t/seed-phrase-placeholder) ;; for longer than 2 seconds
:show-cancel false :on-press-in (fn []
:bottom-value 40 (reset! pressed-in-at (datetime/now)))
:multiline true :on-press-out (fn []
:auto-correct false (when (>= (datetime/seconds-ago @pressed-in-at) 2)
:monospace true}] (reset! show-bip39-password? true)))}
[react/view {:align-items :flex-end} [react/view
[react/view {:flex-direction :row [quo/text-input
:align-items :center {:on-change-text #(re-frame/dispatch [:multiaccounts.recover/enter-phrase-input-changed (security/mask-data %)])
:padding-vertical 8 :auto-focus true
:opacity (if passphrase-word-count 1 0)} :error (when passphrase-error (i18n/label passphrase-error))
[quo/text {:color (if next-button-disabled? :secondary :main) :accessibility-label :passphrase-input
:size :small} :placeholder (i18n/label :t/seed-phrase-placeholder)
(when-not next-button-disabled? :show-cancel false
"✓ ") :bottom-value 40
(i18n/label-pluralize passphrase-word-count :t/words-n)]]]] :multiline true
[react/view {:align-items :center} :auto-correct false
[react/text {:style {:color colors/gray :monospace true}]
:font-size 14 [react/view {:align-items :flex-end}
:margin-bottom 8 [react/view {:flex-direction :row
:text-align :center}} :align-items :center
(i18n/label :t/multiaccounts-recover-enter-phrase-text)] :padding-vertical 8
(when processing? :opacity (if passphrase-word-count 1 0)}
[react/view {:flex 1 :align-items :center} [quo/text {:color (if next-button-disabled? :secondary :main)
[react/activity-indicator {:size :large :size :small}
:animating true}] (when-not next-button-disabled?
[react/text {:style {:color colors/gray "✓ ")
:margin-top 8}} (i18n/label-pluralize passphrase-word-count :t/words-n)]]]
(i18n/label :t/processing)]])]]) (when @show-bip39-password?
;; BIP39 password (`passphrase` in BIP39 https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki#from-mnemonic-to-seed)
;; is an advanced security feature which allows to add an arbitrary
;; extra word to your existing mnemonic. The password is an empty
;; string if not provided. If the password is added a completely
;; different key will be created.
[quo/text-input
{:on-change-text
#(re-frame/dispatch [:multiaccounts.recover/enter-passphrase-input-changed
(security/mask-data %)])
:placeholder (i18n/label :t/bip39-password-placeholder)
:show-cancel false}])]]
[react/view {:align-items :center}
[react/text {:style {:color colors/gray
:font-size 14
:margin-bottom 8
:text-align :center}}
(i18n/label :t/multiaccounts-recover-enter-phrase-text)]
(when processing?
[react/view {:flex 1 :align-items :center}
[react/activity-indicator {:size :large
:animating true}]
[react/text {:style {:color colors/gray
:margin-top 8}}
(i18n/label :t/processing)]])]])))
(defn recovery-success [pubkey name photo-path] (defn recovery-success [pubkey name photo-path]
[react/view {:flex 1 [react/view {:flex 1

View File

@ -1516,5 +1516,6 @@
"activity": "Activity", "activity": "Activity",
"reject-and-delete": "Reject and delete", "reject-and-delete": "Reject and delete",
"accept-and-add": "Accept and add", "accept-and-add": "Accept and add",
"my-profile": "My profile" "my-profile": "My profile",
"bip39-password-placeholder": "BIP39 password"
} }