Skip to content

Commit

Permalink
[#21993] Keycard - Unlock Keycard (#22030)
Browse files Browse the repository at this point in the history
  • Loading branch information
flexsurfer authored Feb 10, 2025
1 parent 8c089bb commit ed10ed7
Show file tree
Hide file tree
Showing 11 changed files with 221 additions and 33 deletions.
10 changes: 5 additions & 5 deletions src/status_im/contexts/keycard/backup/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
{:theme :dark
:on-error
(fn [error]
(if (= error :keycard/error.keycard-blank)
(if (= error :keycard/error.keycard-empty)
(rf/dispatch [:keycard/backup.generate-and-load-key])
(ready-to-add-not-empty error)))}]]]}))

Expand All @@ -52,7 +52,7 @@
{:theme :dark
:on-error
(fn [error]
(if (= error :keycard/error.keycard-blank)
(if (= error :keycard/error.keycard-empty)
(do
(rf/dispatch [:keycard/disconnect])
(rf/dispatch [:keycard/backup.create-or-enter-pin]))
Expand All @@ -78,7 +78,7 @@
{:theme :dark
:on-error
(fn [error]
(if (= error :keycard/error.keycard-blank)
(if (= error :keycard/error.keycard-empty)
(rf/dispatch
[:keycard/verify-pin
{:pin pin
Expand All @@ -95,15 +95,15 @@
{:theme :dark
:on-error
(fn [error]
(if (= error :keycard/error.keycard-blank)
(if (= error :keycard/error.keycard-empty)
(rf/dispatch
[:keycard/init-card
{:pin pin
:on-success #(rf/dispatch
[:keycard/get-application-info
{:on-error
(fn [error]
(if (= error :keycard/error.keycard-blank)
(if (= error :keycard/error.keycard-empty)
(save-pin-and-navigate-to-phrase pin)
(init-card-not-empty pin error)))}])}])
(init-card-not-empty pin error)))}]))
Expand Down
2 changes: 1 addition & 1 deletion src/status_im/contexts/keycard/check/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
:on-error
(fn [error]
(rf/dispatch [:navigate-back])
(if (and (= error :keycard/error.keycard-blank)
(if (and (= error :keycard/error.keycard-empty)
(not keycard-profile?))
(do
(rf/dispatch [:keycard/disconnect])
Expand Down
4 changes: 2 additions & 2 deletions src/status_im/contexts/keycard/create/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{:theme :dark
:on-error
(fn [error]
(if (= error :keycard/error.keycard-blank)
(if (= error :keycard/error.keycard-empty)
(do
(rf/dispatch [:keycard/disconnect])
(rf/dispatch [:open-modal :screen/keycard.empty-create]))
Expand Down Expand Up @@ -74,7 +74,7 @@

(rf/reg-event-fx :keycard/create.on-application-info-error
(fn [{:keys [db]} [error]]
(if (or (= error :keycard/error.keycard-blank)
(if (or (= error :keycard/error.keycard-empty)
(and (get-in db [:keycard :application-info :initialized?])
(= error :keycard/error.keycard-wrong-profile)))
(rf/dispatch [:keycard/create.continue])
Expand Down
42 changes: 28 additions & 14 deletions src/status_im/contexts/keycard/error/view.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
[status-im.common.events-helper :as events-helper]
[status-im.contexts.keycard.backup.view :as backup.view]
[status-im.contexts.keycard.factory-reset.view :as factory-reset]
[status-im.contexts.keycard.unblock.view :as keycard.unblock]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))

(def titles
{:keycard/error.keycard-blank {:title (i18n/label :t/keycard-empty)
{:keycard/error.keycard-empty {:title (i18n/label :t/keycard-empty)
:description (i18n/label :t/no-key-pair-keycard)}
:keycard/error.keycard-wrong-profile {:title (i18n/label :t/keycard-not-empty)
:description (i18n/label :t/cant-store-new-keys)}
Expand All @@ -35,7 +36,7 @@
[quo/keycard {:holder-name ""}]
[quo/section-label
{:section (i18n/label :t/what-you-can-do) :container-style {:padding-vertical 8}}]
(if (= error :keycard/error.keycard-blank)
(if (= error :keycard/error.keycard-empty)
[quo/settings-item
{:title (i18n/label :t/use-backup-keycard)
:image :icon
Expand All @@ -51,15 +52,28 @@
{:on-continue
(rf/dispatch
[:keycard/backup.create-or-enter-pin])}])}]))}]
[quo/settings-item
{:title (i18n/label :t/factory-reset)
:image :icon
:image-props :i/placeholder
:action :arrow
:description :text
:description-props {:text (i18n/label :t/remove-keycard-content)}
:on-press (fn []
(rf/dispatch [:show-bottom-sheet
{:theme :dark
:shell? true
:content factory-reset/sheet}]))}])]]))
[:<>
(when (or (= error :keycard/error.keycard-frozen)
(= error :keycard/error.keycard-locked))
[quo/settings-item
{:title (i18n/label :t/unblock-keycard)
:image :icon
:image-props :i/placeholder
:action :arrow
:description :text
:description-props {:text (i18n/label :t/with-recovery-phrase)}
:on-press (fn []
(rf/dispatch [:show-bottom-sheet
{:content keycard.unblock/sheet}]))}])
[quo/settings-item
{:title (i18n/label :t/factory-reset)
:image :icon
:image-props :i/placeholder
:action :arrow
:description :text
:description-props {:text (i18n/label :t/remove-keycard-content)}
:on-press (fn []
(rf/dispatch [:show-bottom-sheet
{:theme :dark
:shell? true
:content factory-reset/sheet}]))}]])]]))
23 changes: 16 additions & 7 deletions src/status_im/contexts/keycard/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
status-im.contexts.keycard.nfc.sheets.events
status-im.contexts.keycard.pin.events
status-im.contexts.keycard.sign.events
status-im.contexts.keycard.unblock.events
[status-im.contexts.keycard.utils :as keycard.utils]
[utils.address :as address]
utils.datetime
Expand Down Expand Up @@ -160,14 +161,22 @@
(rf/dispatch [:keycard/on-application-info-error
:keycard/error.not-keycard]))))}}))

(rf/reg-event-fx :keycard/connect.next-stage
(fn [{:keys [db]} [{:keys [key-uid on-success on-error]}]]
(let [event-vector [:keycard/get-application-info
{:key-uid key-uid
:on-success on-success
:on-error on-error}]]
{:db (assoc-in db [:keycard :on-card-connected-event-vector] event-vector)
:fx [(when (get-in db [:keycard :card-connected?])
[:dispatch event-vector])]})))

(rf/reg-event-fx :keycard/connect
(fn [{:keys [db]} [{:keys [key-uid on-success on-error on-connect-event-vector theme]}]]
(let [event-vector
(or on-connect-event-vector
[:keycard/get-application-info
{:key-uid key-uid
:on-success on-success
:on-error on-error}])]
(fn [{:keys [db]} [{:keys [key-uid on-success on-error theme]}]]
(let [event-vector [:keycard/get-application-info
{:key-uid key-uid
:on-success on-success
:on-error on-error}]]
{:db (assoc-in db [:keycard :on-card-connected-event-vector] event-vector)
:fx [[:dispatch
[:keycard/show-connection-sheet
Expand Down
4 changes: 2 additions & 2 deletions src/status_im/contexts/keycard/migrate/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
:on-success #(rf/dispatch [:keycard/migration.continue])
:on-error
(fn [error]
(if (= error :keycard/error.keycard-blank)
(if (= error :keycard/error.keycard-empty)
(rf/dispatch [:keycard/migration.continue])
(rf/dispatch [:keycard/on-application-info-error error])))}]))

Expand Down Expand Up @@ -49,7 +49,7 @@
:theme :dark
:on-error
(fn [error]
(if (= error :keycard/error.keycard-blank)
(if (= error :keycard/error.keycard-empty)
(rf/dispatch [:keycard/migration.continue])
(rf/dispatch [:keycard/on-application-info-error error])))}]]]}))

Expand Down
87 changes: 87 additions & 0 deletions src/status_im/contexts/keycard/unblock/events.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
(ns status-im.contexts.keycard.unblock.events
(:require [utils.re-frame :as rf]
[utils.security.core :as security]))

(rf/reg-event-fx :keycard/unblock.pin-created
(fn [{:keys [db]} [pin]]
{:db (assoc-in db [:keycard :unblock :pin] pin)
:fx [[:dispatch [:navigate-back]]
[:dispatch [:open-modal :screen/keycard.unblock.ready-to-unblock]]]}))

(rf/reg-event-fx :keycard/unblock.phrase-entered
(fn [{:keys [db]} [{:keys [phrase]}]]
{:db (assoc-in db [:keycard :unblock :masked-phrase] phrase)
:fx [[:dispatch [:navigate-back]]
[:dispatch
[:open-modal :screen/keycard.pin.create
{:on-complete #(rf/dispatch [:keycard/unblock.pin-created %])}]]]}))

(rf/reg-event-fx :keycard/unblock.generate-and-load-key
(fn [{:keys [db]}]
(let [{:keys [masked-phrase pin]} (get-in db [:keycard :unblock])]
{:fx [[:effects.keycard/generate-and-load-key
{:mnemonic (security/safe-unmask-data masked-phrase)
:pin pin
:on-success (fn []
(rf/dispatch [:keycard/disconnect])
(rf/dispatch [:navigate-back])
(rf/dispatch [:open-modal :screen/keycard.unblock.success]))}]]})))

;; third stage, import keys
(rf/reg-event-fx :keycard/unblock.import-keys
(fn []
{:fx [[:dispatch
[:keycard/connect.next-stage
{:on-error (fn [error]
(if (= error :keycard/error.keycard-empty)
(rf/dispatch [:keycard/unblock.generate-and-load-key])
(do
(rf/dispatch [:navigate-back])
(rf/dispatch [:keycard/on-application-info-error error]))))}]]]}))

;; second stage, check if card initialized
(rf/reg-event-fx :keycard/unblock.init-card-or-import-keys
(fn [{:keys [db]}]
(let [pin (get-in db [:keycard :unblock :pin])
{:keys [initialized?]} (get-in db [:keycard :application-info])]
{:fx [(if initialized?
[:dispatch [:keycard/unblock.import-keys]]
[:effects.keycard/init-card
{:pin pin
:on-success #(rf/dispatch [:keycard/unblock.import-keys])}])]})))

;; second stage, init card with pin
(defn init-with-pin
[]
(rf/dispatch
[:keycard/connect.next-stage
{:on-error (fn [error]
(if (= error :keycard/error.keycard-empty)
(rf/dispatch [:keycard/unblock.init-card-or-import-keys])
(do
(rf/dispatch [:navigate-back])
(rf/dispatch [:keycard/on-application-info-error error]))))}]))

;; first stage, reset card
(rf/reg-event-fx :keycard/unblock
(fn [{:keys [db]}]
{:fx [[:dispatch
[:keycard/connect
{:key-uid (get-in db [:keycard :application-info :key-uid])
:on-error (fn [error]
(cond
(or (= error :keycard/error.keycard-frozen)
(= error :keycard/error.keycard-locked))
(rf/dispatch [:keycard/factory-reset {:on-success init-with-pin}])

(= error :keycard/error.keycard-empty)
(init-with-pin)

:else
(do
(rf/dispatch [:navigate-back])
(if (= error :keycard/error.keycard-wrong-profile)
(do
(rf/dispatch [:keycard/disconnect])
(rf/dispatch [:open-modal :screen/keycard.different-card]))
(rf/dispatch [:keycard/on-application-info-error error])))))}]]]}))
60 changes: 60 additions & 0 deletions src/status_im/contexts/keycard/unblock/view.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
(ns status-im.contexts.keycard.unblock.view
(:require [quo.core :as quo]
[react-native.core :as rn]
[status-im.common.events-helper :as events-helper]
[status-im.contexts.keycard.common.view :as common.view]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))

(defn success-view
[]
[:<>
[quo/page-nav
{:icon-name :i/close
:on-press events-helper/navigate-back}]
[quo/page-top
{:title (i18n/label :t/keycard-unblocked)}]
[rn/view {:style {:flex 1}}]
[rn/view {:style {:padding-horizontal 20}}
[quo/button {:on-press events-helper/navigate-back}
(i18n/label :t/done)]]])

(defn ready-to-unblock
[]
[:<>
[quo/page-nav
{:icon-name :i/close
:on-press events-helper/navigate-back}]
[quo/page-top
{:title (i18n/label :t/ready-to-unblock-keycard)}]
[rn/view {:style {:flex 1}}]
[common.view/tips]
[quo/bottom-actions
{:actions :one-action
:button-one-label (i18n/label :t/scan-keycard)
:button-one-props {:on-press #(rf/dispatch [:keycard/unblock])}}]])

(defn sheet
[]
(let [customization-color (rf/sub [:profile/customization-color])]
[:<>
[quo/drawer-top {:title (i18n/label :t/unblock-keycard-recovery)}]
[quo/text
{:style {:padding-horizontal 20
:padding-vertical 8}}
(i18n/label :t/unblock-keycard-instructions)]
[quo/bottom-actions
{:actions :two-actions
:button-one-label (i18n/label :t/continue)
:button-one-props {:customization-color
customization-color
:on-press
(fn []
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:navigate-back])
(rf/dispatch
[:open-modal :screen/use-recovery-phrase-dark
{:on-success #(rf/dispatch [:keycard/unblock.phrase-entered %])}]))}
:button-two-label (i18n/label :t/cancel)
:button-two-props {:type :grey
:on-press #(rf/dispatch [:hide-bottom-sheet])}}]]))
2 changes: 1 addition & 1 deletion src/status_im/contexts/keycard/utils.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
:keycard/error.not-keycard

(not has-master-key?)
:keycard/error.keycard-blank
:keycard/error.keycard-empty

(and (zero? pin-retry-counter)
(or (nil? puk-retry-counter)
Expand Down
14 changes: 13 additions & 1 deletion src/status_im/navigation/screens.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
[status-im.contexts.keycard.not-keycard.view :as keycard.not-keycard]
[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.keycard.unblock.view :as keycard.unblock]
[status-im.contexts.onboarding.create-password.view :as create-password]
[status-im.contexts.onboarding.create-profile.view :as create-profile]
[status-im.contexts.onboarding.enable-biometrics.view :as enable-biometrics]
Expand Down Expand Up @@ -1097,8 +1098,19 @@
:options {:theme :dark
:modalPresentationStyle :fullScreen
:insets {:top? true :bottom? true}}
:component keycard.backup/success-view}])
:component keycard.backup/success-view}

{:name :screen/keycard.unblock.ready-to-unblock
:metrics {:track? true}
:options {:insets {:top? true :bottom? true}
:modalPresentationStyle :fullScreen}
:component keycard.unblock/ready-to-unblock}

{:name :screen/keycard.unblock.success
:metrics {:track? true}
:options {:insets {:top? true :bottom? true}
:modalPresentationStyle :fullScreen}
:component keycard.unblock/success-view}])

(defn screens
[]
Expand Down
Loading

0 comments on commit ed10ed7

Please sign in to comment.