From dea7227c2949ff2714e23ba87c9f841673938484 Mon Sep 17 00:00:00 2001 From: Shivek Khurana Date: Thu, 24 Jun 2021 13:50:52 +0530 Subject: [PATCH] Enabled password reset UI Fix function typo that caused android version to fail Fix Issue 1 pointed out by Tetiana. Implement new UI to accomodate slow progress on Android Fix QA Issue 3 - Hide reset password option for keycard accounts Add steps to password reset Align the checkbox on terms of use Make modal rext align center because it wrapped abruptly Logout user after password reset Disable next button to curb recklessness Remove reset password feature flag Signed-off-by: Shivek Khurana --- .env | 1 - .env.e2e | 2 +- .env.jenkins | 2 +- .env.release | 2 +- .../status/ethereum/module/StatusModule.java | 2 +- .../multiaccounts/reset_password/core.cljs | 30 ++++-- src/status_im/subs.cljs | 9 +- .../ui/screens/onboarding/intro/views.cljs | 11 ++- src/status_im/ui/screens/popover/views.cljs | 4 +- .../privacy_and_security_settings/views.cljs | 3 +- .../ui/screens/reset_password/views.cljs | 93 +++++++++++++------ src/status_im/utils/config.cljs | 1 - translations/en.json | 4 +- 13 files changed, 107 insertions(+), 57 deletions(-) diff --git a/.env b/.env index 8a6d5477b5..5cbfccc338 100644 --- a/.env +++ b/.env @@ -29,4 +29,3 @@ APN_TOPIC=im.status.ethereum.pr COMMUNITIES_ENABLED=1 DATABASE_MANAGEMENT_ENABLED=1 METRICS_ENABLED=0 -RESET_PASSWORD_ENABLED=1 \ No newline at end of file diff --git a/.env.e2e b/.env.e2e index 57137d816c..380294e221 100644 --- a/.env.e2e +++ b/.env.e2e @@ -29,4 +29,4 @@ VERIFY_TRANSACTION_CHAIN_ID=3 DATABASE_MANAGEMENT_ENABLED=1 COMMUNITIES_ENABLED=1 COMMUNITIES_MANAGEMENT_ENABLED=1 -METRICS_ENABLED=0 \ No newline at end of file +METRICS_ENABLED=0 diff --git a/.env.jenkins b/.env.jenkins index 200eca953d..55e385bcf8 100644 --- a/.env.jenkins +++ b/.env.jenkins @@ -29,4 +29,4 @@ GOOGLE_FREE=0 DATABASE_MANAGEMENT_ENABLED=1 COMMUNITIES_ENABLED=1 COMMUNITIES_MANAGEMENT_ENABLED=1 -METRICS_ENABLED=0 \ No newline at end of file +METRICS_ENABLED=0 diff --git a/.env.release b/.env.release index 7e878eca47..213838ce59 100644 --- a/.env.release +++ b/.env.release @@ -18,4 +18,4 @@ PARTITIONED_TOPIC=0 ENABLE_ROOT_ALERT=1 MAX_IMAGES_BATCH=1 ENABLE_REFERRAL_INVITE=0 -METRICS_ENABLED=0 \ No newline at end of file +METRICS_ENABLED=0 diff --git a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java index 25704dd51c..0638c5a7d7 100644 --- a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java +++ b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java @@ -1504,7 +1504,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL } @ReactMethod - public void reEncryptDbAndKeyStore(final String keyUID, final String password, final String newPassword, final Callback callback) { + public void reEncryptDbAndKeystore(final String keyUID, final String password, final String newPassword, final Callback callback) { Log.d(TAG, "reEncryptDbAndKeyStore"); Runnable r = new Runnable() { diff --git a/src/status_im/multiaccounts/reset_password/core.cljs b/src/status_im/multiaccounts/reset_password/core.cljs index f8c5cfebad..44823ec7bc 100644 --- a/src/status_im/multiaccounts/reset_password/core.cljs +++ b/src/status_im/multiaccounts/reset_password/core.cljs @@ -4,6 +4,7 @@ [status-im.utils.types :as types] [clojure.string :as string] [status-im.utils.security :as security] + [status-im.utils.keychain.core :as keychain] [status-im.popover.core :as popover] [status-im.native-module.core :as status] [status-im.ethereum.core :as ethereum])) @@ -34,13 +35,19 @@ (fx/defn password-reset-success {:events [::password-reset-success]} [{:keys [db] :as cofx}] - (fx/merge cofx - {:db (dissoc - db - :multiaccount/reset-password-form-vals - :multiaccount/reset-password-errors - :multiaccount/reset-password-next-enabled?)} - (popover/show-popover {:view :password-reset-success}))) + (let [{:keys [key-uid]} (:multiaccount db) + auth-method (get db :auth-method keychain/auth-method-none) + new-password (get-in db [:multiaccount/reset-password-form-vals :new-password])] + (fx/merge cofx + {:db (dissoc + db + :multiaccount/reset-password-form-vals + :multiaccount/reset-password-errors + :multiaccount/reset-password-next-enabled? + :multiaccount/resetting-password?)} + ;; update password in keychain if biometrics are enabled + (when (= auth-method keychain/auth-method-biometric) + (keychain/save-user-password key-uid new-password))))) (defn change-db-password-cb [res] (let [{:keys [error]} (types/json->clj res)] @@ -59,9 +66,14 @@ (fx/defn handle-verification-success {:events [::handle-verification-success]} - [{:keys [db]} form-vals] + [{:keys [db] :as cofx} form-vals] (let [{:keys [key-uid name]} (:multiaccount db)] - {::change-db-password [key-uid form-vals]})) + (fx/merge cofx + {::change-db-password [key-uid form-vals] + :db (assoc db + :multiaccount/resetting-password? true)} + (popover/show-popover {:view :password-reset-popover + :prevent-closing? true})))) (defn handle-verification [form-vals result] (let [{:keys [error]} (types/json->clj result)] diff --git a/src/status_im/subs.cljs b/src/status_im/subs.cljs index a97e198fbb..7af67db0e3 100644 --- a/src/status_im/subs.cljs +++ b/src/status_im/subs.cljs @@ -100,6 +100,7 @@ (reg-root-key-sub :multiaccounts/key-storage :multiaccounts/key-storage) (reg-root-key-sub :multiaccount/reset-password-form-vals :multiaccount/reset-password-form-vals) (reg-root-key-sub :multiaccount/reset-password-errors :multiaccount/reset-password-errors) +(reg-root-key-sub :multiaccount/resetting-password? :multiaccount/resetting-password?) ;;chat (reg-root-key-sub ::cooldown-enabled? :chat/cooldown-enabled?) @@ -2707,10 +2708,12 @@ :multiaccount/reset-password-form-vals-and-errors :<- [:multiaccount/reset-password-form-vals] :<- [:multiaccount/reset-password-errors] - (fn [[form-vals errors]] + :<- [:multiaccount/resetting-password?] + (fn [[form-vals errors resetting?]] (let [{:keys [current-password new-password confirm-new-password]} form-vals] - {:form-vals form-vals - :errors errors + {:form-vals form-vals + :errors errors + :resetting? resetting? :next-enabled? (and (pos? (count current-password)) (pos? (count new-password)) diff --git a/src/status_im/ui/screens/onboarding/intro/views.cljs b/src/status_im/ui/screens/onboarding/intro/views.cljs index 896f5e94d2..b9efa89dec 100644 --- a/src/status_im/ui/screens/onboarding/intro/views.cljs +++ b/src/status_im/ui/screens/onboarding/intro/views.cljs @@ -152,6 +152,7 @@ [react/view {:style {:align-items :center}} [react/view {:flex-direction :row :justify-content :space-between + :align-items :center :margin-top 36 :margin-bottom 24} [quo/checkbox {:value @tos-accepted @@ -159,9 +160,9 @@ [rn/touchable-opacity {:on-press #(swap! tos-accepted not)} [react/nested-text {:style {:margin-left 12}} (i18n/label :t/accept-status-tos-prefix) - [{:style (merge {:color colors/blue} - typography/font-medium) - :on-press #(re-frame/dispatch [:open-modal :terms-of-service]) + [{:style (merge {:color colors/blue} + typography/font-medium) + :on-press #(re-frame/dispatch [:open-modal :terms-of-service]) :accessibility-label :terms-of-service-link} " " (i18n/label :t/terms-of-service)]]]] @@ -173,7 +174,7 @@ (re-frame/dispatch [:hide-terms-of-services-opt-in-screen]))} (i18n/label :t/get-started)]] [react/text - {:style {:color colors/blue} - :on-press #(re-frame/dispatch [:open-modal :privacy-policy]) + {:style {:color colors/blue} + :on-press #(re-frame/dispatch [:open-modal :privacy-policy]) :accessibility-label :privacy-policy-link} (i18n/label :t/privacy-policy)]]]) diff --git a/src/status_im/ui/screens/popover/views.cljs b/src/status_im/ui/screens/popover/views.cljs index 7f1bad175e..f780c0bf1c 100644 --- a/src/status_im/ui/screens/popover/views.cljs +++ b/src/status_im/ui/screens/popover/views.cljs @@ -171,8 +171,8 @@ (= :transfer-multiaccount-unknown-error view) [multiaccounts.key-storage/unknown-error-popover] - (= :password-reset-success view) - [reset-password.views/reset-success-popover] + (= :password-reset-popover view) + [reset-password.views/reset-password-popover] (= :pin-limit view) [pinned-message/pin-limit-popover] diff --git a/src/status_im/ui/screens/privacy_and_security_settings/views.cljs b/src/status_im/ui/screens/privacy_and_security_settings/views.cljs index e1f31244c0..4b857436e3 100644 --- a/src/status_im/ui/screens/privacy_and_security_settings/views.cljs +++ b/src/status_im/ui/screens/privacy_and_security_settings/views.cljs @@ -19,6 +19,7 @@ messages-from-contacts-only webview-allow-permission-requests?]} [:multiaccount] supported-biometric-auth [:supported-biometric-auth] + keycard? [:keycard-multiaccount?] auth-method [:auth-method]] [react/scroll-view {:padding-vertical 8} [quo/list-header (i18n/label :t/security)] @@ -69,7 +70,7 @@ :t/anyone)) :on-press #(re-frame/dispatch [:navigate-to :messages-from-contacts-only]) :accessibility-label :accept-new-chats-from}] - (when config/reset-password-enabled? + (when (not keycard?) [quo/list-item {:size :small :title (i18n/label :t/reset-password) :chevron true diff --git a/src/status_im/ui/screens/reset_password/views.cljs b/src/status_im/ui/screens/reset_password/views.cljs index fcfe4bbe2d..025496c559 100644 --- a/src/status_im/ui/screens/reset_password/views.cljs +++ b/src/status_im/ui/screens/reset_password/views.cljs @@ -11,12 +11,14 @@ (:require-macros [status-im.utils.views :refer [defview letsubs]])) (defn input-field - ([id errors on-submit] (input-field id errors on-submit false)) - ([id errors on-submit focus?] + [{:keys [id errors on-submit disabled? focus?] + :or {disabled? false focus? false}}] + [react/view {:style {:opacity (if disabled? 0.33 1)}} [quo/text-input {:placeholder (i18n/label id) :default-value "" :auto-focus focus? + :editable (not disabled?) :accessibility-label id :show-cancel false :style {:margin-bottom 32} @@ -28,20 +30,33 @@ :error (when-let [error (get errors id)] (if (keyword? error) (i18n/label error) - error))}])) + error))}]]) (defview reset-password [] - (letsubs [{:keys [form-vals errors next-enabled?]} + (letsubs [{:keys [form-vals errors next-enabled? resetting?]} [:multiaccount/reset-password-form-vals-and-errors]] - (let [on-submit #(re-frame/dispatch [::reset-password/reset form-vals])] + (let [{:keys [current-password + new-password]} form-vals + on-submit #(re-frame/dispatch [::reset-password/reset form-vals])] [react/keyboard-avoiding-view {:flex 1} [react/view {:style {:flex 1 :justify-content :space-between}} - [react/view {:style {:padding-horizontal 16 + [react/view {:style {:margin-top 32 + :padding-horizontal 16 :padding-vertical 16}} - [input-field :current-password errors on-submit true] - [input-field :new-password errors on-submit] - [input-field :confirm-new-password errors on-submit]] + [input-field {:id :current-password + :errors errors + :on-sumbit on-submit + :disabled? false + :focus? true}] + [input-field {:id :new-password + :errors errors + :on-sumbit on-submit + :disabled? (zero? (count current-password))}] + [input-field {:id :confirm-new-password + :errors errors + :on-sumbit on-submit + :disabled? (zero? (count new-password))}]] [quo/text {:color :secondary :align :center :size :small :style {:padding-horizontal 16}} (i18n/label :t/password-description)] @@ -51,28 +66,46 @@ [quo/button {:on-press on-submit :accessibility-label :next-button - :disabled (not next-enabled?) + :disabled (or (not next-enabled?) + ;; disable on resetting? so the user cannot press the next button recklessly + ;; https://github.com/status-im/status-react/pull/12245#issuecomment-874827573 + resetting?) :type :secondary :after :main-icons/next} (i18n/label :t/next)]}]]]))) -(defview reset-success-popover [] - [react/view {:padding-vertical 24 - :padding-horizontal 48 - :align-items :center} - [react/view {:width 32 - :height 32 - :background-color colors/green-transparent-10 - :border-radius 32 - :align-items :center - :justify-content :center} - [icons/icon :main-icons/check {:color colors/green}]] - [quo/text {:size :x-large - :weight :bold - :style {:typography :title-bold - :margin-top 16 - :margin-bottom 24}} - (i18n/label :t/password-reset-success)] - [react/view {:align-items :center} - [quo/button {:on-press #(re-frame/dispatch [:hide-popover])} - (i18n/label :t/ok-got-it)]]]) +(defview reset-password-popover [] + (letsubs [{:keys [resetting?]} [:multiaccount/reset-password-form-vals-and-errors]] + [react/view {:padding-vertical 24 + :padding-horizontal 48 + :align-items :center} + [react/view {:width 32 + :height 32 + :background-color (if resetting? + colors/gray-lighter + colors/green-transparent-10) + :border-radius 32 + :align-items :center + :justify-content :center} + (if resetting? + [react/activity-indicator {:size :small + :animating true}] + [icons/icon :main-icons/check {:color colors/green}])] + [quo/text {:size :x-large + :weight :bold + :align :center + :style {:typography :title-bold + :margin-top 16 + :margin-bottom 24}} + (i18n/label (if resetting? + :t/password-reset-in-progress + :t/password-reset-success))] + (when-not resetting? + [quo/text {:align :center + :color :secondary + :style {:margin-bottom 24}} + (i18n/label :t/password-reset-success-message)]) + [react/view {:align-items :center} + [quo/button {:on-press #(re-frame/dispatch [:logout]) + :disabled resetting?} + (i18n/label :t/okay)]]])) diff --git a/src/status_im/utils/config.cljs b/src/status_im/utils/config.cljs index fd2a055107..ee9a22f0d2 100644 --- a/src/status_im/utils/config.cljs +++ b/src/status_im/utils/config.cljs @@ -49,7 +49,6 @@ (def database-management-enabled? (enabled? (get-config :DATABASE_MANAGEMENT_ENABLED "0"))) (def debug-webview? (enabled? (get-config :DEBUG_WEBVIEW "0"))) (def metrics-enabled? (enabled? (get-config :METRICS_ENABLED "0"))) -(def reset-password-enabled? (enabled? (get-config :RESET_PASSWORD_ENABLED "0"))) ;; CONFIG VALUES (def log-level diff --git a/translations/en.json b/translations/en.json index 968a1cc5f4..d2115b283b 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1577,7 +1577,9 @@ "bip39-password-placeholder": "BIP39 password", "current-password": "Current password", "reset-password": "Reset password", - "password-reset-success": "Password reset", + "password-reset-success": "Password changed", + "password-reset-success-message": "You will need to sign in again", + "password-reset-in-progress": "Changing password...", "new-password": "New password", "confirm-new-password": "Confirm new password", "password-mismatch": "New password and confirmation does not match",