add creation of backup keycards

Signed-off-by: Michele Balistreri <michele@bitgamma.com>
This commit is contained in:
Michele Balistreri 2021-03-25 16:39:13 +03:00
parent be0ad943ea
commit f0827ff624
No known key found for this signature in database
GPG Key ID: E9567DA33A4F791A
8 changed files with 113 additions and 24 deletions

View File

@ -0,0 +1,40 @@
(ns status-im.keycard.backup-key
(:require [status-im.utils.fx :as fx]
[status-im.ethereum.mnemonic :as mnemonic]
[status-im.multiaccounts.recover.core :as multiaccounts.recover]
[status-im.navigation :as navigation]
[taoensso.timbre :as log]))
(fx/defn backup-card-pressed
{:events [:keycard-settings.ui/backup-card-pressed]}
[{:keys [db] :as cofx}]
(log/debug "[keycard] start backup")
(fx/merge cofx
{:db (-> db
(assoc-in [:keycard :creating-backup?] true))}
(navigation/navigate-to-cofx :seed-phrase nil)))
(fx/defn start-keycard-backup
{:events [::start-keycard-backup]}
[{:keys [db] :as cofx}]
{::multiaccounts.recover/import-multiaccount {:passphrase (-> db
:multiaccounts/key-storage
:seed-phrase
mnemonic/sanitize-passphrase)
:password nil
:success-event ::create-backup-card}})
(fx/defn create-backup-card
{:events [::create-backup-card]}
[{:keys [db] :as cofx} root-data derived-data]
(fx/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)
(update :multiaccounts/key-storage dissoc :seed-phrase))
:dismiss-keyboard nil}
(navigation/navigate-to-cofx :keycard-onboarding-intro nil)))

View File

@ -5,6 +5,7 @@
status-im.keycard.delete-key
status-im.keycard.export-key
status-im.keycard.unpair
status-im.keycard.backup-key
[status-im.keycard.login :as login]
[status-im.keycard.mnemonic :as mnemonic]
[status-im.keycard.onboarding :as onboarding]
@ -65,8 +66,9 @@
"instance-uid" instance-uid)
(if (= flow :import)
(navigation/navigate-to-cofx cofx :keycard-recovery-no-key nil)
(let [pairing-data (get-in db [:keycard :pairings instance-uid])]
(if pairing-data
(let [pairing-data (get-in db [:keycard :pairings (keyword instance-uid)])
paired? (get-in db [:keycard :application-info :paired?])]
(if paired?
(fx/merge cofx
{:db (update-in db [:keycard :secrets] merge pairing-data)}
(common/listen-to-hardware-back-button)

View File

@ -197,12 +197,20 @@
(navigation/navigate-to-cofx (if platform/android?
:notifications-settings :welcome) nil))))))
(fx/defn on-backup-success
[{:keys [db] :as cofx}]
(fx/merge cofx
{:utils/show-popup {:title (i18n/label :t/keycard-backup-success-title)
:content (i18n/label :t/keycard-backup-success-body)}}
(navigation/navigate-to-cofx :keycard-settings nil)))
(fx/defn on-generate-and-load-key-success
{:events [:keycard.callback/on-generate-and-load-key-success]
:interceptors [(re-frame/inject-cofx :random-guid-generator)
(re-frame/inject-cofx ::multiaccounts.create/get-signing-phrase)]}
[{:keys [db random-guid-generator] :as cofx} data]
(let [account-data (js->clj data :keywordize-keys true)]
(let [account-data (js->clj data :keywordize-keys true)
backup? (get-in db [:keycard :creating-backup?])]
(fx/merge cofx
{:db (-> db
(assoc-in [:keycard :multiaccount]
@ -222,12 +230,13 @@
(assoc-in [:keycard :application-info :key-uid]
(ethereum/normalized-hex (:key-uid account-data)))
(update :keycard dissoc :recovery-phrase)
(update :keycard dissoc :creating-backup?)
(update-in [:keycard :secrets] dissoc :pin :puk :password)
(assoc :multiaccounts/new-installation-id (random-guid-generator))
(update-in [:keycard :secrets] dissoc :mnemonic))}
(common/remove-listener-to-hardware-back-button)
(common/hide-connection-sheet)
(create-keycard-multiaccount))))
(if backup? (on-backup-success) (create-keycard-multiaccount)))))
(fx/defn on-generate-and-load-key-error
{:events [:keycard.callback/on-generate-and-load-key-error]}

View File

@ -10,7 +10,8 @@
[status-im.popover.core :as popover]
[status-im.utils.fx :as fx]
[status-im.utils.security :as security]
[status-im.utils.types :as types]))
[status-im.utils.types :as types]
[status-im.keycard.backup-key :as keycard.backup]))
(fx/defn key-and-storage-management-pressed
"This event can be dispatched before login and from profile and needs to redirect accordingly"
@ -53,6 +54,14 @@
[cofx _]
(popover/show-popover cofx {:view :seed-key-uid-mismatch}))
(fx/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 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]}]
@ -70,7 +79,7 @@
::validate-seed-against-key-uid
(partial validate-seed-against-key-uid
{:import-mnemonic-fn native-module/multiaccount-import-mnemonic
:on-success #(re-frame/dispatch [:navigate-to :storage])
:on-success #(re-frame/dispatch [::key-uid-matches])
:on-error #(re-frame/dispatch [::show-seed-key-uid-mismatch-error-popup])}))
(fx/defn seed-phrase-validated
@ -85,7 +94,7 @@
(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 (-> db :multiaccounts/login :key-uid)}})))
:key-uid (or (-> db :multiaccounts/login :key-uid) (-> db :multiaccount :key-uid))}})))
(fx/defn choose-storage-pressed
{:events [::choose-storage-pressed]}

View File

@ -95,19 +95,15 @@
:on-press #(re-frame/dispatch [:keycard-settings.ui/change-pin-pressed])}]
;; TODO(rasom): uncomment this when unpairing will be enabled
;; https://github.com/status-im/status-react/issues/9227
[quo/list-item {:icon :main-icons/keycard
:size :small
:title (i18n/label :t/keycard-backup)
:accessibility-label "create-backup-keycard"
:on-press #(re-frame/dispatch [:keycard-settings.ui/backup-card-pressed])}]
#_[quo/list-item {:icon :main-icons/close
:size :small
:title (i18n/label :t/unpair-card)
:on-press #(re-frame/dispatch [:keycard-settings.ui/unpair-card-pressed])}]])])]
; NOTE: Reset card is hidden until multiaccount removal will be implemented
#_(when pairing
[react/view {:margin-bottom 35
:margin-left 16}
[quo/list-item {:icon :main-icons/warning
:theme :negative
:size :small
:title (i18n/label :t/reset-card)
:on-press #(re-frame/dispatch [:keycard-settings.ui/reset-card-pressed])}]])]]))
:on-press #(re-frame/dispatch [:keycard-settings.ui/unpair-card-pressed])}]])])]]]))
(defn reset-pin []
[keycard.views/login-pin

View File

@ -103,7 +103,8 @@
(defview seed-phrase []
(letsubs
[{:keys [seed-word-count seed-shape-invalid?]} [:multiaccounts/key-storage]]
[{:keys [seed-word-count seed-shape-invalid?]} [:multiaccounts/key-storage]
{:keys [creating-backup?]} [:keycard]]
[react/keyboard-avoiding-view {:flex 1}
[local-topbar (i18n/label :t/enter-seed-phrase)]
[multiaccounts.views/seed-phrase-input
@ -122,7 +123,7 @@
(nil? seed-shape-invalid?))
:on-press #(re-frame/dispatch [::multiaccounts.key-storage/choose-storage-pressed])
:after :main-icons/next}
(i18n/label :t/choose-storage)]}]]))
(i18n/label (if creating-backup? :t/next :t/choose-storage))]}]]))
(defn keycard-subtitle []
[react/view
@ -197,7 +198,8 @@
(i18n/label :t/confirm)]}]]]))
(defview seed-key-uid-mismatch-popover []
(letsubs [{:keys [name]} [:multiaccounts/login]]
(letsubs [{:keys [name]} [:multiaccounts/login]
{logged-in-name :name} [:multiaccount]]
[react/view {:margin-top 24
:margin-horizontal 24
:align-items :center}
@ -215,7 +217,7 @@
[react/view
[react/text {:style (into styles/popover-text
{:margin-bottom 16})}
(i18n/label :t/seed-key-uid-mismatch-desc-1 {:multiaccount-name name})]
(i18n/label :t/seed-key-uid-mismatch-desc-1 {:multiaccount-name (or name logged-in-name)})]
[react/text {:style styles/popover-text}
(i18n/label :t/seed-key-uid-mismatch-desc-2)]]]
[react/view {:margin-vertical 24

View File

@ -27,7 +27,12 @@
[status-im.ui.screens.status.new.views :as status.new]
[status-im.ui.screens.browser.bookmarks.views :as bookmarks]
[status-im.ui.screens.routing.status-stack :as status-stack]
[status-im.ui.screens.communities.invite :as communities.invite]))
[status-im.ui.screens.communities.invite :as communities.invite]
[status-im.ui.screens.keycard.onboarding.views :as keycard.onboarding]
[status-im.ui.screens.keycard.recovery.views :as keycard.recovery]
[status-im.keycard.core :as keycard.core]
[status-im.ui.screens.keycard.views :as keycard]
[status-im.ui.screens.multiaccounts.key-storage.views :as key-storage.views]))
(defonce main-stack (navigation/create-stack))
(defonce bottom-tabs (navigation/create-bottom-tabs))
@ -55,7 +60,8 @@
:component profile-stack/profile-stack}]])
(views/defview get-main-component [_]
(views/letsubs [logged-in? [:multiaccount/logged-in?]]
(views/letsubs [logged-in? [:multiaccount/logged-in?]
keycard-account? [:multiaccounts/keycard-account?]]
[main-stack (merge {:header-mode :none}
;; https://github.com/react-navigation/react-navigation/issues/6520
(when platform/ios?
@ -170,4 +176,26 @@
(when config/quo-preview-enabled?
[{:name :quo-preview
:insets {:top false :bottom false}
:component quo.preview/preview-stack}]))]))
:component quo.preview/preview-stack}])
(when keycard-account?
[{:name :keycard-onboarding-intro
:back-handler keycard.core/onboarding-intro-back-handler
:component keycard.onboarding/intro}
{:name :keycard-onboarding-puk-code
:back-handler :noop
:component keycard.onboarding/puk-code}
{:name :keycard-onboarding-pin
:back-handler :noop
:component keycard.onboarding/pin}
{:name :keycard-recovery-pair
:back-handler :noop
:component keycard.recovery/pair}
{:name :seed-phrase
:component key-storage.views/seed-phrase}
{:name :keycard-recovery-pin
:component keycard.recovery/pin}
{:name :keycard-wrong
:component keycard/wrong}
{:name :not-keycard
:component keycard/not-keycard}]))]))

View File

@ -1211,6 +1211,9 @@
"keycard-error-description": "Connect the card again to continue",
"keycard-success-title": "Success",
"keycard-success-description": "You may remove the card now",
"keycard-backup": "Create a backup Keycard",
"keycard-backup-success-title": "Backup successful",
"keycard-backup-success-body": "Backup card created successfully. You can now use it with your account just like the primary card.",
"type-a-message": "Message",
"ulc-enabled": "ULC enabled",
"unable-to-read-this-code": "Unable to read this code",