Skip to content

Commit

Permalink
[#10002] Follow up after #10008
Browse files Browse the repository at this point in the history
- ensure that `:key-uid` is always added to `app-db` with proper case
- tests which cover multiacc duplication case
  • Loading branch information
rasom committed Feb 25, 2020
1 parent e5f7a94 commit 9a71314
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 29 deletions.
8 changes: 4 additions & 4 deletions src/status_im/hardwallet/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -1846,20 +1846,20 @@
(assoc :intro-wizard nil))}
(multiaccounts.create/on-multiaccount-created
{:derived {constants/path-wallet-root-keyword
{:publicKey wallet-root-public-key
{:public-key wallet-root-public-key
:address (eip55/address->checksum wallet-root-address)}
constants/path-whisper-keyword
{:publicKey whisper-public-key
{:public-key whisper-public-key
:address (eip55/address->checksum whisper-address)
:name name
:photo-path photo-path}
constants/path-default-wallet-keyword
{:publicKey wallet-public-key
{:public-key wallet-public-key
:address (eip55/address->checksum wallet-address)}}
:address address
:public-key public-key
:keycard-instance-uid instance-uid
:keyUid (ethereum/normalized-hex key-uid)
:key-uid (ethereum/normalized-hex key-uid)
:keycard-pairing pairing
:keycard-paired-on paired-on
:chat-key whisper-private-key}
Expand Down
41 changes: 30 additions & 11 deletions src/status_im/multiaccounts/create/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,30 @@
(let [{:keys [selected-id multiaccounts]} (:intro-wizard db)]
(some #(when (= selected-id (:id %)) %) multiaccounts)))

(defn normalize-derived-data-keys [derived-data]
(->> derived-data
(map (fn [[path {:keys [publicKey] :as data}]]
[path (cond-> (-> data
(dissoc :publicKey)
(assoc :public-key publicKey)))]))
(into {})))

(defn normalize-multiaccount-data-keys
[{:keys [publicKey keyUid derived] :as data}]
(cond-> (-> data
(dissoc :keyUid :publicKey)
(assoc :key-uid keyUid
:public-key publicKey))
derived
(update :derived normalize-derived-data-keys)))

(fx/defn create-multiaccount
[{:keys [db]}]
(let [{:keys [selected-id key-code]} (:intro-wizard db)
hashed-password (ethereum/sha3 (security/safe-unmask-data key-code))
callback (fn [result]
(let [derived-data (types/json->clj result)
public-key (get-in derived-data [constants/path-whisper-keyword :publicKey])]
(let [derived-data (normalize-derived-data-keys (types/json->clj result))
public-key (get-in derived-data [constants/path-whisper-keyword :public-key])]
(status/gfycat-identicon-async
public-key
(fn [name photo-path]
Expand Down Expand Up @@ -191,17 +208,17 @@

(defn prepare-accounts-data
[multiaccount]
[(let [{:keys [publicKey address]}
[(let [{:keys [public-key address]}
(get-in multiaccount [:derived constants/path-default-wallet-keyword])]
{:public-key publicKey
{:public-key public-key
:address (eip55/address->checksum address)
:color colors/blue
:wallet true
:path constants/path-default-wallet
:name "Status account"})
(let [{:keys [publicKey address name photo-path]}
(let [{:keys [public-key address name photo-path]}
(get-in multiaccount [:derived constants/path-whisper-keyword])]
{:public-key publicKey
{:public-key public-key
:address (eip55/address->checksum address)
:name name
:photo-path photo-path
Expand All @@ -227,7 +244,7 @@

(fx/defn on-multiaccount-created
[{:keys [signing-phrase random-guid-generator db] :as cofx}
{:keys [address chat-key keycard-instance-uid keyUid
{:keys [address chat-key keycard-instance-uid key-uid
keycard-pairing keycard-paired-on mnemonic public-key]
:as multiaccount}
password
Expand All @@ -236,7 +253,7 @@
multiaccount-data {:name name
:address address
:photo-path photo-path
:key-uid keyUid
:key-uid key-uid
:keycard-pairing keycard-pairing}
keycard-multiaccount? (boolean keycard-pairing)
eip1581-address (get-in multiaccount [:derived
Expand All @@ -247,7 +264,7 @@
{;; address of the master key
:address address
;; sha256 of master public key
:key-uid keyUid
:key-uid key-uid
;; The address from which we derive any wallet
:wallet-root-address
(get-in multiaccount [:derived
Expand All @@ -274,7 +291,7 @@
:keycard-pairing keycard-pairing
:keycard-paired-on keycard-paired-on))
db (assoc db
:multiaccounts/login {:key-uid keyUid
:multiaccounts/login {:key-uid key-uid
:name name
:photo-path photo-path
:password password
Expand Down Expand Up @@ -311,7 +328,9 @@
5
12
[constants/path-whisper constants/path-default-wallet]
#(re-frame/dispatch [:intro-wizard/on-keys-generated (types/json->clj %)]))))
#(re-frame/dispatch [:intro-wizard/on-keys-generated
(mapv normalize-multiaccount-data-keys
(types/json->clj %))]))))

(fx/defn on-keys-generated
{:events [:intro-wizard/on-keys-generated]}
Expand Down
16 changes: 15 additions & 1 deletion src/status_im/multiaccounts/db.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
(spec/def :multiaccount/accounts (spec/coll-of :multiaccount/account :kind vector?))

(spec/def :multiaccount/address :global/address)
(spec/def :multiaccount/key-uid string?)
(spec/def :multiaccount/key-uid :global/key-uid)
(spec/def :multiaccount/name :global/not-empty-string)
(spec/def :multiaccount/public-key :global/public-key)
(spec/def :multiaccount/signed-up? (spec/nilable boolean?))
Expand Down Expand Up @@ -76,6 +76,20 @@
:multiaccount/keycard-paired-on
:multiaccount/root-address
:multiaccount/accounts]))
;; generated multiaccounts
(spec/def :generated-multiaccounts/id string?)
(spec/def :generated-multiaccounts/derived-key
(spec/keys :req-un [:multiaccount/address
:multiaccount/public-key]))
(spec/def :generated-multiaccounts/derived
(spec/map-of keyword? :generated-multiaccounts/derived-key))
(spec/def :multiaccounts/generated-multiaccount
(spec/keys :req-un [:multiaccount/address
:multiaccount/mnemonic
:multiaccount/public-key
:multiaccount/key-uid
:generated-multiaccounts/id]
:opt-un [:generated-multiaccounts/derived]))

;;used during recovering multiaccount
(spec/def :multiaccounts/recover (spec/nilable map?))
Expand Down
26 changes: 16 additions & 10 deletions src/status_im/multiaccounts/recover/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
[taoensso.timbre :as log]))

(defn existing-account?
[root-key multiaccounts]
(contains? multiaccounts (:keyUid root-key)))
[multiaccounts key-uid]
{:pre [(not (nil? key-uid))]}
(contains? multiaccounts key-uid))

(re-frame/reg-fx
::validate-mnemonic
Expand Down Expand Up @@ -100,21 +101,26 @@
passphrase
password
(fn [result]
(let [{:keys [id] :as root-data} (types/json->clj result)]
(let [{:keys [id] :as root-data}
(multiaccounts.create/normalize-multiaccount-data-keys
(types/json->clj result))]
(status-im.native-module.core/multiaccount-derive-addresses
id
[constants/path-wallet-root
constants/path-eip1581
constants/path-whisper
constants/path-default-wallet]
(fn [result]
(let [derived-data (types/json->clj result)
public-key (get-in derived-data [constants/path-whisper-keyword :publicKey])]
(let [derived-data (multiaccounts.create/normalize-derived-data-keys
(types/json->clj result))
public-key (get-in derived-data [constants/path-whisper-keyword :public-key])]
(status/gfycat-identicon-async
public-key
(fn [name photo-path]
(let [derived-whisper (derived-data constants/path-whisper-keyword)
derived-data-extended (assoc-in derived-data [constants/path-whisper-keyword] (merge derived-whisper {:name name :photo-path photo-path}))]
(let [derived-data-extended
(update derived-data
constants/path-whisper-keyword
merge {:name name :photo-path photo-path})]
(re-frame/dispatch [::import-multiaccount-success
root-data derived-data-extended]))))))))))))

Expand All @@ -130,7 +136,7 @@

(fx/defn on-import-multiaccount-success
{:events [::import-multiaccount-success]}
[{:keys [db] :as cofx} root-data derived-data]
[{:keys [db] :as cofx} {:keys [key-uid] :as root-data} derived-data]
(let [multiaccounts (:multiaccounts/multiaccounts db)]
(fx/merge
cofx
Expand All @@ -139,8 +145,8 @@
:derived derived-data
:step :recovery-success
:forward-action :multiaccounts.recover/re-encrypt-pressed)}
(when (existing-account? root-data multiaccounts)
(show-existing-multiaccount-alert (:keyUid root-data)))
(when (existing-account? multiaccounts key-uid)
(show-existing-multiaccount-alert key-uid))
(navigation/navigate-to-cofx :recover-multiaccount-success nil))))

(fx/defn enter-phrase-pressed
Expand Down
2 changes: 1 addition & 1 deletion src/status_im/subs.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@
:intro-wizard/recovery-success
:<- [:intro-wizard]
(fn [wizard-state]
{:pubkey (get-in wizard-state [:derived constants/path-whisper-keyword :publicKey])
{:pubkey (get-in wizard-state [:derived constants/path-whisper-keyword :public-key])
:name (get-in wizard-state [:derived constants/path-whisper-keyword :name])
:photo-path (get-in wizard-state [:derived constants/path-whisper-keyword :photo-path])
:processing? (:processing? wizard-state)}))
Expand Down
4 changes: 3 additions & 1 deletion src/status_im/ui/screens/db.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
status-im.browser.db
status-im.ui.screens.add-new.new-public-chat.db
status-im.ui.components.bottom-sheet.core
status-im.ui.screens.intro.db
[status-im.wallet.db :as wallet.db]))

;; initial state of app-db
Expand Down Expand Up @@ -314,4 +315,5 @@
::collectibles
:registry/registry
::two-pane-ui-enabled?
::add-account]))
::add-account
:intro-wizard/intro-wizard]))
36 changes: 36 additions & 0 deletions src/status_im/ui/screens/intro/db.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
(ns status-im.ui.screens.intro.db
(:require [cljs.spec.alpha :as spec]
status-im.multiaccounts.db))

(spec/def :intro-wizrad/encrypt-with-password? boolean?)
(spec/def :intro-wizard/multiaccounts
(spec/coll-of :multiaccounts/generated-multiaccount))
(spec/def :intro-wizard/selected-storage-type? keyword?)
(spec/def :intro-wizard/selected-id :generated-multiaccounts/id)
(spec/def :intro-wizard/back-action keyword?)
(spec/def :intro-wizard/weak-password? boolean?)
(spec/def :intro-wizard/forward-action keyword?)
(spec/def :intro-wizard/first-time-setup? boolean?)
(spec/def :intro-wizard/step (spec/nilable keyword?))
(spec/def :intro-wizard/root-key :multiaccounts/generated-multiaccount)
(spec/def :intro-wizard/passphrase string?)
(spec/def :intro-wizard/recovering? boolean?)
(spec/def :intro-wizard/passphrase-word-count int?)
(spec/def :intro-wizard/derived :generated-multiaccounts/derived)
(spec/def :intro-wizard/next-button-disabled? boolean?)

(spec/def :intro-wizard/intro-wizard
(spec/keys :req-un [:intro-wizrad/encrypt-with-password?
:intro-wizard/back-action
:intro-wizard/weak-password?
:intro-wizard/forward-action
:intro-wizard/first-time-setup?
:intro-wizard/step]
:opt-un [:intro-wizard/selected-id
:intro-wizard/selected-storage-type?
:intro-wizard/multiaccounts
:intro-wizard/root-key
:intro-wizard/passphrase
:intro-wizard/passphrase-word-count
:intro-wizard/derived
:intro-wizard/next-button-disabled?]))
2 changes: 1 addition & 1 deletion src/status_im/ui/screens/intro/views.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
{:content-container-style {:justify-content :flex-start}}
(for [[acc accessibility-n] (map vector multiaccounts (range (count multiaccounts)))]
(let [selected? (= (:id acc) selected-id)
public-key (get-in acc [:derived constants/path-whisper-keyword :publicKey])]
public-key (get-in acc [:derived constants/path-whisper-keyword :public-key])]
^{:key public-key}
[react/touchable-highlight
{:accessibility-label (keyword (str "select-account-button-" accessibility-n))
Expand Down
4 changes: 4 additions & 0 deletions src/status_im/utils/db.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
(defn valid-public-key? [s]
(boolean (re-matches #"0x04[0-9a-f]{128}" s)))

(defn valid-key-uid? [s]
(boolean (re-matches #"0x[0-9a-f]{64}" s)))

(spec/def :global/not-empty-string (spec/and string? not-empty))
(spec/def :global/public-key (spec/and :global/not-empty-string valid-public-key?))
(spec/def :global/key-uid (spec/and :global/not-empty-string valid-key-uid?))
(spec/def :global/address ethereum/address?)

(spec/def :status/tag (spec/and :global/not-empty-string
Expand Down
14 changes: 14 additions & 0 deletions test/cljs/status_im/test/multiaccounts/recover/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,17 @@
(is (= (i18n/label :recovery-typo-dialog-title) (-> new-cofx :ui/show-confirmation :title)))
(is (= (i18n/label :recovery-typo-dialog-description) (-> new-cofx :ui/show-confirmation :content)))
(is (= (i18n/label :recovery-confirm-phrase) (-> new-cofx :ui/show-confirmation :confirm-button-text)))))

(deftest on-import-multiaccount-success
(testing "importing a new multiaccount"
(let [res (models/on-import-multiaccount-success
{:db {:multiaccounts/multiaccounts {:acc1 {}}}}
{:key-uid :acc2}
nil)]
(is (nil? (:utils/show-confirmation res)))))
(testing "importing an existing multiaccount"
(let [res (models/on-import-multiaccount-success
{:db {:multiaccounts/multiaccounts {:acc1 {}}}}
{:key-uid :acc1}
nil)]
(is (contains? res :utils/show-confirmation)))))

0 comments on commit 9a71314

Please sign in to comment.