From 952b01e9e121c5cb88c46cfa7cc94373248cd330 Mon Sep 17 00:00:00 2001 From: Julien Eluard Date: Thu, 24 May 2018 19:19:59 +0200 Subject: [PATCH] [#1228] Only enable Next button when passphrase is valid Signed-off-by: Julien Eluard --- .../ui/screens/accounts/recover/db.cljs | 4 --- .../ui/screens/accounts/recover/views.cljs | 9 ++++--- src/status_im/utils/ethereum/core.cljs | 25 +++++++++++++++++-- .../status_im/test/utils/ethereum/core.cljs | 15 +++++++++-- 4 files changed, 41 insertions(+), 12 deletions(-) delete mode 100644 src/status_im/ui/screens/accounts/recover/db.cljs diff --git a/src/status_im/ui/screens/accounts/recover/db.cljs b/src/status_im/ui/screens/accounts/recover/db.cljs deleted file mode 100644 index fee18ff9f7..0000000000 --- a/src/status_im/ui/screens/accounts/recover/db.cljs +++ /dev/null @@ -1,4 +0,0 @@ -(ns status-im.ui.screens.accounts.recover.db - (:require [cljs.spec.alpha :as spec])) - -(spec/def ::passphrase :global/not-empty-string) diff --git a/src/status_im/ui/screens/accounts/recover/views.cljs b/src/status_im/ui/screens/accounts/recover/views.cljs index f56665c80f..dacd2fbf7f 100644 --- a/src/status_im/ui/screens/accounts/recover/views.cljs +++ b/src/status_im/ui/screens/accounts/recover/views.cljs @@ -10,9 +10,9 @@ [status-im.ui.components.toolbar.view :as toolbar] [status-im.i18n :as i18n] [status-im.ui.screens.accounts.recover.styles :as styles] - [status-im.ui.screens.accounts.recover.db :as recover.db] [status-im.ui.screens.accounts.db :as db] [status-im.utils.config :as config] + [status-im.utils.ethereum.core :as ethereum] [status-im.react-native.js-dependencies :as js-dependencies] [cljs.spec.alpha :as spec] [status-im.ui.components.common.common :as components.common] @@ -49,8 +49,9 @@ (defview recover [] (letsubs [{:keys [passphrase password processing]} [:get :accounts/recover]] - (let [valid-form? (and - (spec/valid? ::recover.db/passphrase passphrase) + (let [words (ethereum/passphrase->words passphrase) + valid-form? (and + (ethereum/valid-words? words) (spec/valid? ::db/password password))] [react/keyboard-avoiding-view {:style styles/screen-container} [status-bar/status-bar] @@ -73,5 +74,5 @@ :label (i18n/label :t/sign-in) :disabled? (not valid-form?) :on-press (fn [_] - (let [masked-passphrase (security/mask-data (string/trim passphrase))] + (let [masked-passphrase (security/mask-data (ethereum/words->passphrase words))] (re-frame/dispatch [:recover-account masked-passphrase password])))}]])]))) diff --git a/src/status_im/utils/ethereum/core.cljs b/src/status_im/utils/ethereum/core.cljs index 63b7b7fad4..68b2897595 100644 --- a/src/status_im/utils/ethereum/core.cljs +++ b/src/status_im/utils/ethereum/core.cljs @@ -3,8 +3,7 @@ [status-im.js-dependencies :as dependencies] [status-im.utils.ethereum.tokens :as tokens] [status-im.utils.money :as money] - [taoensso.timbre :as log] - [status-im.utils.types :as types])) + [taoensso.timbre :as log])) ;; IDs standardized in https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md#list-of-chain-ids @@ -33,6 +32,28 @@ (defn network-with-upstream-rpc? [network] (get-in network [:config :UpstreamConfig :Enabled])) +(defn passphrase->words [s] + (when s + (-> (string/trim s) + (string/replace-all #"\s+" " ") + (string/split #" ")))) + +(defn words->passphrase [v] + (string/join " " v)) + +(def valid-word-counts #{12 15 18 21 24}) + +(defn valid-word-counts? [v] + (boolean (valid-word-counts (count v)))) + +(defn- valid-word? [s] + (re-matches #"^[A-z]+$" s)) + +(defn valid-words? [v] + (and + (valid-word-counts? v) + (every? valid-word? v))) + (def hex-prefix "0x") (defn normalized-address [address] diff --git a/test/cljs/status_im/test/utils/ethereum/core.cljs b/test/cljs/status_im/test/utils/ethereum/core.cljs index 0228287a17..bc64f1cae4 100644 --- a/test/cljs/status_im/test/utils/ethereum/core.cljs +++ b/test/cljs/status_im/test/utils/ethereum/core.cljs @@ -1,11 +1,22 @@ (ns status-im.test.utils.ethereum.core (:require [cljs.test :refer-macros [deftest is testing]] - [status-im.utils.ethereum.core :as core])) + [status-im.utils.ethereum.core :as ethereum])) (deftest call-params (testing "ERC20 balance-of params" (let [contract "0x29b5f6efad2ad701952dfde9f29c960b5d6199c5" address "0xa7cfd581060ec66414790691681732db249502bd"] - (is (= (core/call-params contract "balanceOf(address)" address) + (is (= (ethereum/call-params contract "balanceOf(address)" address) {:to "0x29b5f6efad2ad701952dfde9f29c960b5d6199c5" :data "0x70a08231000000000000000000000000a7cfd581060ec66414790691681732db249502bd"}))))) + +(deftest valid-words? + (is (not (true? (ethereum/valid-words? ["rate" "rate"])))) + (is (not (true? (ethereum/valid-words? ["rate" "rate" "rate" "rate" "rate" "rate" "rate" "rate" "rate" "rate" "rate" "rate?"])))) + (is (true? (ethereum/valid-words? ["rate" "rate" "rate" "rate" "rate" "rate" "rate" "rate" "rate" "rate" "rate" "rate"])))) + +(deftest passphrase->words? + (is (= ["one" "two" "three" "for" "five" "six" "seven" "height" "nine" "ten" "eleven" "twelve"] + (ethereum/passphrase->words "one two three for five six seven height nine ten eleven twelve")) + (= ["one" "two" "three" "for" "five" "six" "seven" "height" "nine" "ten" "eleven" "twelve"] + (ethereum/passphrase->words " one two three for five six seven height nine ten eleven twelve "))))