key-storage cleanup (#16427)

This commit is contained in:
flexsurfer 2023-06-29 14:29:39 +02:00 committed by GitHub
parent b953ddb5af
commit d9f7510d13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 30 additions and 320 deletions

View File

@ -48,7 +48,7 @@
{:events [::start-keycard-backup]} {:events [::start-keycard-backup]}
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
{::multiaccounts.recover/import-multiaccount {:passphrase (-> db {::multiaccounts.recover/import-multiaccount {:passphrase (-> db
:multiaccounts/key-storage :profile/key-storage
:seed-phrase :seed-phrase
mnemonic/sanitize-passphrase) mnemonic/sanitize-passphrase)
:password nil :password nil
@ -66,7 +66,7 @@
:recovering? true :recovering? true
:selected-storage-type :advanced) :selected-storage-type :advanced)
(assoc-in [:keycard :flow] :recovery) (assoc-in [:keycard :flow] :recovery)
(update :multiaccounts/key-storage dissoc :seed-phrase)) (update :profile/key-storage dissoc :seed-phrase))
:dismiss-keyboard nil} :dismiss-keyboard nil}
(common/listen-to-hardware-back-button) (common/listen-to-hardware-back-button)
(navigation/navigate-to :keycard-onboarding-intro nil))) (navigation/navigate-to :keycard-onboarding-intro nil)))

View File

@ -2,7 +2,6 @@
(:require [re-frame.core :as re-frame] (:require [re-frame.core :as re-frame]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[status-im.keycard.common :as common] [status-im.keycard.common :as common]
[status-im.multiaccounts.key-storage.core :as key-storage]
[status-im.multiaccounts.update.core :as multiaccounts.update] [status-im.multiaccounts.update.core :as multiaccounts.update]
[utils.re-frame :as rf] [utils.re-frame :as rf]
[status-im2.navigation.events :as navigation] [status-im2.navigation.events :as navigation]
@ -124,31 +123,32 @@
pairings (get-in db [:keycard :pairings])] pairings (get-in db [:keycard :pairings])]
(rf/merge (rf/merge
cofx cofx
{:db (-> db {:db (-> db
(update :profile/profiles-overview dissoc key-uid) (update :profile/profiles-overview dissoc key-uid)
(assoc-in [:keycard :secrets] nil) (assoc-in [:keycard :secrets] nil)
(update-in [:keycard :pairings] (update-in [:keycard :pairings]
dissoc dissoc
(keyword instance-uid)) (keyword instance-uid))
(update-in [:keycard :pairings] dissoc instance-uid) (update-in [:keycard :pairings] dissoc instance-uid)
(assoc-in [:keycard :whisper-public-key] nil) (assoc-in [:keycard :whisper-public-key] nil)
(assoc-in [:keycard :wallet-address] nil) (assoc-in [:keycard :wallet-address] nil)
(assoc-in [:keycard :application-info] nil) (assoc-in [:keycard :application-info] nil)
(assoc-in [:keycard :pin] (assoc-in [:keycard :pin]
{:status nil {:status nil
:error-label nil :error-label nil
:on-verified nil})) :on-verified nil}))
:keycard/persist-pairings (dissoc pairings (keyword instance-uid)) :keycard/persist-pairings (dissoc pairings (keyword instance-uid))
:utils/show-popup {:title (i18n/label (if keys-removed-from-card? :utils/show-popup {:title (i18n/label (if keys-removed-from-card?
:t/profile-deleted-title :t/profile-deleted-title
:t/database-reset-title)) :t/database-reset-title))
:content (i18n/label (if keys-removed-from-card? :content (i18n/label (if keys-removed-from-card?
:t/profile-deleted-keycard :t/profile-deleted-keycard
:t/database-reset-content)) :t/database-reset-content))
:on-dismiss #(re-frame/dispatch [:logout])} :on-dismiss #(re-frame/dispatch [:logout])}}
::key-storage/delete-multiaccount {:key-uid key-uid ;;should be reimplemented
:on-success #(log/debug "[keycard] remove account ok") ;;:key-storage/delete-profile {:key-uid key-uid
:on-error #(log/warn "[keycard] remove account: " %)}} ;;:on-success #(log/debug "[keycard] remove account ok")
;; :on-error #(log/warn "[keycard] remove account: " %)}
(common/clear-on-card-connected) (common/clear-on-card-connected)
(common/hide-connection-sheet)))) (common/hide-connection-sheet))))

View File

@ -1,119 +1,13 @@
(ns status-im.multiaccounts.key-storage.core (ns status-im.multiaccounts.key-storage.core
(:require [clojure.string :as string] (:require [clojure.string :as string]
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[status-im.bottom-sheet.events :as bottom-sheet]
[status-im.ethereum.core :as ethereum] [status-im.ethereum.core :as ethereum]
[status-im.ethereum.mnemonic :as mnemonic]
[utils.i18n :as i18n]
[status-im.keycard.backup-key :as keycard.backup]
[status-im.keycard.common :as common]
[status-im.multiaccounts.logout.core :as multiaccounts.logout]
[status-im.multiaccounts.model :as multiaccounts.model]
[status-im.multiaccounts.recover.core :as multiaccounts.recover]
[native-module.core :as native-module] [native-module.core :as native-module]
[status-im.popover.core :as popover]
[utils.re-frame :as rf]
[status-im.utils.types :as types] [status-im.utils.types :as types]
[status-im2.navigation.events :as navigation]
[utils.security.core :as security])) [utils.security.core :as security]))
(rf/defn key-and-storage-management-pressed
"This event can be dispatched before login and from profile and needs to redirect accordingly"
{:events [::key-and-storage-management-pressed]}
[{:keys [db] :as cofx}]
(navigation/navigate-to
cofx
(if (multiaccounts.model/logged-in? db)
:actions-logged-in
:actions-not-logged-in)
nil))
(rf/defn navigate-back
{:events [::navigate-back]}
[{:keys [db] :as cofx}]
(rf/merge
cofx
{:db (-> db
(dissoc :recovered-account?)
(update :keycard
dissoc
:from-key-storage-and-migration?
:creating-backup?
:factory-reset-card?))}
(navigation/navigate-back)))
(rf/defn enter-seed-pressed
"User is logged out and probably wants to move multiaccount to Keycard. Navigate to enter seed phrase screen"
{:events [::enter-seed-pressed]}
[{:keys [db] :as cofx}]
(rf/merge
cofx
{:db (assoc db :recovered-account? true)}
(navigation/navigate-to :seed-phrase nil)))
(rf/defn key-uid-seed-mismatch
{:events [::show-seed-key-uid-mismatch-error-popup]}
[cofx _]
(popover/show-popover cofx {:view :seed-key-uid-mismatch}))
(rf/defn key-uid-matches
{:events [::key-uid-matches]}
[{:keys [db] :as cofx} _]
(let [backup? (get-in db [:keycard :creating-backup?])]
(if backup?
(keycard.backup/start-keycard-backup cofx)
(navigation/navigate-to cofx :storage nil))))
(defn validate-seed-against-key-uid
"Check if the key-uid was generated with the given seed-phrase"
[{:keys [import-mnemonic-fn on-success on-error]} {:keys [seed-phrase key-uid]}]
(import-mnemonic-fn
(mnemonic/sanitize-passphrase seed-phrase)
nil
(fn [result]
(let [{:keys [keyUid]} (types/json->clj result)]
;; if the key-uid from app-db is same as the one returned by multiaccount import,
;; it means that this seed was used to generate this multiaccount
(if (= key-uid keyUid)
(on-success)
(on-error))))))
(re-frame/reg-fx (re-frame/reg-fx
::validate-seed-against-key-uid :key-storage/delete-imported-key
(partial validate-seed-against-key-uid
{:import-mnemonic-fn native-module/multiaccount-import-mnemonic
:on-success #(re-frame/dispatch [::key-uid-matches])
:on-error #(re-frame/dispatch [::show-seed-key-uid-mismatch-error-popup])}))
(rf/defn seed-phrase-validated
{:events [::seed-phrase-validated]}
[{:keys [db] :as cofx} validation-error]
(let [error? (-> validation-error
types/json->clj
:error
string/blank?
not)
onboarding? (not (or (:profile/login db) (:profile/profile db)))]
(if error?
(popover/show-popover cofx {:view :custom-seed-phrase})
{::validate-seed-against-key-uid {:seed-phrase (-> db :multiaccounts/key-storage :seed-phrase)
;; Unique key-uid of the account for which we are going to move
;; keys
:key-uid (or (-> db :profile/login :key-uid)
(-> db :profile/profile :key-uid)
(and onboarding?
(-> db
:keycard
:application-info
:key-uid)))}})))
(rf/defn keycard-storage-pressed
{:events [::keycard-storage-pressed]}
[{:keys [db]} selected?]
{:db (assoc-in db [:multiaccounts/key-storage :keycard-storage-selected?] selected?)})
(re-frame/reg-fx
::delete-imported-key
(fn [{:keys [key-uid address password on-success on-error]}] (fn [{:keys [key-uid address password on-success on-error]}]
(let [hashed-pass (ethereum/sha3 (security/safe-unmask-data password))] (let [hashed-pass (ethereum/sha3 (security/safe-unmask-data password))]
(native-module/delete-imported-key (native-module/delete-imported-key
@ -125,132 +19,3 @@
(if-not (string/blank? error) (if-not (string/blank? error)
(on-error error) (on-error error)
(on-success)))))))) (on-success))))))))
#_"Multiaccount has been deleted from device. We now need to emulate the restore seed phrase process, and make the user land on Keycard setup screen.
To ensure that keycard setup works, we need to:
1. Import multiaccount, derive required keys and save them at the correct location in app-db
2. Take the user to :keycard-onboarding-intro screen in :intro-login-stack
The exact events dispatched for this flow if consumed from the UI are:
:m.r/enter-phrase-input-changed
:m.r/enter-phrase-next-pressed
:m.r/re-encrypt-pressed
:i/on-key-storage-selected ([:intro-wizard :selected-storage-type] is set to :advanced)
:m.r/select-storage-next-pressed
We don't need to take the exact steps, just set the required state and redirect to correct screen
"
(rf/defn import-multiaccount
[{:keys [db] :as cofx}]
{:dispatch [:bottom-sheet/hide-old]
::multiaccounts.recover/import-multiaccount
{:passphrase (get-in db [:multiaccounts/key-storage :seed-phrase])
:password nil
:success-event ::import-multiaccount-success}})
(rf/defn delete-multiaccount-and-init-keycard-onboarding
{:events [::delete-multiaccount-and-init-keycard-onboarding]}
[{:keys [db] :as cofx}]
(rf/merge
{:dispatch [:bottom-sheet/hide-old]
:db (assoc-in db [:multiaccounts/key-storage :reset-db-checked?] true)}
(import-multiaccount)))
(rf/defn storage-selected
{:events [::storage-selected]}
[{:keys [db] :as cofx}]
(if (get-in db [:multiaccounts/key-storage :reset-db-checked?])
(popover/show-popover cofx {:view :transfer-multiaccount-to-keycard-warning})
(bottom-sheet/hide-bottom-sheet-old cofx)))
(rf/defn skip-password-pressed
{:events [::skip-password-pressed]}
[cofx]
(popover/show-popover cofx {:view :transfer-multiaccount-to-keycard-warning}))
(rf/defn password-changed
{:events [::password-changed]}
[{db :db} password]
(let [unmasked-pass (security/safe-unmask-data password)]
{:db (update db
:keycard assoc
:migration-password password
:migration-password-error nil
:migration-password-valid? (and unmasked-pass (> (count unmasked-pass) 5)))}))
(rf/defn verify-password-result
{:events [::verify-password-result]}
[{:keys [db] :as cofx} result]
(let [{:keys [error]} (types/json->clj result)]
(if (string/blank? error)
(rf/merge
cofx
{:db (update db :keycard dissoc :migration-password-error :migration-password-valid?)}
(import-multiaccount))
{:db (assoc-in db [:keycard :migration-password-error] (i18n/label :t/wrong-password))})))
(rf/defn verify-password
{:events [::verify-password]}
[{:keys [db] :as cofx}]
(native-module/verify-database-password
(get-in db [:profile/login :key-uid])
(ethereum/sha3 (security/safe-unmask-data (get-in db [:keycard :migration-password])))
#(re-frame/dispatch [::verify-password-result %])))
(rf/defn handle-multiaccount-import
{:events [::import-multiaccount-success]}
[{:keys [db] :as cofx} root-data derived-data]
(rf/merge cofx
{:db (-> db
(update :intro-wizard
assoc
:root-key root-data
:derived derived-data
:recovering? true
:selected-storage-type :advanced)
(assoc-in [:keycard :flow] :recovery)
(assoc-in [:keycard :from-key-storage-and-migration?] true)
(assoc-in [:keycard :converting-account?]
(not (get-in db [:multiaccounts/key-storage :reset-db-checked?])))
(assoc-in [:keycard :delete-account?]
(true? (get-in db [:multiaccounts/key-storage :reset-db-checked?])))
(dissoc :multiaccounts/key-storage))}
(popover/hide-popover)
(common/listen-to-hardware-back-button)
(navigation/navigate-to :keycard-onboarding-intro nil)))
(rf/defn goto-multiaccounts-screen
{:events [::hide-popover-and-goto-multiaccounts-screen]}
[cofx _]
(rf/merge cofx
(popover/hide-popover)
(navigation/navigate-to :multiaccounts nil)))
(rf/defn confirm-logout-and-goto-key-storage
{:events [::confirm-logout-and-goto-key-storage]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (assoc db :goto-key-storage? true)}
(multiaccounts.logout/logout)))
(rf/defn logout-and-goto-key-storage
{:events [::logout-and-goto-key-storage]}
[_]
{:ui/show-confirmation
{:title (i18n/label :t/logout-title)
:content (i18n/label :t/logout-key-management)
:confirm-button-text (i18n/label :t/logout)
:on-accept #(re-frame/dispatch [::confirm-logout-and-goto-key-storage])
:on-cancel nil}})
(comment
;; check import mnemonic output
(native-module/multiaccount-import-mnemonic
"rocket mixed rebel affair umbrella legal resemble scene virus park deposit cargo"
nil
(fn [result]
(prn (types/json->clj result))))
;; check delete account output
(native-module/delete-multiaccount "0x3831d0f22996a65970a214f0a94bfa9a63a21dac235d8dadb91be8e32e7d3ab7"
(fn [result]
(prn ::--delete-account-res-> result))))

View File

@ -1,44 +0,0 @@
(ns status-im.multiaccounts.key-storage.core-test
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.multiaccounts.key-storage.core :as models]
[utils.security.core :as security]))
(def seed-key-uid-pair
{:seed-phrase "rocket mixed rebel affair umbrella legal resemble scene virus park deposit cargo"
:key-uid "0x3831d0f22996a65970a214f0a94bfa9a63a21dac235d8dadb91be8e32e7d3ab7"})
(defn mock-import-mnemonic-fn
[_ _ _]
;; return json with keyUid, the real world will have more info in the response
(str "{\"keyUid\": \"" (:key-uid seed-key-uid-pair) "\"}"))
(deftest validate-seed-against-key-uid
(testing "Success event is triggered if correct seed is entered for selected multiaccount (key-uid)"
(models/validate-seed-against-key-uid
{:import-mnemonic-fn mock-import-mnemonic-fn
:on-success #(is true) ; this callback should be called
:on-error #(is false)}
{:seed-phrase (:seed-phrase seed-key-uid-pair)
:key-uid (:key-uid seed-key-uid-pair)}))
(testing "Error event is triggered if incorrect seed is entered for selected multiaccount"
(models/validate-seed-against-key-uid
{:import-mnemonic-fn mock-import-mnemonic-fn
:on-success #(is false)
:on-error #(is true)}
{:seed-phrase (:seed-phrase seed-key-uid-pair)
:key-uid "0xInvalid-Will-make-the-function-fail"})))
(deftest handle-multiaccount-import
(testing "Sets correct state for Keycard onboarding after multiaccounts seeds are derived"
(let [res (models/handle-multiaccount-import {:db {}} :passed-root-data :passed-derived-data)]
(is (= :passed-root-data (get-in res [:db :intro-wizard :root-key])))
(is (= :passed-derived-data (get-in res [:db :intro-wizard :derived])))
(is (= :advanced (get-in res [:db :intro-wizard :selected-storage-type]))) ; :advanced storage type
; means Keycard
(is (= :recovery (get-in res [:db :keycard :flow])))
(is (get-in res [:db :keycard :from-key-storage-and-migration?])))))
(comment
(security/safe-unmask-data (security/mask-data nil)))

View File

@ -4,7 +4,6 @@
[status-im2.constants :as constants] [status-im2.constants :as constants]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[status-im.multiaccounts.biometric.core :as biometric] [status-im.multiaccounts.biometric.core :as biometric]
[status-im.multiaccounts.key-storage.core :as key-storage]
[status-im.multiaccounts.reset-password.core :as reset-password] [status-im.multiaccounts.reset-password.core :as reset-password]
[status-im.multiaccounts.update.core :as multiaccounts.update] [status-im.multiaccounts.update.core :as multiaccounts.update]
[status-im.ui.components.common.common :as components.common] [status-im.ui.components.common.common :as components.common]
@ -127,14 +126,6 @@
:on-press #(re-frame/dispatch :on-press #(re-frame/dispatch
[:multiaccounts.ui/webview-permission-requests-switched [:multiaccounts.ui/webview-permission-requests-switched
((complement boolean) webview-allow-permission-requests?)])}]) ((complement boolean) webview-allow-permission-requests?)])}])
(when (not keycard?)
[quo/list-item
{:size :small
:title (i18n/label :t/manage-keys-and-storage)
:chevron true
:on-press #(re-frame/dispatch [::key-storage/logout-and-goto-key-storage])
:accessibility-label :key-managment}])
[separator] [separator]
[quo/list-header (i18n/label :t/privacy-photos)] [quo/list-header (i18n/label :t/privacy-photos)]
[quo/list-item [quo/list-item

View File

@ -12,7 +12,6 @@
[status-im.ethereum.stateofus :as stateofus] [status-im.ethereum.stateofus :as stateofus]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[status-im.multiaccounts.core :as multiaccounts] [status-im.multiaccounts.core :as multiaccounts]
[status-im.multiaccounts.key-storage.core :as key-storage]
[status-im.multiaccounts.update.core :as multiaccounts.update] [status-im.multiaccounts.update.core :as multiaccounts.update]
[native-module.core :as native-module] [native-module.core :as native-module]
[status-im.ui.components.list-selection :as list-selection] [status-im.ui.components.list-selection :as list-selection]
@ -342,7 +341,7 @@
(if (= (string/lower-case dapps-address) (string/lower-case deleted-address)) (if (= (string/lower-case dapps-address) (string/lower-case deleted-address))
{:utils/show-popup {:title (i18n/label :t/warning) {:utils/show-popup {:title (i18n/label :t/warning)
:content (i18n/label :t/account-is-used)}} :content (i18n/label :t/account-is-used)}}
{::key-storage/delete-imported-key {:key-storage/delete-imported-key
{:key-uid (get-in db [:profile/profile :key-uid]) {:key-uid (get-in db [:profile/profile :key-uid])
:address (:address account) :address (:address account)
:password password :password password

View File

@ -93,7 +93,6 @@
(reg-root-key-sub :profile/profile-settings :profile/profile) (reg-root-key-sub :profile/profile-settings :profile/profile)
(reg-root-key-sub :profile/wallet-accounts :profile/wallet-accounts) (reg-root-key-sub :profile/wallet-accounts :profile/wallet-accounts)
(reg-root-key-sub :multiaccounts/key-storage :multiaccounts/key-storage)
(reg-root-key-sub :multiaccount/reset-password-form-vals :multiaccount/reset-password-form-vals) (reg-root-key-sub :multiaccount/reset-password-form-vals :multiaccount/reset-password-form-vals)
(reg-root-key-sub :multiaccount/reset-password-errors :multiaccount/reset-password-errors) (reg-root-key-sub :multiaccount/reset-password-errors :multiaccount/reset-password-errors)
(reg-root-key-sub :multiaccount/resetting-password? :multiaccount/resetting-password?) (reg-root-key-sub :multiaccount/resetting-password? :multiaccount/resetting-password?)