From d9f7510d13b437c0864a09ed683b594dd944e2d6 Mon Sep 17 00:00:00 2001 From: flexsurfer Date: Thu, 29 Jun 2023 14:29:39 +0200 Subject: [PATCH] key-storage cleanup (#16427) --- src/status_im/keycard/backup_key.cljs | 4 +- src/status_im/keycard/unpair.cljs | 52 ++-- .../multiaccounts/key_storage/core.cljs | 237 +----------------- .../multiaccounts/key_storage/core_test.cljs | 44 ---- .../privacy_and_security_settings/views.cljs | 9 - src/status_im/wallet/accounts/core.cljs | 3 +- src/status_im2/subs/root.cljs | 1 - 7 files changed, 30 insertions(+), 320 deletions(-) delete mode 100644 src/status_im/multiaccounts/key_storage/core_test.cljs diff --git a/src/status_im/keycard/backup_key.cljs b/src/status_im/keycard/backup_key.cljs index 09500d5f11..5c260bb188 100644 --- a/src/status_im/keycard/backup_key.cljs +++ b/src/status_im/keycard/backup_key.cljs @@ -48,7 +48,7 @@ {:events [::start-keycard-backup]} [{:keys [db] :as cofx}] {::multiaccounts.recover/import-multiaccount {:passphrase (-> db - :multiaccounts/key-storage + :profile/key-storage :seed-phrase mnemonic/sanitize-passphrase) :password nil @@ -66,7 +66,7 @@ :recovering? true :selected-storage-type :advanced) (assoc-in [:keycard :flow] :recovery) - (update :multiaccounts/key-storage dissoc :seed-phrase)) + (update :profile/key-storage dissoc :seed-phrase)) :dismiss-keyboard nil} (common/listen-to-hardware-back-button) (navigation/navigate-to :keycard-onboarding-intro nil))) diff --git a/src/status_im/keycard/unpair.cljs b/src/status_im/keycard/unpair.cljs index e59c9287dc..75efda911d 100644 --- a/src/status_im/keycard/unpair.cljs +++ b/src/status_im/keycard/unpair.cljs @@ -2,7 +2,6 @@ (:require [re-frame.core :as re-frame] [utils.i18n :as i18n] [status-im.keycard.common :as common] - [status-im.multiaccounts.key-storage.core :as key-storage] [status-im.multiaccounts.update.core :as multiaccounts.update] [utils.re-frame :as rf] [status-im2.navigation.events :as navigation] @@ -124,31 +123,32 @@ pairings (get-in db [:keycard :pairings])] (rf/merge cofx - {:db (-> db - (update :profile/profiles-overview dissoc key-uid) - (assoc-in [:keycard :secrets] nil) - (update-in [:keycard :pairings] - dissoc - (keyword instance-uid)) - (update-in [:keycard :pairings] dissoc instance-uid) - (assoc-in [:keycard :whisper-public-key] nil) - (assoc-in [:keycard :wallet-address] nil) - (assoc-in [:keycard :application-info] nil) - (assoc-in [:keycard :pin] - {:status nil - :error-label nil - :on-verified nil})) - :keycard/persist-pairings (dissoc pairings (keyword instance-uid)) - :utils/show-popup {:title (i18n/label (if keys-removed-from-card? - :t/profile-deleted-title - :t/database-reset-title)) - :content (i18n/label (if keys-removed-from-card? - :t/profile-deleted-keycard - :t/database-reset-content)) - :on-dismiss #(re-frame/dispatch [:logout])} - ::key-storage/delete-multiaccount {:key-uid key-uid - :on-success #(log/debug "[keycard] remove account ok") - :on-error #(log/warn "[keycard] remove account: " %)}} + {:db (-> db + (update :profile/profiles-overview dissoc key-uid) + (assoc-in [:keycard :secrets] nil) + (update-in [:keycard :pairings] + dissoc + (keyword instance-uid)) + (update-in [:keycard :pairings] dissoc instance-uid) + (assoc-in [:keycard :whisper-public-key] nil) + (assoc-in [:keycard :wallet-address] nil) + (assoc-in [:keycard :application-info] nil) + (assoc-in [:keycard :pin] + {:status nil + :error-label nil + :on-verified nil})) + :keycard/persist-pairings (dissoc pairings (keyword instance-uid)) + :utils/show-popup {:title (i18n/label (if keys-removed-from-card? + :t/profile-deleted-title + :t/database-reset-title)) + :content (i18n/label (if keys-removed-from-card? + :t/profile-deleted-keycard + :t/database-reset-content)) + :on-dismiss #(re-frame/dispatch [:logout])}} + ;;should be reimplemented + ;;:key-storage/delete-profile {:key-uid key-uid + ;;:on-success #(log/debug "[keycard] remove account ok") + ;; :on-error #(log/warn "[keycard] remove account: " %)} (common/clear-on-card-connected) (common/hide-connection-sheet)))) diff --git a/src/status_im/multiaccounts/key_storage/core.cljs b/src/status_im/multiaccounts/key_storage/core.cljs index be00f5fc35..ccc1d347e8 100644 --- a/src/status_im/multiaccounts/key_storage/core.cljs +++ b/src/status_im/multiaccounts/key_storage/core.cljs @@ -1,119 +1,13 @@ (ns status-im.multiaccounts.key-storage.core (:require [clojure.string :as string] [re-frame.core :as re-frame] - [status-im.bottom-sheet.events :as bottom-sheet] [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] - [status-im.popover.core :as popover] - [utils.re-frame :as rf] [status-im.utils.types :as types] - [status-im2.navigation.events :as navigation] [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 - ::validate-seed-against-key-uid - (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 + :key-storage/delete-imported-key (fn [{:keys [key-uid address password on-success on-error]}] (let [hashed-pass (ethereum/sha3 (security/safe-unmask-data password))] (native-module/delete-imported-key @@ -125,132 +19,3 @@ (if-not (string/blank? error) (on-error error) (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)))) diff --git a/src/status_im/multiaccounts/key_storage/core_test.cljs b/src/status_im/multiaccounts/key_storage/core_test.cljs deleted file mode 100644 index d608939f49..0000000000 --- a/src/status_im/multiaccounts/key_storage/core_test.cljs +++ /dev/null @@ -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))) - diff --git a/src/status_im/ui/screens/privacy_and_security_settings/views.cljs b/src/status_im/ui/screens/privacy_and_security_settings/views.cljs index fcfb8db305..6ba4e5e5c8 100644 --- a/src/status_im/ui/screens/privacy_and_security_settings/views.cljs +++ b/src/status_im/ui/screens/privacy_and_security_settings/views.cljs @@ -4,7 +4,6 @@ [status-im2.constants :as constants] [utils.i18n :as i18n] [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.update.core :as multiaccounts.update] [status-im.ui.components.common.common :as components.common] @@ -127,14 +126,6 @@ :on-press #(re-frame/dispatch [:multiaccounts.ui/webview-permission-requests-switched ((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] [quo/list-header (i18n/label :t/privacy-photos)] [quo/list-item diff --git a/src/status_im/wallet/accounts/core.cljs b/src/status_im/wallet/accounts/core.cljs index e391376a38..4de8b89c98 100644 --- a/src/status_im/wallet/accounts/core.cljs +++ b/src/status_im/wallet/accounts/core.cljs @@ -12,7 +12,6 @@ [status-im.ethereum.stateofus :as stateofus] [utils.i18n :as i18n] [status-im.multiaccounts.core :as multiaccounts] - [status-im.multiaccounts.key-storage.core :as key-storage] [status-im.multiaccounts.update.core :as multiaccounts.update] [native-module.core :as native-module] [status-im.ui.components.list-selection :as list-selection] @@ -342,7 +341,7 @@ (if (= (string/lower-case dapps-address) (string/lower-case deleted-address)) {:utils/show-popup {:title (i18n/label :t/warning) :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]) :address (:address account) :password password diff --git a/src/status_im2/subs/root.cljs b/src/status_im2/subs/root.cljs index b95b1189ee..8289b88ca9 100644 --- a/src/status_im2/subs/root.cljs +++ b/src/status_im2/subs/root.cljs @@ -93,7 +93,6 @@ (reg-root-key-sub :profile/profile-settings :profile/profile) (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-errors :multiaccount/reset-password-errors) (reg-root-key-sub :multiaccount/resetting-password? :multiaccount/resetting-password?)