keycard account removal and card reset

Signed-off-by: Michele Balistreri <michele@bitgamma.com>
This commit is contained in:
Michele Balistreri 2021-03-01 16:04:03 +03:00
parent 49b78c0cea
commit 5fecdd7830
No known key found for this signature in database
GPG Key ID: E9567DA33A4F791A
11 changed files with 144 additions and 110 deletions

View File

@ -61,7 +61,7 @@
"react-native-screens": "^2.10.1",
"react-native-shake": "^3.3.1",
"react-native-splash-screen": "^3.2.0",
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#v2.5.31",
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#v2.5.32",
"react-native-svg": "^9.8.4",
"react-native-touch-id": "^4.4.1",
"react-native-webview": "git+https://github.com/status-im/react-native-webview.git#v10.9.2",

View File

@ -321,19 +321,19 @@
(defn unpair-and-delete [args]
(log/debug "[keycard] unpair-and-delete")
(keycard/unpair-and-delete
(keycard/unpair
card
(merge
args
{:on-success
(fn [response]
(log/debug "[keycard response succ] unpair-and-delete")
(re-frame/dispatch [:keycard.callback/on-delete-success
(re-frame/dispatch [:keycard.callback/on-unpair-and-delete-success
response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] unpair-and-delete")
(re-frame/dispatch [:keycard.callback/on-delete-error
(re-frame/dispatch [:keycard.callback/on-unpair-and-delete-error
(error-object->map response)]))})))
(defn import-keys [{:keys [on-success] :as args}]

View File

@ -4,6 +4,7 @@
[status-im.keycard.common :as common]
status-im.keycard.delete-key
status-im.keycard.export-key
status-im.keycard.unpair
[status-im.keycard.login :as login]
[status-im.keycard.mnemonic :as mnemonic]
[status-im.keycard.onboarding :as onboarding]
@ -192,7 +193,9 @@
;; now for simplicity do not hide bottom sheet when generating key
;; and exporting key but should be refactored.
(when-not (contains? #{:keycard/generate-and-load-key
:wallet.accounts/generate-new-keycard-account} on-verified)
:wallet.accounts/generate-new-keycard-account
:keycard/remove-key-with-unpair
:keycard/unpair-and-delete} on-verified)
(common/hide-connection-sheet))
(when-not (contains? #{:keycard/unpair
:keycard/generate-and-load-key

View File

@ -1,43 +1,8 @@
(ns status-im.keycard.delete-key
(:require [status-im.multiaccounts.logout.core :as multiaccounts.logout]
[status-im.i18n.i18n :as i18n]
[status-im.navigation :as navigation]
(:require [status-im.navigation :as navigation]
[status-im.utils.fx :as fx]
[taoensso.timbre :as log]
[status-im.keycard.common :as common]))
(fx/defn on-delete-success
{:events [:keycard.callback/on-delete-success]}
[{:keys [db] :as cofx}]
(let [key-uid (get-in db [:multiaccount :key-uid])]
(fx/merge cofx
{:db (-> db
(update :multiaccounts/multiaccounts dissoc key-uid)
(assoc-in [:keycard :secrets] nil)
(assoc-in [:keycard :application-info] nil)
(assoc-in [:keycard :pin] {:status nil
:error-label nil
:on-verified nil}))
;;FIXME delete multiaccount
:utils/show-popup {:title ""
:content (i18n/label :t/card-reseted)}}
(common/clear-on-card-connected)
(multiaccounts.logout/logout))))
(fx/defn on-delete-error
{:events [:keycard.callback/on-delete-error]}
[{:keys [db] :as cofx} error]
(log/debug "[keycard] delete error" error)
(fx/merge cofx
{:db (assoc-in db [:keycard :pin] {:status nil
:error-label nil
:on-verified nil})
:keycard/get-application-info nil
:utils/show-popup {:title ""
:content (i18n/label :t/something-went-wrong)}}
(common/clear-on-card-connected)
(navigation/navigate-to-cofx :keycard-settings nil)))
(fx/defn reset-card-pressed
{:events [:keycard-settings.ui/reset-card-pressed]}
[cofx]
@ -61,11 +26,11 @@
{:events [:keycard-settings.ui/reset-card-next-button-pressed]}
[{:keys [db]}]
{:db (assoc-in db [:keycard :reset-card :disabled?] true)
:dispatch [:keycard/proceed-to-reset-card]})
:dispatch [:keycard/proceed-to-reset-card false]})
(fx/defn proceed-to-reset-card
{:events [:keycard/proceed-to-reset-card]}
[{:keys [db] :as cofx}]
[{:keys [db] :as cofx} keep-keys-on-keycard?]
(let [pin-retry-counter (get-in db [:keycard :application-info :pin-retry-counter])
enter-step (if (zero? pin-retry-counter) :puk :current)]
(fx/merge cofx
@ -74,6 +39,8 @@
:puk []
:status nil
:error-label nil
:on-verified :keycard/remove-key-with-unpair})}
:on-verified (if keep-keys-on-keycard?
:keycard/unpair-and-delete
:keycard/remove-key-with-unpair)})}
(common/set-on-card-connected :keycard/navigate-to-enter-pin-screen)
(common/navigate-to-enter-pin-screen))))

View File

@ -1,12 +1,14 @@
(ns status-im.keycard.unpair
(:require [re-frame.core :as re-frame]
[status-im.multiaccounts.update.core :as multiaccounts.update]
[status-im.multiaccounts.logout.core :as multiaccounts.logout]
[status-im.i18n.i18n :as i18n]
[status-im.navigation :as navigation]
[status-im.utils.fx :as fx]
[taoensso.timbre :as log]
[status-im.keycard.common :as common]))
[status-im.keycard.common :as common]
[status-im.native-module.core :as native-module]
[status-im.utils.types :as types]
[clojure.string :as string]))
(fx/defn unpair-card-pressed
{:events [:keycard-settings.ui/unpair-card-pressed]}
@ -42,11 +44,17 @@
(fx/defn unpair-and-delete
{:events [:keycard/unpair-and-delete]}
[{:keys [db]}]
(let [pin (common/vector->string (get-in db [:keycard :pin :current]))
pairing (common/get-pairing db)]
{:keycard/unpair-and-delete {:pin pin
:pairing pairing}}))
[cofx]
(common/show-connection-sheet
cofx
{:on-card-connected :keycard/unpair-and-delete
:handler
(fn [{:keys [db]}]
(let [pin (common/vector->string (get-in db [:keycard :pin :current]))
pairing (common/get-pairing db)]
{:keycard/unpair-and-delete
{:pin pin
:pairing pairing}}))}))
(fx/defn remove-pairing-from-multiaccount
[cofx {:keys [remove-instance-uid?]}]
@ -106,9 +114,7 @@
{:pin pin
:pairing pairing}}))}))
(fx/defn on-remove-key-success
{:events [:keycard.callback/on-remove-key-success]}
[{:keys [db] :as cofx}]
(defn handle-account-removal [{:keys [db] :as cofx} keys-removed-from-card?]
(let [key-uid (get-in db [:multiaccount :key-uid])
instance-uid (get-in db [:keycard :application-info :instance-uid])
pairings (get-in db [:keycard :pairings])]
@ -117,6 +123,7 @@
(update :multiaccounts/multiaccounts 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)
@ -124,11 +131,23 @@
:error-label nil
:on-verified nil}))
:keycard/persist-pairings (dissoc pairings (keyword instance-uid))
;;FIXME delete multiaccount
:utils/show-popup {:title ""
:content (i18n/label :t/card-reseted)}}
: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])}}
(common/clear-on-card-connected)
(multiaccounts.logout/logout))))
(common/hide-connection-sheet)
(native-module/delete-multiaccount
key-uid
(fn [result]
(let [{:keys [error]} (types/json->clj result)]
(if-not (string/blank? error)
(log/warn "[keycard] remove account: " error)
(log/debug "[keycard] remove account ok"))))))))
(fx/defn on-remove-key-success
{:events [:keycard.callback/on-remove-key-success]}
[cofx]
(handle-account-removal cofx true))
(fx/defn on-remove-key-error
{:events [:keycard.callback/on-remove-key-error]}
@ -141,3 +160,20 @@
{:db (assoc-in db [:keycard :pin :status] nil)}
(common/set-on-card-connected :keycard/remove-key-with-unpair))
(common/show-wrong-keycard-alert true)))))
(fx/defn on-unpair-and-delete-success
{:events [:keycard.callback/on-unpair-and-delete-success]}
[cofx]
(handle-account-removal cofx false))
(fx/defn on-unpair-and-delete-error
{:events [:keycard.callback/on-unpair-and-delete-error]}
[{:keys [db] :as cofx} error]
(log/debug "[keycard] unpair and delete error" error)
(let [tag-was-lost? (common/tag-lost? (:error error))]
(fx/merge cofx
(if tag-was-lost?
(fx/merge cofx
{:db (assoc-in db [:keycard :pin :status] nil)}
(common/set-on-card-connected :keycard/unpair-and-delete))
(common/show-wrong-keycard-alert true)))))

View File

@ -204,6 +204,7 @@
;; delete profile
(reg-root-key-sub :delete-profile/error :delete-profile/error)
(reg-root-key-sub :delete-profile/keep-keys-on-keycard? :delete-profile/keep-keys-on-keycard?)
;; push notifications
(reg-root-key-sub :push-notifications/servers :push-notifications/servers)

View File

@ -8,32 +8,30 @@
[status-im.i18n.i18n :as i18n]
[reagent.core :as reagent]
[status-im.utils.security :as security]
[status-im.ui.screens.privacy-and-security-settings.events :as delete-profile]))
[status-im.ui.screens.privacy-and-security-settings.events :as delete-profile]
status-im.keycard.delete-key))
(defn valid-password? [password]
(>= (count password) 6))
(defn keycard-pin []
#_(let [pin @(re-frame/subscribe [:keycard/pin])
step @(re-frame/subscribe [:keycard/pin-enter-step])
status @(re-frame/subscribe [:keycard/pin-status])
pin-retry-counter @(re-frame/subscribe [:keycard/pin-retry-counter])
puk-retry-counter @(re-frame/subscribe [:keycard/puk-retry-counter])
error-label @(re-frame/subscribe [:keycard/pin-error-label])]
[pin.views/pin-view
{:pin pin
:status status
:retry-counter pin-retry-counter
:error-label error-label
:step :current}]))
(defn on-delete-profile [password]
#(do
(re-frame/dispatch
[::delete-profile/delete-profile @password])
(reset! password nil)))
(defn on-delete-keycard-profile [keep-keys-on-keycard?]
#(re-frame/dispatch
[:keycard/proceed-to-reset-card keep-keys-on-keycard?]))
(defn delete-profile []
(let [password (reagent/atom nil)
text-input-ref (atom nil)]
(fn []
(let [keycard? @(re-frame/subscribe [:keycard-multiaccount?])
multiaccount @(re-frame/subscribe [:multiaccount])
error @(re-frame/subscribe [:delete-profile/error])]
(let [keycard? @(re-frame/subscribe [:keycard-multiaccount?])
multiaccount @(re-frame/subscribe [:multiaccount])
error @(re-frame/subscribe [:delete-profile/error])
keep-keys-on-keycard? @(re-frame/subscribe [:delete-profile/keep-keys-on-keycard?])]
(when (and @text-input-ref error (not @password))
(.clear ^js @text-input-ref))
[react/view {:flex 1}
@ -50,12 +48,31 @@
{:title (multiaccounts/displayed-name multiaccount)
:icon [chat-icon.screen/contact-icon-contacts-tab
(multiaccounts/displayed-photo multiaccount)]}]
[quo/text {:style {:margin-horizontal 24}
:align :center
:color :negative}
(i18n/label :t/delete-profile-warning)]
(if keycard?
[keycard-pin]
(when keycard?
[react/view
[quo/list-header (i18n/label :t/actions)]
[quo/list-item {:title (i18n/label :t/delete-keys-keycard)
:accessory :checkbox
:active (not keep-keys-on-keycard?)
:on-press #(re-frame/dispatch [::delete-profile/keep-keys-on-keycard (not keep-keys-on-keycard?)])}]
[quo/list-item {:title (i18n/label :t/unpair-keycard)
:subtitle (i18n/label :t/unpair-keycard-warning)
:subtitle-max-lines 4
:disabled true
:active true
:accessory :checkbox}]
[quo/list-item {:title (i18n/label :t/reset-database)
:subtitle (i18n/label :t/reset-database-warning-keycard)
:subtitle-max-lines 4
:disabled true
:active true
:accessory :checkbox}]])
(when-not keycard?
[quo/text {:style {:margin-horizontal 24}
:align :center
:color :negative}
(i18n/label :t/delete-profile-warning)])
(when-not keycard?
[quo/text-input
{:style {:margin-horizontal 36
:margin-top 36}
@ -71,16 +88,18 @@
(if (= :wrong-password error)
(i18n/label :t/wrong-password)
(str error)))}])]
(when-not keycard?
[react/view {:style {:align-items :center}}
[quo/separator]
[react/view
{:style {:margin-vertical 8}}
[quo/button {:on-press #(do
(re-frame/dispatch
[::delete-profile/delete-profile @password])
(reset! password nil))
:theme :negative
:accessibility-label :delete-profile-confirm
:disabled ((complement valid-password?) @password)}
(i18n/label :t/delete-profile)]]])]]))))
[react/view {:style {:align-items :center}}
(when-not keycard?
[quo/separator])
(when (and keycard? (not keep-keys-on-keycard?))
[quo/text {:style {:margin-horizontal 24 :margin-bottom 16}
:align :center
:color :negative}
(i18n/label :t/delete-profile-warning)])
[react/view
{:style {:margin-vertical 8}}
[quo/button {:on-press (if keycard? (on-delete-keycard-profile keep-keys-on-keycard?) (on-delete-profile password))
:theme :negative
:accessibility-label :delete-profile-confirm
:disabled (and (not keycard?) ((complement valid-password?) @password))}
(i18n/label :t/delete-profile)]]]]]))))

View File

@ -65,3 +65,8 @@
[{:keys [db]} error]
(log/info "[delete-profile] on-failure" error)
{:db (assoc db :delete-profile/error error)})
(fx/defn keep-keys-on-keycard
{:events [::keep-keys-on-keycard]}
[{:keys [db] :as cofx} checked?]
{:db (assoc-in db [:delete-profile/keep-keys-on-keycard?] checked?)})

View File

@ -16,8 +16,7 @@
(views/defview privacy-and-security []
(views/letsubs [{:keys [mnemonic preview-privacy? webview-allow-permission-requests?]} [:multiaccount]
supported-biometric-auth [:supported-biometric-auth]
auth-method [:auth-method]
keycard? [:keycard-multiaccount?]]
auth-method [:auth-method]]
[react/view {:flex 1 :background-color colors/white}
[topbar/topbar {:title (i18n/label :t/privacy-and-security)}]
[react/scroll-view {:padding-vertical 8}
@ -78,14 +77,11 @@
:on-press #(re-frame/dispatch
[:multiaccounts.ui/webview-permission-requests-switched
((complement boolean) webview-allow-permission-requests?)])}])
;; TODO(rasom): remove this condition when kk support will be added
(when-not keycard?
[separator])
(when-not keycard?
[quo/list-item
{:size :small
:theme :negative
:title (i18n/label :t/delete-my-profile)
:on-press #(re-frame/dispatch [:navigate-to :delete-profile])
:accessibility-label :dapps-permissions-button
:chevron true}])]]))
[separator]
[quo/list-item
{:size :small
:theme :negative
:title (i18n/label :t/delete-my-profile)
:on-press #(re-frame/dispatch [:navigate-to :delete-profile])
:accessibility-label :dapps-permissions-button
:chevron true}]]]))

View File

@ -396,6 +396,7 @@
"delete-profile-warning": "Warning: If you dont have your seed phrase written down, you will lose access to your funds after you delete your profile",
"profile-deleted-title": "Profile deleted",
"profile-deleted-content": "Your profile was successfully deleted",
"profile-deleted-keycard": "You can now restore another keypair on your Keycard",
"deny": "Deny",
"description": "Description",
"dev-mode": "Development mode",
@ -1219,6 +1220,8 @@
"unpair-card-confirmation": "This operation will unpair card from current device. Requires 6-digit passcode authorization. Do you want to proceed?",
"unpaired-keycard-text": "The Keycard you tapped is not associated with this phone",
"unpaired-keycard-title": "Looks like your card has been unpaired",
"unpair-keycard": "Unpair Keycard from this phone",
"unpair-keycard-warning": "Your pairing code/PUK & PIN remain unchanged",
"update": "Update",
"url": "URL",
"usd-currency": "USD",
@ -1313,6 +1316,7 @@
"keycard-free-pairing-slots": "Keycard has {{n}} free pairing slots",
"public-chat-description": "Join public chats for your interests! Anyone can start a new one.",
"delete-account": "Delete account",
"delete-keys-keycard": "Delete keys from Keycard",
"watch-only": "Watch-only",
"cant-report-bug": "Can't report a bug",
"mail-should-be-configured": "Mail client should be configured",
@ -1434,6 +1438,8 @@
"transfers-fetching-failure": "Transfers history could not be updated. Check your connection and pull down to try again",
"move-and-reset": "Move and Reset",
"move-keystore-file-to-keycard": "Move keystore file to keycard?",
"database-reset-title": "Database reset",
"database-reset-content": "Chats, contacts and settings have been deleted. You can use your account with your Keycard",
"database-reset-warning": "Database will be reset. Chats, contacts and settings will be deleted",
"empty-keycard-required": "Requires an empty Keycard",
"current": "Current",
@ -1446,6 +1452,7 @@
"select-new-location-for-keys": "Select a new location to save your private key(s)",
"reset-database": "Reset database",
"reset-database-warning": "Delete chats, contacts and settings. Required when youve lost your password",
"reset-database-warning-keycard": "Delete chats, contacts and settings.",
"key-managment": "Key management",
"choose-actions": "Choose actions",
"master-account": "Master account",

View File

@ -6751,9 +6751,9 @@ react-native-splash-screen@^3.2.0:
resolved "https://registry.yarnpkg.com/react-native-splash-screen/-/react-native-splash-screen-3.2.0.tgz#d47ec8557b1ba988ee3ea98d01463081b60fff45"
integrity sha512-Ls9qiNZzW/OLFoI25wfjjAcrf2DZ975hn2vr6U9gyuxi2nooVbzQeFoQS5vQcbCt9QX5NY8ASEEAtlLdIa6KVg==
"react-native-status-keycard@git+https://github.com/status-im/react-native-status-keycard.git#v2.5.31":
version "2.5.31"
resolved "git+https://github.com/status-im/react-native-status-keycard.git#67ba4d5596ae3f7fd123c0f1c925e98e8def493f"
"react-native-status-keycard@git+https://github.com/status-im/react-native-status-keycard.git#v2.5.32":
version "2.5.32"
resolved "git+https://github.com/status-im/react-native-status-keycard.git#f602fadf800937fc1de92aa18c2e58c372eb1bed"
react-native-svg@^9.8.4:
version "9.13.6"