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",