[#21446] Keycard - Current profile key pair migrate (#21558)

[#21470] Keycard - Keycard initialized but has no keys
This commit is contained in:
flexsurfer 2024-11-05 14:48:45 +01:00 committed by GitHub
parent e43a328c6f
commit 03ec410862
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 113 additions and 46 deletions

View File

@ -1,6 +1,5 @@
(ns status-im.contexts.keycard.migrate.events (ns status-im.contexts.keycard.migrate.events
(:require [clojure.string :as string] (:require [clojure.string :as string]
[status-im.contexts.keycard.pin.view :as keycard.pin]
[utils.re-frame :as rf] [utils.re-frame :as rf]
[utils.security.core :as security])) [utils.security.core :as security]))
@ -11,12 +10,8 @@
{:key-uid (get-in db [:profile/profile :key-uid]) {:key-uid (get-in db [:profile/profile :key-uid])
:on-success :on-success
(fn [] (fn []
;;TODO keys already on the keycard, new flow needs to be implemented
;; https://github.com/status-im/status-mobile/issues/21446
(rf/dispatch [:keycard/disconnect]) (rf/dispatch [:keycard/disconnect])
(rf/dispatch [:open-modal :screen/keycard.authorise (rf/dispatch [:open-modal :screen/keycard.profile-keys]))
{:on-success
#(rf/dispatch [:keycard/migration.authorisation-success %])}]))
:on-error :on-error
(fn [error] (fn [error]
(if (= error :keycard/error.keycard-blank) (if (= error :keycard/error.keycard-blank)
@ -40,31 +35,27 @@
(fn [{:keys [db]}] (fn [{:keys [db]}]
(let [key-uid (get-in db [:profile/profile :key-uid]) (let [key-uid (get-in db [:profile/profile :key-uid])
{:keys [initialized? has-master-key?]} (get-in db [:keycard :application-info]) {:keys [initialized? has-master-key?]} (get-in db [:keycard :application-info])
{:keys [masked-phrase pin]} (get-in db [:keycard :migration]) {:keys [masked-phrase pin]} (get-in db [:keycard :migration])]
on-failure (fn []
(rf/dispatch [:keycard/disconnect])
(rf/dispatch [:navigate-to
:screen/keycard.migrate.fail]))]
(cond (cond
(not initialized?) (not initialized?)
{:fx [[:keycard/init-card {:fx [[:keycard/init-card
{:pin pin {:pin pin
:on-success #(get-application-info-and-continue key-uid) :on-success #(get-application-info-and-continue key-uid)}]]}
:on-failure on-failure}]]}
(not has-master-key?) (not has-master-key?)
{:fx [[:effects.keycard/generate-and-load-key {:fx [[:effects.keycard/generate-and-load-key
{:mnemonic (security/safe-unmask-data masked-phrase) {:mnemonic (security/safe-unmask-data masked-phrase)
:pin pin :pin pin
:on-success #(get-application-info-and-continue key-uid) :on-success #(get-application-info-and-continue key-uid)
:on-failure on-failure}]]} :on-failure #(rf/dispatch [:keycard/on-action-with-pin-error %])}]]}
:else :else
{:fx [[:effects.keycard/get-keys {:fx [[:effects.keycard/get-keys
{:pin pin {:pin pin
:on-success #(rf/dispatch [:keycard/migration.convert-to-keycard-profile %]) :on-success #(rf/dispatch [:keycard/migration.convert-to-keycard-profile %])
:on-failure on-failure}]]})))) :on-failure #(rf/dispatch [:keycard/on-action-with-pin-error %])}]]}))))
(rf/reg-event-fx :keycard/migration.start (rf/reg-event-fx :keycard/migration.start
(fn [{:keys [db]}] (fn [{:keys [db]}]
@ -115,11 +106,7 @@
{:db (assoc-in db [:keycard :migration :masked-password] masked-password) {:db (assoc-in db [:keycard :migration :masked-password] masked-password)
:fx [[:dispatch [:navigate-back]] :fx [[:dispatch [:navigate-back]]
(if initialized? (if initialized?
[:dispatch [:dispatch [:open-modal :screen/keycard.migrate]]
[:show-bottom-sheet
{:content (fn []
[keycard.pin/auth
{:on-complete #(rf/dispatch [:keycard/migration.pin-created %])}])}]]
[:dispatch [:dispatch
[:open-modal :screen/keycard.pin.create [:open-modal :screen/keycard.pin.create
{:on-complete (fn [new-pin] {:on-complete (fn [new-pin]
@ -130,3 +117,8 @@
(fn [{:keys [db]} [pin]] (fn [{:keys [db]} [pin]]
{:db (assoc-in db [:keycard :migration :pin] pin) {:db (assoc-in db [:keycard :migration :pin] pin)
:fx [[:dispatch [:open-modal :screen/keycard.migrate]]]})) :fx [[:dispatch [:open-modal :screen/keycard.migrate]]]}))
(rf/reg-event-fx :keycard/migration.pin-entered
(fn [{:keys [db]} [pin]]
{:db (assoc-in db [:keycard :migration :pin] pin)
:fx [[:dispatch [:keycard/migration.start]]]}))

View File

@ -0,0 +1,34 @@
(ns status-im.contexts.keycard.migrate.profile-keys.view
(:require [quo.core :as quo]
[react-native.core :as rn]
[status-im.common.events-helper :as events-helper]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn view
[]
[:<>
[quo/page-nav
{:icon-name :i/close
:on-press events-helper/navigate-back}]
[quo/page-top
{:title (i18n/label :t/keycard-contains-key-pair)
:description :text
:description-text (i18n/label :t/finalise-migration-instructions)}]
[rn/view {:style {:margin-horizontal 20}}
[rn/view {:style {:padding-top 8 :padding-bottom 20}}
[quo/keycard {:holder-name ""}]]
[quo/section-label {:section (i18n/label :t/what-you-can-do) :container-style {:padding-vertical 8}}]
[quo/settings-item
{:title (i18n/label :t/finalise-migration)
:image :icon
:image-props :i/profile
:action :arrow
:description :text
:description-props {:text (i18n/label :t/use-keycard-instead-password)}
:on-press (fn []
(rf/dispatch [:navigate-back])
(rf/dispatch [:open-modal :screen/keycard.authorise
{:on-success
#(rf/dispatch [:keycard/migration.authorisation-success
%])}]))}]]])

View File

@ -10,7 +10,8 @@
[] []
(let [profile-name (rf/sub [:profile/name]) (let [profile-name (rf/sub [:profile/name])
profile-picture (rf/sub [:profile/image]) profile-picture (rf/sub [:profile/image])
customization-color (rf/sub [:profile/customization-color])] customization-color (rf/sub [:profile/customization-color])
initialized? (rf/sub [:keycard/initialized?])]
[:<> [:<>
[quo/page-nav [quo/page-nav
{:icon-name :i/close {:icon-name :i/close
@ -30,5 +31,13 @@
[quo/markdown-list {:description (i18n/label :t/keep-card-steady)}] [quo/markdown-list {:description (i18n/label :t/keep-card-steady)}]
[quo/bottom-actions [quo/bottom-actions
{:actions :one-action {:actions :one-action
:button-one-label (i18n/label :t/scan-keycard) :button-one-label (if initialized? (i18n/label :t/enter-keycard-pin) (i18n/label :t/scan-keycard))
:button-one-props {:on-press #(rf/dispatch [:keycard/migration.start])}}]])) :button-one-props {:on-press
(fn []
(if initialized?
(do
(rf/dispatch [:navigate-back])
(rf/dispatch [:open-modal :screen/keycard.pin.enter
{:on-complete #(rf/dispatch
[:keycard/migration.pin-entered %])}]))
(rf/dispatch [:keycard/migration.start])))}}]]))

View File

@ -49,7 +49,7 @@
(i18n/label :t/create-keycard-pin) (i18n/label :t/create-keycard-pin)
(i18n/label :t/repeat-keycard-pin)) (i18n/label :t/repeat-keycard-pin))
:description :text :description :text
:description-text "Youll need this PIN to login and sign transactions"}] :description-text (i18n/label :t/pin-needed-login-sign)}]
[rn/view {:style {:flex 1 :justify-content :center :align-items :center :padding-vertical 34}} [rn/view {:style {:flex 1 :justify-content :center :align-items :center :padding-vertical 34}}
[quo/pin-input [quo/pin-input
{:blur? false {:blur? false

View File

@ -0,0 +1,18 @@
(ns status-im.contexts.keycard.pin.enter.view
(:require [quo.core :as quo]
[react-native.core :as rn]
[status-im.common.events-helper :as events-helper]
[status-im.contexts.keycard.pin.view :as keycard.pin]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn view
[]
(let [{:keys [on-complete]} (rf/sub [:get-screen-params])]
[rn/view {:style {:padding-bottom 12 :flex 1}}
[quo/page-nav
{:icon-name :i/close
:on-press events-helper/navigate-back}]
[quo/page-top {:title (i18n/label :t/enter-keycard-pin)}]
[rn/view {:style {:flex 1}}]
[keycard.pin/auth {:on-complete on-complete}]]))

View File

@ -33,11 +33,13 @@
[status-im.contexts.keycard.empty.view :as keycard.empty] [status-im.contexts.keycard.empty.view :as keycard.empty]
[status-im.contexts.keycard.error.view :as keycard.error] [status-im.contexts.keycard.error.view :as keycard.error]
[status-im.contexts.keycard.migrate.fail.view :as keycard.migrate.fail] [status-im.contexts.keycard.migrate.fail.view :as keycard.migrate.fail]
[status-im.contexts.keycard.migrate.profile-keys.view :as keycard.migrate.profile-keys]
[status-im.contexts.keycard.migrate.re-encrypting.view :as keycard.re-encrypting] [status-im.contexts.keycard.migrate.re-encrypting.view :as keycard.re-encrypting]
[status-im.contexts.keycard.migrate.success.view :as keycard.migrate.success] [status-im.contexts.keycard.migrate.success.view :as keycard.migrate.success]
[status-im.contexts.keycard.migrate.view :as keycard.migrate] [status-im.contexts.keycard.migrate.view :as keycard.migrate]
[status-im.contexts.keycard.not-keycard.view :as keycard.not-keycard] [status-im.contexts.keycard.not-keycard.view :as keycard.not-keycard]
[status-im.contexts.keycard.pin.create.view :as pin.create] [status-im.contexts.keycard.pin.create.view :as keycard.pin.create]
[status-im.contexts.keycard.pin.enter.view :as keycard.pin.enter]
[status-im.contexts.onboarding.create-or-sync-profile.view :as create-or-sync-profile] [status-im.contexts.onboarding.create-or-sync-profile.view :as create-or-sync-profile]
[status-im.contexts.onboarding.create-password.view :as create-password] [status-im.contexts.onboarding.create-password.view :as create-password]
[status-im.contexts.onboarding.create-profile.view :as create-profile] [status-im.contexts.onboarding.create-profile.view :as create-profile]
@ -883,44 +885,37 @@
(def keycard-screens (def keycard-screens
[{:name :screen/keycard.check [{:name :screen/keycard.check
:metrics {:track? :true :metrics {:track? :true}
:alias-id :keycard.check}
:options {:insets {:top? true :bottom? true}} :options {:insets {:top? true :bottom? true}}
:component keycard.check/view} :component keycard.check/view}
{:name :screen/keycard.empty {:name :screen/keycard.empty
:metrics {:track? :true :metrics {:track? :true}
:alias-id :keycard.empty}
:options {:insets {:top? true :bottom? true}} :options {:insets {:top? true :bottom? true}}
:component keycard.empty/view} :component keycard.empty/view}
{:name :screen/keycard.error {:name :screen/keycard.error
:metrics {:track? :true :metrics {:track? :true}
:alias-id :keycard.error}
:options {:insets {:top? true :bottom? true}} :options {:insets {:top? true :bottom? true}}
:component keycard.error/view} :component keycard.error/view}
{:name :screen/keycard.not-keycard {:name :screen/keycard.not-keycard
:metrics {:track? :true :metrics {:track? :true}
:alias-id :keycard.not-keycard}
:options {:insets {:top? true :bottom? true}} :options {:insets {:top? true :bottom? true}}
:component keycard.not-keycard/view} :component keycard.not-keycard/view}
{:name :screen/keycard.authorise {:name :screen/keycard.authorise
:metrics {:track? :true :metrics {:track? :true}
:alias-id :keycard.authorise}
:options {:insets {:top? true :bottom? true}} :options {:insets {:top? true :bottom? true}}
:component keycard.authorise/view} :component keycard.authorise/view}
{:name :screen/keycard.migrate {:name :screen/keycard.migrate
:metrics {:track? :true :metrics {:track? :true}
:alias-id :keycard.migrate}
:options {:insets {:top? true :bottom? true}} :options {:insets {:top? true :bottom? true}}
:component keycard.migrate/view} :component keycard.migrate/view}
{:name :screen/keycard.re-encrypting {:name :screen/keycard.re-encrypting
:metrics {:track? :true :metrics {:track? :true}
:alias-id :keycard.re-encrypting}
:options {:insets {:top? true :bottom? true} :options {:insets {:top? true :bottom? true}
:popGesture false :popGesture false
:hardwareBackButton {:dismissModalOnPress false :hardwareBackButton {:dismissModalOnPress false
@ -928,8 +923,7 @@
:component keycard.re-encrypting/view} :component keycard.re-encrypting/view}
{:name :screen/keycard.migrate.success {:name :screen/keycard.migrate.success
:metrics {:track? :true :metrics {:track? :true}
:alias-id :keycard.migrate.success}
:options {:insets {:top? true :bottom? true} :options {:insets {:top? true :bottom? true}
:popGesture false :popGesture false
:hardwareBackButton {:dismissModalOnPress false :hardwareBackButton {:dismissModalOnPress false
@ -937,8 +931,7 @@
:component keycard.migrate.success/view} :component keycard.migrate.success/view}
{:name :screen/keycard.migrate.fail {:name :screen/keycard.migrate.fail
:metrics {:track? :true :metrics {:track? :true}
:alias-id :keycard.migrate.fail}
:options {:insets {:top? true :bottom? true} :options {:insets {:top? true :bottom? true}
:popGesture false :popGesture false
:hardwareBackButton {:dismissModalOnPress false :hardwareBackButton {:dismissModalOnPress false
@ -946,10 +939,19 @@
:component keycard.migrate.fail/view} :component keycard.migrate.fail/view}
{:name :screen/keycard.pin.create {:name :screen/keycard.pin.create
:metrics {:track? :true :metrics {:track? :true}
:alias-id :keycard.pin.create}
:options {:insets {:top? true :bottom? true}} :options {:insets {:top? true :bottom? true}}
:component pin.create/view}]) :component keycard.pin.create/view}
{:name :screen/keycard.pin.enter
:metrics {:track? :true}
:options {:insets {:top? true :bottom? true}}
:component keycard.pin.enter/view}
{:name :screen/keycard.profile-keys
:metrics {:track? :true}
:options {:insets {:top? true :bottom? true}}
:component keycard.migrate.profile-keys/view}])
(defn screens (defn screens
[] []

View File

@ -41,3 +41,9 @@
:<- [:keycard] :<- [:keycard]
(fn [keycard] (fn [keycard]
(:application-info-error keycard))) (:application-info-error keycard)))
(rf/reg-sub
:keycard/initialized?
:<- [:keycard]
(fn [keycard]
(get-in keycard [:application-info :initialized?])))

View File

@ -965,6 +965,7 @@
"enter-chat-key": "Enter chat key or scan a QR", "enter-chat-key": "Enter chat key or scan a QR",
"enter-contact-code": "ENS (vitalik94) or chat key (0x04…)", "enter-contact-code": "ENS (vitalik94) or chat key (0x04…)",
"enter-eth": "Enter any ETH address or ENS name.", "enter-eth": "Enter any ETH address or ENS name.",
"enter-keycard-pin": "Enter Keycard PIN",
"enter-pair-code": "Enter your pairing code", "enter-pair-code": "Enter your pairing code",
"enter-pair-code-description": "Pairing code can be set from an already paired Status client", "enter-pair-code-description": "Pairing code can be set from an already paired Status client",
"enter-password": "Enter password", "enter-password": "Enter password",
@ -1033,6 +1034,8 @@
"fetch-timeline": "↓ Fetch", "fetch-timeline": "↓ Fetch",
"fetching-community": "Fetching community...", "fetching-community": "Fetching community...",
"fetching-the-price-took-longer-than-expected": "Fetching the price took longer than expected.\nPlease, try again later.", "fetching-the-price-took-longer-than-expected": "Fetching the price took longer than expected.\nPlease, try again later.",
"finalise-migration": "Finalise migration",
"finalise-migration-instructions": "Finalise migration to use this Keycard for logging in and signing transactions on this device",
"finalized-on": "Finalized on", "finalized-on": "Finalized on",
"find": "Find", "find": "Find",
"find-it-in-setting": "Find it in Settings on your other synced device", "find-it-in-setting": "Find it in Settings on your other synced device",
@ -1339,6 +1342,7 @@
"keycard-cancel-setup-title": "Dangerous operation", "keycard-cancel-setup-title": "Dangerous operation",
"keycard-connected-description": "Try keeping the card still", "keycard-connected-description": "Try keeping the card still",
"keycard-connected-title": "Connected", "keycard-connected-title": "Connected",
"keycard-contains-key-pair": "Keycard contains your profile key pair",
"keycard-desc": "Own a Keycard? Store your keys on it; youll need it for transactions", "keycard-desc": "Own a Keycard? Store your keys on it; youll need it for transactions",
"keycard-dont-ask-card": "Don't ask for card to sign in", "keycard-dont-ask-card": "Don't ask for card to sign in",
"keycard-empty": "Keycard is empty", "keycard-empty": "Keycard is empty",
@ -1945,6 +1949,7 @@
"pin-code": "6-digit passcode", "pin-code": "6-digit passcode",
"pin-limit-reached": "Pin limit reached. Unpin a previous message first.", "pin-limit-reached": "Pin limit reached. Unpin a previous message first.",
"pin-mismatch": "Wrong passcode", "pin-mismatch": "Wrong passcode",
"pin-needed-login-sign": "Youll need this PIN to login and sign transactions",
"pin-not-match": "PIN do not match", "pin-not-match": "PIN do not match",
"pin-one-attempt": " one attempt ", "pin-one-attempt": " one attempt ",
"pin-one-attempt-blocked-after": "before your Keycard gets blocked", "pin-one-attempt-blocked-after": "before your Keycard gets blocked",
@ -2678,6 +2683,7 @@
"use-biometrics": "Use biometrics to fill in your password", "use-biometrics": "Use biometrics to fill in your password",
"use-keycard": "Use Keycard", "use-keycard": "Use Keycard",
"use-keycard-for-status": "From now on, use this Keycard to login to Status and transact with derived accounts on all synced devices. To start using it, logout and log back in with this Keycard.", "use-keycard-for-status": "From now on, use this Keycard to login to Status and transact with derived accounts on all synced devices. To start using it, logout and log back in with this Keycard.",
"use-keycard-instead-password": "To use Keycard instead of password",
"use-keycard-login-sign": "Use this Keycard to login and sign transactions", "use-keycard-login-sign": "Use this Keycard to login and sign transactions",
"use-keycard-subtitle": "Keys will be stored on your Keycard", "use-keycard-subtitle": "Keys will be stored on your Keycard",
"use-photo": "Use Photo", "use-photo": "Use Photo",