From 866b854ee0d05b926f7b88d02b3d4334eb7af8ff Mon Sep 17 00:00:00 2001 From: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com> Date: Thu, 11 Jul 2024 15:55:00 +0530 Subject: [PATCH] fix(key-pairs)_: error message on scanning different key pair QR (#20612) This commit: - update the connection string validation method to use the method from status-go - updates the error message if the user tries to scan a different key pair QR for importing a missing key pair - updates the text for exporting an individual key pair Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com> --- .../java/im/status/ethereum/module/Utils.kt | 5 ++ .../react-native-status/ios/RCTStatus/Utils.m | 4 ++ src/native_module/core.cljs | 8 +++- src/status_im/common/pairing/events.cljs | 6 ++- src/status_im/constants.cljs | 6 ++- .../contexts/settings/wallet/events.cljs | 46 +++++++++++++++---- .../contexts/settings/wallet/events_test.cljs | 10 ++-- .../keypairs_and_accounts/actions/view.cljs | 2 +- src/status_im/contexts/syncing/utils.cljs | 14 ++++-- translations/en.json | 5 +- 10 files changed, 80 insertions(+), 26 deletions(-) diff --git a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/Utils.kt b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/Utils.kt index 564aea425a..0401424312 100644 --- a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/Utils.kt +++ b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/Utils.kt @@ -153,4 +153,9 @@ class Utils(private val reactContext: ReactApplicationContext) : ReactContextBas return strArray } + + @ReactMethod(isBlockingSynchronousMethod = true) + fun validateConnectionString(connectionString: String): String { + return Statusgo.validateConnectionString(connectionString) + } } diff --git a/modules/react-native-status/ios/RCTStatus/Utils.m b/modules/react-native-status/ios/RCTStatus/Utils.m index e9b0149fc3..6f0f35e1fa 100644 --- a/modules/react-native-status/ios/RCTStatus/Utils.m +++ b/modules/react-native-status/ios/RCTStatus/Utils.m @@ -128,4 +128,8 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(toChecksumAddress:(NSString *)address) { return StatusgoToChecksumAddress(address); } +RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(validateConnectionString:(NSString *)cs) { + return StatusgoValidateConnectionString(cs); +} + @end diff --git a/src/native_module/core.cljs b/src/native_module/core.cljs index 44f3f84d24..85b11a7f5e 100644 --- a/src/native_module/core.cljs +++ b/src/native_module/core.cljs @@ -543,6 +543,13 @@ (log/debug "[native-module] validate-mnemonic") (.validateMnemonic ^js (utils) mnemonic callback))) +(defn validate-connection-string + [connection-string] + (log/debug "[native-module] validate-connection-string") + (->> connection-string + (.validateConnectionString ^js (utils)) + types/json->clj)) + (defn delete-multiaccount "Delete multiaccount from database, deletes multiaccount's database and key files." @@ -653,7 +660,6 @@ (native-utils/promisify-native-module-call create-account-from-private-key private-key)) ([private-key callback] (log/debug "[native-module] create-account-from-private-key") - (.createAccountFromPrivateKey ^js (account-manager) (types/clj->json {:privateKey private-key}) callback))) diff --git a/src/status_im/common/pairing/events.cljs b/src/status_im/common/pairing/events.cljs index 7beef829e4..a7791b99d1 100644 --- a/src/status_im/common/pairing/events.cljs +++ b/src/status_im/common/pairing/events.cljs @@ -35,7 +35,9 @@ user-in-syncing-devices-screen? (or (= (:view-id db) :screen/onboarding.syncing-progress) (= (:view-id db) :screen/profile.profiles) (= (:view-id db) :screen/onboarding.syncing-progress-intro)) - user-in-sign-in-intro-screen? (= (:view-id db) :screen/onboarding.sign-in-intro)] + user-in-sign-in-intro-screen? (= (:view-id db) :screen/onboarding.sign-in-intro) + keystore-files-transfer-action? (= action + constants/local-pairing-action-keystore-files-transfer)] (merge {:db (cond-> db connection-success? (assoc-in [:syncing :pairing-status] :connected) @@ -61,7 +63,7 @@ (and completed-pairing? receiver?) {:dispatch [:profile.login/local-paired-user]} - (and error-on-pairing? (some? error)) + (and error-on-pairing? (some? error) (not keystore-files-transfer-action?)) {:dispatch [:toasts/upsert {:type :negative :text error}]})))) diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index e1d32923e6..2b39d36ce9 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -370,16 +370,18 @@ (def ^:const local-pairing-role-receiver "receiver") ;; sender and receiver events +(def ^:const local-pairing-event-peer-discovered "peer-discovered") (def ^:const local-pairing-event-connection-success "connection-success") (def ^:const local-pairing-event-connection-error "connection-error") (def ^:const local-pairing-event-transfer-success "transfer-success") (def ^:const local-pairing-event-transfer-error "transfer-error") +(def ^:const local-pairing-event-received-installation "received-installation") ;; receiver events (def ^:const local-pairing-event-received-account "received-account") (def ^:const local-pairing-event-process-success "process-success") (def ^:const local-pairing-event-process-error "process-error") -(def ^:const local-pairing-event-received-installation "received-installation") +(def ^:const local-pairing-event-received-keystore-files "received-keystore-files") (def ^:const local-pairing-event-errors #{local-pairing-event-connection-error @@ -390,6 +392,8 @@ (def ^:const local-pairing-action-pairing-account 2) (def ^:const local-pairing-action-sync-device 3) (def ^:const local-pairing-action-pairing-installation 4) +(def ^:const local-pairing-action-peer-discovery 5) +(def ^:const local-pairing-action-keystore-files-transfer 6) (def ^:const serialization-key "We pass this serialization key as a parameter to MultiformatSerializePublicKey diff --git a/src/status_im/contexts/settings/wallet/events.cljs b/src/status_im/contexts/settings/wallet/events.cljs index 4bd0908b2b..7c559638f1 100644 --- a/src/status_im/contexts/settings/wallet/events.cljs +++ b/src/status_im/contexts/settings/wallet/events.cljs @@ -1,5 +1,6 @@ (ns status-im.contexts.settings.wallet.events (:require + [clojure.string :as string] [native-module.core :as native-module] [status-im.contexts.settings.wallet.data-store :as data-store] [taoensso.timbre :as log] @@ -91,7 +92,37 @@ (rf/reg-event-fx :wallet/make-keypairs-accounts-fully-operable make-keypairs-accounts-fully-operable) -(defn connection-string-for-import-keypair + +(rf/reg-event-fx :wallet/connection-string-for-import-keypairs-failed + (fn [{:keys [db]} [keypairs-key-uids error]] + (let [error-message (-> error ex-data :error) + incorrect-keypair? (string/includes? + error-message + "one or more expected keystore files are not found among the sent files") + single-keypair-to-update? (= (count keypairs-key-uids) 1) + keypair-name (when single-keypair-to-update? + (let [key-uid (first keypairs-key-uids)] + (get-in db [:wallet :keypairs key-uid :name]))) + toast-message (cond + (and single-keypair-to-update? incorrect-keypair?) + (i18n/label + :t/this-qr-does-not-contain-key-pair + {:name keypair-name}) + + (and (not single-keypair-to-update?) incorrect-keypair?) + (i18n/label + :t/this-qr-does-not-contain-any-missing-key-pair) + + :else + error-message)] + (log/error "failed to import missing key pairs with connection string" + {:error error-message}) + (rf/dispatch [:toasts/upsert + {:type :negative + :theme :dark + :text toast-message}])))) + +(defn connection-string-for-import-keypairs [{:keys [db]} [{:keys [sha3-pwd keypairs-key-uids connection-string]}]] (let [key-uid (get-in db [:profile/profile :key-uid])] {:fx [[:effects.syncing/import-keypairs-keystores @@ -102,14 +133,11 @@ :on-success (fn [key-uids] (rf/dispatch [:wallet/make-keypairs-accounts-fully-operable key-uids])) :on-fail (fn [error] - (log/error "failed to import missing key pairs with connection string" - {:error error}) - (rf/dispatch [:toasts/upsert - {:type :negative - :theme :dark - :text (i18n/label :t/incorrect-qr-code)}]))}]]})) + (rf/dispatch [:wallet/connection-string-for-import-keypairs-failed + keypairs-key-uids + error]))}]]})) -(rf/reg-event-fx :wallet/connection-string-for-import-keypair connection-string-for-import-keypair) +(rf/reg-event-fx :wallet/connection-string-for-import-keypairs connection-string-for-import-keypairs) (defn success-keypair-qr-scan [_ [connection-string keypairs-key-uids]] @@ -121,7 +149,7 @@ :on-auth-success (fn [password] (rf/dispatch [:hide-bottom-sheet]) (rf/dispatch - [:wallet/connection-string-for-import-keypair + [:wallet/connection-string-for-import-keypairs {:connection-string connection-string :keypairs-key-uids keypairs-key-uids :sha3-pwd password}]))}]]]}) diff --git a/src/status_im/contexts/settings/wallet/events_test.cljs b/src/status_im/contexts/settings/wallet/events_test.cljs index dcf0b9c916..7c7f5f27ad 100644 --- a/src/status_im/contexts/settings/wallet/events_test.cljs +++ b/src/status_im/contexts/settings/wallet/events_test.cljs @@ -83,11 +83,11 @@ :on-success fn? :on-fail fn?}]]}] (is (match? expected - (sut/connection-string-for-import-keypair cofx - [{:sha3-pwd sha3-pwd - :keypairs-key-uids [test-keypair-key-uid] - :connection-string - connection-string}]))))) + (sut/connection-string-for-import-keypairs cofx + [{:sha3-pwd sha3-pwd + :keypairs-key-uids [test-keypair-key-uid] + :connection-string + connection-string}]))))) (deftest success-keypair-qr-scan-test (let [connection-string "valid-connection-string" diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/actions/view.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/actions/view.cljs index 6eed006d40..970fa191bd 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/actions/view.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/actions/view.cljs @@ -44,7 +44,7 @@ [{:blur? true :icon :i/qr-code :accessibility-label :show-key-pr-qr - :label (i18n/label :t/show-encrypted-qr-of-key-pairs) + :label (i18n/label :t/show-encrypted-qr-of-key-pair) :on-press on-show-qr}] [{:blur? true :icon :i/scan diff --git a/src/status_im/contexts/syncing/utils.cljs b/src/status_im/contexts/syncing/utils.cljs index f906ee02d9..11910541e0 100644 --- a/src/status_im/contexts/syncing/utils.cljs +++ b/src/status_im/contexts/syncing/utils.cljs @@ -1,15 +1,19 @@ (ns status-im.contexts.syncing.utils (:require [clojure.string :as string] - [status-im.constants :as constants] + [native-module.core :as native-module] [utils.transforms :as transforms])) +(defn validate-connection-string + [connection-string] + (native-module/validate-connection-string + connection-string)) + (defn valid-connection-string? [connection-string] - (when connection-string - (string/starts-with? - connection-string - constants/local-pairing-connection-string-identifier))) + (some-> connection-string + validate-connection-string + string/blank?)) (defn extract-error [json-str] diff --git a/translations/en.json b/translations/en.json index a4452c46ce..f35b1e7b19 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1311,7 +1311,8 @@ "scan-key-pairs-qr-code": "Scan key pairs QR code", "invalid-qr": "Oops! This QR doesn’t work with Status", "invalid-key-pair-qr": "This does not look like a key pair QR code", - "incorrect-qr-code": "This is not the QR code you are looking for", + "this-qr-does-not-contain-key-pair": "This QR does not contain {{name}} key pair", + "this-qr-does-not-contain-any-missing-key-pair": "This QR does not contain any missing key pairs", "search": "Search", "search-discover-communities": "Search communities or categories", "secret-keys-confirmation-text": "You will need them to continue to use your Keycard in case you ever lose your phone.", @@ -1363,7 +1364,7 @@ "show-more": "Show more", "show-qr": "Show QR code", "show-transaction-data": "Show transaction data", - "show-encrypted-qr-of-key-pairs": "Show encrypted QR of key pairs on device", + "show-encrypted-qr-of-key-pair": "Show encrypted QR of key pair", "sign-and-send": "Sign and send", "sign-in": "Sign in", "sign-message": "Sign Message",