diff --git a/src/legacy/status_im/events.cljs b/src/legacy/status_im/events.cljs index b257bb385c..90afefe6a8 100644 --- a/src/legacy/status_im/events.cljs +++ b/src/legacy/status_im/events.cljs @@ -11,7 +11,6 @@ legacy.status-im.group-chats.core legacy.status-im.log-level.core legacy.status-im.multiaccounts.login.core - legacy.status-im.multiaccounts.logout.core [legacy.status-im.multiaccounts.model :as multiaccounts.model] legacy.status-im.multiaccounts.update.core legacy.status-im.pairing.core @@ -110,14 +109,14 @@ (defn- on-biometric-auth-fail [{:keys [code]}] (if (= code "USER_FALLBACK") - (re-frame/dispatch [:multiaccounts.logout.ui/logout-confirmed]) + (re-frame/dispatch [:profile/logout]) (utils/show-confirmation {:title (i18n/label :t/biometric-auth-confirm-title) :content (i18n/label :t/biometric-auth-confirm-message) :confirm-button-text (i18n/label :t/biometric-auth-confirm-try-again) :cancel-button-text (i18n/label :t/biometric-auth-confirm-logout) :on-accept #(rf/dispatch [:biometric/authenticate {:on-fail on-biometric-auth-fail}]) - :on-cancel #(re-frame/dispatch [:multiaccounts.logout.ui/logout-confirmed])}))) + :on-cancel #(re-frame/dispatch [:profile/logout])}))) (rf/defn on-return-from-background [{:keys [db now] :as cofx}] diff --git a/src/legacy/status_im/fleet/core.cljs b/src/legacy/status_im/fleet/core.cljs index 700e301dc3..d504f791be 100644 --- a/src/legacy/status_im/fleet/core.cljs +++ b/src/legacy/status_im/fleet/core.cljs @@ -91,5 +91,4 @@ cofx :fleet fleet - {:on-success - #(re-frame/dispatch [:logout])})))) + {:on-success #(re-frame/dispatch [:profile/logout])})))) diff --git a/src/legacy/status_im/log_level/core.cljs b/src/legacy/status_im/log_level/core.cljs index f804bd347b..1f865a00bd 100644 --- a/src/legacy/status_im/log_level/core.cljs +++ b/src/legacy/status_im/log_level/core.cljs @@ -14,7 +14,7 @@ cofx :log-level log-level - {:on-success #(re-frame/dispatch [:logout])})))) + {:on-success #(re-frame/dispatch [:profile/logout])})))) (rf/defn show-change-log-level-confirmation {:events [:log-level.ui/log-level-selected]} diff --git a/src/legacy/status_im/multiaccounts/logout/core.cljs b/src/legacy/status_im/multiaccounts/logout/core.cljs deleted file mode 100644 index aaa5dfdaaa..0000000000 --- a/src/legacy/status_im/multiaccounts/logout/core.cljs +++ /dev/null @@ -1,66 +0,0 @@ -(ns legacy.status-im.multiaccounts.logout.core - (:require - [native-module.core :as native-module] - [re-frame.core :as re-frame] - [status-im.common.keychain.events :as keychain] - [status-im.db :as db] - [utils.i18n :as i18n] - [utils.re-frame :as rf])) - -(re-frame/reg-fx - ::logout - (fn [] - (native-module/logout))) - -(rf/defn initialize-app-db - [{{:keys [keycard initials-avatar-font-file biometrics] - :network/keys [type status expensive?] - :centralized-metrics/keys [user-confirmed?]} - :db}] - {:db (assoc db/app-db - :centralized-metrics/user-confirmed? user-confirmed? - :network/type type - :network/status status - :network/expensive? expensive? - :initials-avatar-font-file initials-avatar-font-file - :keycard (dissoc keycard :secrets :pin :application-info) - :biometrics biometrics - :syncing nil)}) - -(rf/defn logout-method - {:events [::logout-method]} - [{:keys [db] :as cofx} {:keys [auth-method logout?]}] - (let [key-uid (get-in db [:profile/profile :key-uid])] - (rf/merge cofx - {:dispatch [:update-theme-and-init-root :progress] - :effects.shell/reset-state nil - :hide-popover nil - ::logout nil - :profile.settings/webview-debug-changed false - :keychain/clear-user-password key-uid - :profile/get-profiles-overview #(rf/dispatch - [:profile/get-profiles-overview-success %])} - (keychain/save-auth-method key-uid auth-method) - (initialize-app-db)))) - -(rf/defn logout - {:events [:logout :multiaccounts.logout.ui/logout-confirmed - :multiaccounts.update.callback/save-settings-success]} - [_] - ;; we need to disable notifications before starting the logout process - {:effects/push-notifications-disable nil - :dispatch [:alert-banners/remove-all] - :dispatch-later [{:ms 100 - :dispatch [::logout-method - {:auth-method keychain/auth-method-none - :logout? true}]}]}) - -(rf/defn show-logout-confirmation - {:events [:multiaccounts.logout.ui/logout-pressed]} - [_] - {:ui/show-confirmation - {:title (i18n/label :t/logout-title) - :content (i18n/label :t/logout-are-you-sure) - :confirm-button-text (i18n/label :t/logout) - :on-accept #(re-frame/dispatch [:multiaccounts.logout.ui/logout-confirmed]) - :on-cancel nil}}) diff --git a/src/legacy/status_im/ui/screens/reset_password/views.cljs b/src/legacy/status_im/ui/screens/reset_password/views.cljs index 16f5edb0f0..91f99a738b 100644 --- a/src/legacy/status_im/ui/screens/reset_password/views.cljs +++ b/src/legacy/status_im/ui/screens/reset_password/views.cljs @@ -125,6 +125,6 @@ (i18n/label :t/password-reset-success-message)]) [react/view {:align-items :center} [quo/button - {:on-press #(re-frame/dispatch [:logout]) + {:on-press #(re-frame/dispatch [:profile/logout]) :disabled resetting?} (i18n/label :t/okay)]]])) diff --git a/src/legacy/status_im/waku/core.cljs b/src/legacy/status_im/waku/core.cljs index abbcff1fae..84c15b5257 100644 --- a/src/legacy/status_im/waku/core.cljs +++ b/src/legacy/status_im/waku/core.cljs @@ -133,7 +133,7 @@ :params [{:enabled enabled?}] :on-success (fn [] (log/info "light client set successfully" enabled?) - (re-frame/dispatch [:logout])) + (re-frame/dispatch [:profile/logout])) :on-error #(log/error "failed to set light client" {:error % :enabled? enabled?})}]}) @@ -149,7 +149,7 @@ :params [{:enabled enabled?}] :on-success (fn [] (log/info "store confirmation set successfully" enabled?) - (re-frame/dispatch [:logout])) + (re-frame/dispatch [:profile/logout])) :on-error #(log/error "failed to set store confirmation" {:error % :enabled? enabled?})}]}) diff --git a/src/quo/components/common/no_flicker_image.cljs b/src/quo/components/common/no_flicker_image.cljs index 7949b593e5..66126d3dc5 100644 --- a/src/quo/components/common/no_flicker_image.cljs +++ b/src/quo/components/common/no_flicker_image.cljs @@ -36,10 +36,11 @@ "Same as rn/image but cache the image source in a js/Set, so the image won't flicker when re-render on android" [props] - (let [[loaded-source set-loaded-source] (rn/use-state nil) - on-source-loaded (rn/use-callback #(set-loaded-source %))] + (let [[loaded-source set-loaded-source] (rn/use-state nil)] (if platform/ios? [rn/image props] [:<> - [rn/image (assoc props :source loaded-source)] - [caching-image props on-source-loaded]]))) + [rn/image + (cond-> props + loaded-source (assoc :source loaded-source))] + [caching-image props set-loaded-source]]))) diff --git a/src/status_im/common/keychain/events.cljs b/src/status_im/common/keychain/events.cljs index 3686b96a90..4e4a9095b2 100644 --- a/src/status_im/common/keychain/events.cljs +++ b/src/status_im/common/keychain/events.cljs @@ -75,7 +75,9 @@ (-> (str key-uid "-auth") (keychain/get-credentials) (.then (fn [value] - (if value (oops/oget value "password") auth-method-none))) + (if value + (oops/oget value "password") + auth-method-none))) (.catch (constantly auth-method-none)))) (defn save-user-password! @@ -86,10 +88,10 @@ [key-uid callback] (keychain/get-credentials key-uid (fn [value] - (callback (when value - (-> value - (oops/oget "password") - (security/mask-data))))))) + (some-> value + (oops/oget "password") + (security/mask-data) + (callback))))) (re-frame/reg-fx :keychain/get-user-password diff --git a/src/status_im/common/standard_authentication/password_input/view.cljs b/src/status_im/common/standard_authentication/password_input/view.cljs index 1c9595d186..bebfaea101 100644 --- a/src/status_im/common/standard_authentication/password_input/view.cljs +++ b/src/status_im/common/standard_authentication/password_input/view.cljs @@ -4,6 +4,7 @@ [quo.foundations.colors :as colors] [quo.theme :as quo.theme] [react-native.core :as rn] + [status-im.common.biometric.utils :as biometric] [status-im.common.standard-authentication.forgot-password-doc.view :as forgot-password-doc] [status-im.common.standard-authentication.password-input.style :as style] [utils.debounce :as debounce] @@ -54,7 +55,8 @@ {:password (security/mask-data entered-password) :error ""}] - 100)))] + 100))) + biometric-type (rf/sub [:biometrics/supported-type])] [:<> [rn/view {:style {:flex-direction :row}} [quo/input @@ -76,6 +78,6 @@ :icon-only? true :background (when blur? :blur) :type :outline} - :i/face-id])] + (biometric/get-icon-by-type biometric-type)])] (when error? [error-info error-message processing shell?])])) diff --git a/src/status_im/common/standard_authentication/standard_auth/slide_button/view.cljs b/src/status_im/common/standard_authentication/standard_auth/slide_button/view.cljs index 8589140413..108bb023a3 100644 --- a/src/status_im/common/standard_authentication/standard_auth/slide_button/view.cljs +++ b/src/status_im/common/standard_authentication/standard_auth/slide_button/view.cljs @@ -3,6 +3,7 @@ [quo.core :as quo] [quo.theme :as quo.theme] [react-native.core :as rn] + [status-im.common.biometric.utils :as biometric] [status-im.constants :as constants] [utils.re-frame :as rf])) @@ -26,12 +27,15 @@ :on-auth-success on-auth-success :on-auth-fail on-auth-fail :auth-button-label auth-button-label}])) - (vec (conj dependencies on-auth-success on-auth-fail)))] + (vec (conj dependencies on-auth-success on-auth-fail))) + biometric-type (rf/sub [:biometrics/supported-type])] [quo/slide-button {:container-style container-style :size size :customization-color customization-color :on-complete on-complete - :track-icon (if biometric-auth? :i/face-id :password) + :track-icon (if biometric-auth? + (biometric/get-icon-by-type biometric-type) + :password) :track-text track-text :disabled? disabled?}])) diff --git a/src/status_im/contexts/keycard/migrate/fail/view.cljs b/src/status_im/contexts/keycard/migrate/fail/view.cljs index b594dbbee3..beb0d3f53e 100644 --- a/src/status_im/contexts/keycard/migrate/fail/view.cljs +++ b/src/status_im/contexts/keycard/migrate/fail/view.cljs @@ -29,4 +29,4 @@ [quo/bottom-actions {:actions :one-action :button-one-label (i18n/label :t/log-out-remove) - :button-one-props {:on-press #(rf/dispatch [:logout])}}]])) + :button-one-props {:on-press #(rf/dispatch [:profile/logout])}}]])) diff --git a/src/status_im/contexts/keycard/migrate/success/view.cljs b/src/status_im/contexts/keycard/migrate/success/view.cljs index b5f05dac24..9be78900d7 100644 --- a/src/status_im/contexts/keycard/migrate/success/view.cljs +++ b/src/status_im/contexts/keycard/migrate/success/view.cljs @@ -26,6 +26,6 @@ {:resize-mode :contain :source (resources/get-image :keycard-migration-succeeded)}]] [quo/button - {:on-press #(rf/dispatch [:logout]) + {:on-press #(rf/dispatch [:profile/logout]) :container-style {:margin-horizontal 20}} (i18n/label :t/logout)]])) diff --git a/src/status_im/contexts/onboarding/enable_biometrics/view.cljs b/src/status_im/contexts/onboarding/enable_biometrics/view.cljs index 214f60bad7..cc59f2d1b2 100644 --- a/src/status_im/contexts/onboarding/enable_biometrics/view.cljs +++ b/src/status_im/contexts/onboarding/enable_biometrics/view.cljs @@ -10,7 +10,6 @@ [utils.i18n :as i18n] [utils.re-frame :as rf])) - (defn page-title [] [quo/text-combinations @@ -26,12 +25,13 @@ bio-type-label (biometric/get-label-by-type supported-biometric-type) profile-color (or (:color (rf/sub [:onboarding/profile])) (rf/sub [:profile/customization-color])) - syncing-results? (= :screen/onboarding.syncing-results @state/root-id)] + syncing-results? (= :screen/onboarding.syncing-results @state/root-id) + biometric-type (rf/sub [:biometrics/supported-type])] [rn/view {:style (style/buttons insets)} [quo/button {:size 40 :accessibility-label :enable-biometrics-button - :icon-left :i/face-id + :icon-left (biometric/get-icon-by-type biometric-type) :customization-color profile-color :on-press #(rf/dispatch [:onboarding/enable-biometrics])} (i18n/label :t/biometric-enable-button {:bio-type-label bio-type-label})] diff --git a/src/status_im/contexts/onboarding/events.cljs b/src/status_im/contexts/onboarding/events.cljs index 00441f9fc6..834a84ffe6 100644 --- a/src/status_im/contexts/onboarding/events.cljs +++ b/src/status_im/contexts/onboarding/events.cljs @@ -81,8 +81,8 @@ (rf/defn create-account-and-login {:events [:onboarding/create-account-and-login]} [{:keys [db] :as cofx}] - (let [{:keys [display-name seed-phrase password image-path color] :as profile} - (:onboarding/profile db) + (let [{:keys [seed-phrase] + :as profile} (:onboarding/profile db) syncing-account-recovered? (and (seq (:syncing/key-uid db)) (= (:syncing/key-uid db) (get-in db [:onboarding/profile :key-uid])))] @@ -112,20 +112,21 @@ (when-not (seq multiaccounts) {:dispatch [:update-theme-and-init-root :screen/onboarding.intro]})))) -(rf/defn password-set - {:events [:onboarding/password-set]} - [{:keys [db]} password] - (let [supported-type (get-in db [:biometrics :supported-type])] - {:db (-> db - (assoc-in [:onboarding/profile :password] password) - (assoc-in [:onboarding/profile :auth-method] constants/auth-method-password)) - :dispatch (if supported-type - [:navigate-to-within-stack - [:screen/onboarding.enable-biometrics - (get db - :onboarding/navigated-to-enter-seed-phrase-from-screen - :screen/onboarding.new-to-status)]] - [:onboarding/create-account-and-login])})) +(rf/reg-event-fx + :onboarding/password-set + (fn [{:keys [db]} [masked-password]] + (let [biometric-supported-type (get-in db [:biometrics :supported-type])] + {:db (-> db + (assoc-in [:onboarding/profile :password] masked-password) + (assoc-in [:onboarding/profile :auth-method] constants/auth-method-password)) + :fx [[:dispatch + (if biometric-supported-type + [:navigate-to-within-stack + [:screen/onboarding.enable-biometrics + (get db + :onboarding/navigated-to-enter-seed-phrase-from-screen + :screen/onboarding.new-to-status)]] + [:onboarding/create-account-and-login])]]}))) (rf/defn navigate-to-enable-biometrics {:events [:onboarding/navigate-to-enable-biometrics]} @@ -190,8 +191,7 @@ key-uid (get-in db [:profile/profile :key-uid]) syncing? (get-in db [:onboarding/profile :syncing?]) auth-method (get-in db [:onboarding/profile :auth-method]) - biometric-enabled? (= auth-method - constants/auth-method-biometric)] + biometric-enabled? (= auth-method constants/auth-method-biometric)] (cond-> {:db (assoc db :onboarding/generated-keys? true)} biometric-enabled? (assoc :keychain/save-password-and-auth-method diff --git a/src/status_im/contexts/profile/events.cljs b/src/status_im/contexts/profile/events.cljs index b35e224f28..2bc418178a 100644 --- a/src/status_im/contexts/profile/events.cljs +++ b/src/status_im/contexts/profile/events.cljs @@ -11,6 +11,7 @@ [status-im.contexts.profile.edit.name.events] status-im.contexts.profile.effects status-im.contexts.profile.login.events + status-im.contexts.profile.logout.events [status-im.contexts.profile.rpc :as profile.rpc] [utils.re-frame :as rf])) @@ -39,32 +40,54 @@ (rf/reg-event-fx :profile/profile-selected (fn [{:keys [db]} [key-uid]] - {:db (update db :profile/login #(select-profile % key-uid))})) + {:db (update db :profile/login select-profile key-uid)})) + +(rf/reg-event-fx + :profile/set-profile-overview-auth-method + (fn [{db :db} [key-uid auth-method]] + {:db (assoc-in db [:profile/profiles-overview key-uid :auth-method] auth-method)})) + +(rf/reg-event-fx + :profile/get-profiles-auth-method + (fn [_ [key-uids]] + (let [auth-method-fx (fn [key-uid] + [:effects.biometric/check-if-available + {:key-uid key-uid + :on-success (fn [auth-method] + (rf/dispatch + [:profile/set-profile-overview-auth-method + key-uid + auth-method]))}])] + {:fx (map auth-method-fx key-uids)}))) + +(rf/reg-event-fx + :profile/set-already-logged-out + (fn [{:keys [db]}] + {:db (dissoc db :profile/logging-out?)})) (rf/reg-event-fx :profile/get-profiles-overview-success - (fn [{:keys [db]} [{:keys [accounts] {:keys [userConfirmed enabled]} :centralizedMetricsInfo}]] - (let [db-with-settings (assoc db - :centralized-metrics/user-confirmed? userConfirmed - :centralized-metrics/enabled? enabled) - profiles (reduce-profiles accounts) - {:keys [key-uid]} (first (sort-by :timestamp > (vals profiles))) - new-db (cond-> db-with-settings - (seq profiles) - (assoc :profile/profiles-overview profiles) + (fn [{:keys [db]} + [{accounts :accounts + {:keys [userConfirmed enabled]} :centralizedMetricsInfo}]] + (let [profiles (reduce-profiles accounts) + profiles-key-uids (keys profiles) + new-db (cond-> db + :always + (assoc :centralized-metrics/user-confirmed? userConfirmed + :centralized-metrics/enabled? enabled) - key-uid - (update :profile/login #(select-profile % key-uid)))] + (seq profiles) + (assoc :profile/profiles-overview profiles))] {:db new-db - :fx (if (profile.data-store/accepted-terms? accounts) - [[:dispatch [:update-theme-and-init-root :screen/profile.profiles]] - (when (and key-uid userConfirmed) - [:effects.biometric/check-if-available - {:key-uid key-uid - :on-success (fn [auth-method] - (rf/dispatch [:profile.login/check-biometric-success key-uid - auth-method]))}])] - [[:dispatch [:update-theme-and-init-root :screen/onboarding.intro]]])}))) + :fx [[:dispatch [:profile/get-profiles-auth-method profiles-key-uids]] + (if (profile.data-store/accepted-terms? accounts) + [:dispatch [:update-theme-and-init-root :screen/profile.profiles]] + [:dispatch [:update-theme-and-init-root :screen/onboarding.intro]]) + ;; dispatch-later makes sure that the logout button subscribed is always disabled + [:dispatch-later + {:ms 100 + :dispatch [:profile/set-already-logged-out]}]]}))) (rf/reg-event-fx :profile/update-setting-from-backup diff --git a/src/status_im/contexts/profile/login/events.cljs b/src/status_im/contexts/profile/login/events.cljs index e8fee23848..9df55d2b00 100644 --- a/src/status_im/contexts/profile/login/events.cljs +++ b/src/status_im/contexts/profile/login/events.cljs @@ -35,22 +35,20 @@ ;; login phase 1: we want to load and show chats faster, so we split login into 2 phases (rf/reg-event-fx :profile.login/login-existing-profile - (fn [{:keys [db]} [settings account]] - (let [{:networks/keys [_current-network _networks] - :as settings} - (data-store.settings/rpc->settings settings) - profile-overview (profile.rpc/rpc->profiles-overview account) - log-level (or (:log-level settings) config/log-level) - pairing-completed? (= (get-in db [:syncing :pairing-status]) :completed)] - {:db (cond-> (-> db - (assoc :chats/loading? true - :profile/profile (merge profile-overview - settings - {:log-level log-level})) - (assoc-in [:activity-center :loading?] true) - (dissoc :centralized-metrics/onboarding-enabled?)) - pairing-completed? - (dissoc :syncing)) + (fn [{:keys [db]} [settings-data account]] + (let [settings (data-store.settings/rpc->settings settings-data) + profile-overview (profile.rpc/rpc->profiles-overview account) + log-level (or (:log-level settings) config/log-level) + pairing-completed? (= (get-in db [:syncing :pairing-status]) :completed) + new-db (-> db + (assoc :chats/loading? true + :profile/profile (merge profile-overview + settings + {:log-level log-level})) + (assoc-in [:activity-center :loading?] true) + (dissoc :centralized-metrics/onboarding-enabled?))] + {:db (cond-> new-db + pairing-completed? (dissoc :syncing)) :fx (into [[:json-rpc/call [{:method "wakuext_startMessenger" :js-response true @@ -201,11 +199,11 @@ (fn [{:keys [db]}] (let [key-uid (get-in db [:profile/login :key-uid]) keycard? (get-in db [:profile/profiles-overview key-uid :keycard-pairing])] - (if keycard? - {:keychain/get-keycard-keys - [key-uid #(rf/dispatch [:keycard.login/on-get-keys-from-keychain-success key-uid %])]} - {:keychain/get-user-password - [key-uid #(rf/dispatch [:profile.login/get-user-password-success %])]})))) + {:fx [(if keycard? + [:keychain/get-keycard-keys + [key-uid #(rf/dispatch [:keycard.login/on-get-keys-from-keychain-success key-uid %])]] + [:keychain/get-user-password + [key-uid #(rf/dispatch [:profile.login/get-user-password-success %])]])]}))) (rf/reg-event-fx :profile.login/biometric-auth-fail diff --git a/src/status_im/contexts/profile/logout/effects.cljs b/src/status_im/contexts/profile/logout/effects.cljs new file mode 100644 index 0000000000..3d2af82698 --- /dev/null +++ b/src/status_im/contexts/profile/logout/effects.cljs @@ -0,0 +1,5 @@ +(ns status-im.contexts.profile.logout.effects + (:require [native-module.core :as native-module] + [re-frame.core :as rf])) + +(rf/reg-fx :effects.profile/logout native-module/logout) diff --git a/src/status_im/contexts/profile/logout/events.cljs b/src/status_im/contexts/profile/logout/events.cljs new file mode 100644 index 0000000000..7ce50732cf --- /dev/null +++ b/src/status_im/contexts/profile/logout/events.cljs @@ -0,0 +1,47 @@ +(ns status-im.contexts.profile.logout.events + (:require [status-im.contexts.profile.logout.effects] + [status-im.db :as db] + [utils.re-frame :as rf])) + +(rf/reg-event-fx + :profile.logout/disable-notifications + (fn [_] + {:fx [[:effects/push-notifications-disable nil] + [:dispatch [:alert-banners/remove-all]]]})) + +(defn- restart-app-db + [{:keys [initials-avatar-font-file keycard biometrics + network/status network/expensive? + centralized-metrics/user-confirmed?] + network-type :network/network-type + :as _db}] + (assoc db/app-db + :profile/logging-out? true + :centralized-metrics/user-confirmed? user-confirmed? + :network/type network-type + :network/status status + :network/expensive? expensive? + :initials-avatar-font-file initials-avatar-font-file + :keycard (dissoc keycard :secrets :pin :application-info) + :biometrics biometrics + :syncing nil)) + +(rf/reg-event-fx + :profile.logout/reset-state + (fn [{db :db}] + {:db (restart-app-db db) + :fx [[:hide-popover nil] + [:effects.profile/logout nil] + [:profile.settings/webview-debug-changed false] + [:profile/get-profiles-overview #(rf/dispatch [:profile/get-profiles-overview-success %])]]})) + +(rf/reg-event-fx + :profile/logout + (fn [{db :db}] + {:db (assoc db :profile/logging-out? true) + ;; We need to disable notifications before starting the logout process + :fx [[:dispatch [:profile.logout/disable-notifications]] + [:dispatch-later + {:ms 100 + :dispatch [:profile.logout/reset-state]}]]})) + diff --git a/src/status_im/contexts/profile/profiles/view.cljs b/src/status_im/contexts/profile/profiles/view.cljs index 8f56a33f96..393510555d 100644 --- a/src/status_im/contexts/profile/profiles/view.cljs +++ b/src/status_im/contexts/profile/profiles/view.cljs @@ -138,8 +138,7 @@ :color customization-color :profile-picture profile-picture}) :on-card-press (fn [] - (rf/dispatch - [:profile/profile-selected key-uid]) + (rf/dispatch-sync [:profile/profile-selected key-uid]) (rf/dispatch [:profile.login/login-with-biometric-if-available key-uid]) (set-hide-profiles))}])) @@ -157,10 +156,8 @@ (pop-animation-fn))) (reset! push-animation-fn-atom nil) (reset! pop-animation-fn-atom nil)))) - [reanimated/view - {:style (style/profiles-container translate-x)} - [rn/view - {:style style/profiles-header} + [reanimated/view {:style (style/profiles-container translate-x)} + [rn/view {:style style/profiles-header} [quo/text {:size :heading-1 :weight :semi-bold @@ -183,22 +180,21 @@ :render-fn profile-card}]])) (defn password-input - [processing error] - (let [auth-method (rf/sub [:auth-method]) - on-press-biometrics (fn [] - (rf/dispatch [:biometric/authenticate - {:on-success #(rf/dispatch - [:profile.login/biometric-success]) - :on-fail #(rf/dispatch - [:profile.login/biometric-auth-fail - %])}]))] - + [processing error auth-method] + (let [on-press-biometrics (fn [] + (rf/dispatch + [:biometric/authenticate + {:on-success #(rf/dispatch + [:profile.login/biometric-success]) + :on-fail #(rf/dispatch + [:profile.login/biometric-auth-fail %])}]))] [standard-authentication/password-input {:processing processing :error error :shell? true :blur? true - :on-press-biometrics (when (= auth-method constants/auth-method-biometric) on-press-biometrics)}])) + :on-press-biometrics (when (= auth-method constants/auth-method-biometric) + on-press-biometrics)}])) (defn- get-error-message [error] @@ -210,7 +206,7 @@ (defn login-section [{:keys [show-profiles]}] - (let [{:keys [key-uid name keycard-pairing + (let [{:keys [key-uid name keycard-pairing auth-method customization-color]} (rf/sub [:profile/login-profile]) sign-in-enabled? (rf/sub [:sign-in-enabled?]) profile-picture (rf/sub [:profile/login-profiles-picture key-uid]) @@ -266,7 +262,7 @@ {:pin pin :on-success #(rf/dispatch [:keycard.login/on-get-keys-success %]) :on-failure #(rf/dispatch [:keycard/on-action-with-pin-error %])}]))}]))}] - [password-input processing error])] + [password-input processing error auth-method])] (when-not keycard-pairing [quo/button {:size 40 @@ -282,7 +278,7 @@ (defn view [] (rn/use-mount #(rf/dispatch [:centralized-metrics/check-modal metrics-modal/view])) - (let [[show-profiles? set-show-profiles] (rn/use-state false) + (let [[show-profiles? set-show-profiles] (rn/use-state true) show-profiles (rn/use-callback #(set-show-profiles true)) hide-profiles (rn/use-callback #(set-show-profiles false))] [:<> diff --git a/src/status_im/contexts/profile/settings/events.cljs b/src/status_im/contexts/profile/settings/events.cljs index 40d2e25d31..f346e1cf7d 100644 --- a/src/status_im/contexts/profile/settings/events.cljs +++ b/src/status_im/contexts/profile/settings/events.cljs @@ -15,8 +15,7 @@ (rf/reg-event-fx :profile.settings/profile-update (fn [{:keys [db]} [setting setting-value {:keys [dont-sync? on-success]}]] - {:db (-> db - (set-setting-value setting setting-value)) + {:db (set-setting-value db setting setting-value) :fx [[:json-rpc/call [{:method "settings_saveSetting" :params [setting setting-value] @@ -40,14 +39,14 @@ (rf/reg-event-fx :profile.settings/toggle-test-networks (fn [{:keys [db]}] - (let [value (get-in db [:profile/profile :test-networks-enabled?]) - on-success #(rf/dispatch [:logout])] + (let [test-networks-disabled? (not (get-in db [:profile/profile :test-networks-enabled?]))] {:fx [[:ui/show-confirmation {:title (i18n/label :t/testnet-mode-prompt-title) :content (i18n/label :t/testnet-mode-prompt-content) - :on-accept #(rf/dispatch [:profile.settings/profile-update :test-networks-enabled? - (not value) - {:on-success on-success}]) + :on-accept (fn [] + (rf/dispatch [:profile.settings/profile-update :test-networks-enabled? + test-networks-disabled? + {:on-success #(rf/dispatch [:profile/logout])}])) :on-cancel nil}]]}))) (rf/reg-event-fx :profile.settings/change-preview-privacy @@ -58,8 +57,7 @@ (rf/reg-event-fx :profile.settings/change-profile-pictures-show-to (fn [{:keys [db]} [id]] - {:db (-> db - (assoc-in [:profile/profile :profile-pictures-show-to] id)) + {:db (assoc-in db [:profile/profile :profile-pictures-show-to] id) :fx [[:json-rpc/call [{:method "wakuext_changeIdentityImageShowTo" :params [id] @@ -97,8 +95,7 @@ (rf/reg-event-fx :profile.settings/save-profile-picture (fn [{:keys [db]} [path ax ay bx by]] (let [key-uid (get-in db [:profile/profile :key-uid])] - {:db (-> db - (assoc :bottom-sheet/show? false)) + {:db (assoc db :bottom-sheet/show? false) :fx [[:json-rpc/call [{:method "multiaccounts_storeIdentityImage" :params [key-uid (string/replace-first path #"file://" "") ax ay bx @@ -109,8 +106,7 @@ (rf/reg-event-fx :profile.settings/save-profile-picture-from-url (fn [{:keys [db]} [url]] (let [key-uid (get-in db [:profile/profile :key-uid])] - {:db (-> db - (assoc :bottom-sheet/show? false)) + {:db (assoc db :bottom-sheet/show? false) :fx [[:json-rpc/call [{:method "multiaccounts_storeIdentityImageFromURL" :params [key-uid url] @@ -147,3 +143,14 @@ (fn [_ [currency]] {:fx [[:dispatch [:profile.settings/profile-update :currency currency]] [:dispatch [:wallet/get-wallet-token-for-all-accounts]]]})) + +;; Logout process +(rf/reg-event-fx + :profile.settings/ask-logout + (fn [_ _] + {:fx [[:ui/show-confirmation + {:title (i18n/label :t/logout-title) + :content (i18n/label :t/logout-are-you-sure) + :confirm-button-text (i18n/label :t/logout) + :on-accept #(rf/dispatch [:profile/logout]) + :on-cancel nil}]]})) diff --git a/src/status_im/contexts/profile/settings/screens/password/change_password/loading.cljs b/src/status_im/contexts/profile/settings/screens/password/change_password/loading.cljs index e8099391dd..b843475112 100644 --- a/src/status_im/contexts/profile/settings/screens/password/change_password/loading.cljs +++ b/src/status_im/contexts/profile/settings/screens/password/change_password/loading.cljs @@ -12,7 +12,7 @@ (defn- handle-logout [] - (rf/dispatch [:multiaccounts.logout.ui/logout-pressed]) + (rf/dispatch [:profile.settings/ask-logout]) (rf/dispatch [:change-password/reset])) (defn view @@ -21,6 +21,7 @@ [minimum-loading-timeout-done? set-minimum-loading-timeout-done] (rn/use-state false) loading? (rf/sub [:settings/change-password-loading]) + logging-out? (rf/sub [:profile/logging-out?]) done? (and (not loading?) minimum-loading-timeout-done?)] (rn/use-mount (fn [] (js/setTimeout @@ -39,8 +40,7 @@ :description-text (if done? (i18n/label :t/change-password-done-description) (i18n/label :t/change-password-loading-description))}] - [rn/view - {:style style/loading-content} + [rn/view {:style style/loading-content} (when-not done? [quo/information-box {:type :error @@ -50,5 +50,6 @@ (when done? [quo/logout-button {:container-style style/logout-container + :disabled? logging-out? :on-press handle-logout}])]])) diff --git a/src/status_im/contexts/profile/settings/view.cljs b/src/status_im/contexts/profile/settings/view.cljs index 03c59036c7..d74449a3bf 100644 --- a/src/status_im/contexts/profile/settings/view.cljs +++ b/src/status_im/contexts/profile/settings/view.cljs @@ -32,20 +32,23 @@ (let [current-y (oops/oget event "nativeEvent.contentOffset.y")] (reanimated/set-shared-value scroll-y current-y))) +(defn- logout-press + [] + (rf/dispatch [:profile.settings/ask-logout])) + (defn- footer - [{:keys [bottom]} logout-press] + [{:keys [bottom]}] (rn/delay-render - [rn/view {:style (style/footer-container bottom)} - [quo/logout-button {:on-press logout-press}]])) + (let [logging-out? (rf/sub [:profile/logging-out?])] + [rn/view {:style (style/footer-container bottom)} + [quo/logout-button + {:on-press logout-press + :disabled? logging-out?}]]))) (defn- get-item-layout [_ index] #js {:length 100 :offset (* 100 index) :index index}) -(defn logout-press - [] - (rf/dispatch [:multiaccounts.logout.ui/logout-pressed])) - (defn view [] (let [theme (quo.theme/use-theme) @@ -83,7 +86,7 @@ :shows-vertical-scroll-indicator false :render-fn settings-category-view :get-item-layout get-item-layout - :footer [footer insets logout-press] + :footer [footer insets] :scroll-event-throttle 16 :on-scroll on-scroll :bounces false diff --git a/src/status_im/contexts/settings/wallet/network_settings/testnet_mode/view.cljs b/src/status_im/contexts/settings/wallet/network_settings/testnet_mode/view.cljs index e1008782fb..8442276566 100644 --- a/src/status_im/contexts/settings/wallet/network_settings/testnet_mode/view.cljs +++ b/src/status_im/contexts/settings/wallet/network_settings/testnet_mode/view.cljs @@ -11,7 +11,7 @@ (defn logout [] - (rf/dispatch [:logout])) + (rf/dispatch [:profile/logout])) (defn on-confirm-change [enable?] diff --git a/src/status_im/subs/root.cljs b/src/status_im/subs/root.cljs index 7981d9adad..4b27862673 100644 --- a/src/status_im/subs/root.cljs +++ b/src/status_im/subs/root.cljs @@ -88,6 +88,7 @@ (reg-root-key-sub :profile/profiles-overview :profile/profiles-overview) (reg-root-key-sub :profile/login :profile/login) (reg-root-key-sub :profile/profile :profile/profile) +(reg-root-key-sub :profile/logging-out? :profile/logging-out?) (reg-root-key-sub :profile/wallet-accounts :profile/wallet-accounts) (reg-root-key-sub :multiaccount/reset-password-form-vals :multiaccount/reset-password-form-vals) diff --git a/src/test_helpers/integration.cljs b/src/test_helpers/integration.cljs index 2a714ebae5..646db61716 100644 --- a/src/test_helpers/integration.cljs +++ b/src/test_helpers/integration.cljs @@ -2,7 +2,6 @@ (:require [cljs.test :refer [is] :as test] legacy.status-im.events - [legacy.status-im.multiaccounts.logout.core :as logout] legacy.status-im.subs.root [native-module.core :as native-module] [promesa.core :as promesa] @@ -96,7 +95,7 @@ (defn logout [] (log/info (str "==== before dispatch logout ====")) - (rf/dispatch [:logout])) + (rf/dispatch [:profile/logout])) (defn log-headline [test-name] @@ -259,7 +258,7 @@ (setup-account) (logout) (log/info (str "==== before wait-for logout ====")) - (wait-for [::logout/logout-method]) + (wait-for [:profile.logout/reset-state]) (log/info (str "==== after wait-for logout ====")))))) ;;;; Fixtures @@ -287,7 +286,7 @@ (test/async done (promesa/do (logout) (log/info (str "==== before wait-for logout ====")) - (wait-for [::logout/logout-method]) + (wait-for [:profile.logout/reset-state]) (log/info (str "==== after wait-for logout ====")) (done))))}) ([] (fixture-session [:new-account]))) diff --git a/test/appium/tests/activity_center/test_activity_center.py b/test/appium/tests/activity_center/test_activity_center.py index 26fc8ef5ae..40500c6804 100644 --- a/test/appium/tests/activity_center/test_activity_center.py +++ b/test/appium/tests/activity_center/test_activity_center.py @@ -170,8 +170,7 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC self.home_2.just_fyi("Device 2 sign in, user name is " + self.username_2) self.home_2.reopen_app(sign_in=False) self.device_2.show_profiles_button.wait_and_click() - self.device_2.get_user_profile_by_name(username=self.username_2).click() - self.device_2.sign_in() + self.device_2.sign_in(user_name=self.username_2) self.loop.run_until_complete(run_in_parallel(((_device_1_creates_user, {}), (_device_2_sign_in, {})))) @@ -466,7 +465,7 @@ class TestActivityMultipleDevicePRTwo(MultipleSharedDeviceTestCase): community_name = 'closed community' self.channel_name = "dogs" self.home_1.create_community(community_type="closed") - self.home_1.reopen_app() + self.home_1.reopen_app(user_name=self.username_1) self.community_1.invite_to_community(community_name, self.username_2) self.home_2.just_fyi("Request access to community") diff --git a/test/appium/tests/critical/chats/test_1_1_public_chats.py b/test/appium/tests/critical/chats/test_1_1_public_chats.py index 69424f1956..88ef684993 100644 --- a/test/appium/tests/critical/chats/test_1_1_public_chats.py +++ b/test/appium/tests/critical/chats/test_1_1_public_chats.py @@ -687,7 +687,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUiTwo(MultipleSharedDeviceTestCase chat = self.home_2.get_chat_from_home_view(self.username_1) if chat.is_element_displayed(): self.errors.append("Deleted '%s' chat is shown, but the chat has been deleted" % self.username_1) - self.home_2.reopen_app() + self.home_2.reopen_app(user_name=self.username_2) if chat.is_element_displayed(15): self.errors.append( "Deleted chat '%s' is shown after re-login, but the chat has been deleted" % self.username_1) diff --git a/test/appium/tests/critical/chats/test_group_chat.py b/test/appium/tests/critical/chats/test_group_chat.py index ebe3c88e3c..081b9c5f2e 100644 --- a/test/appium/tests/critical/chats/test_group_chat.py +++ b/test/appium/tests/critical/chats/test_group_chat.py @@ -186,7 +186,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase): ))) self.chats[0].just_fyi("Admin relogins") - self.chats[0].reopen_app() + self.chats[0].reopen_app(user_name=self.usernames[0]) self.homes[0].get_chat(self.chat_name).click() self.chats[0].just_fyi("Admin checks reactions count after relogin") @@ -277,7 +277,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase): # workaround for app closed after navigating back from gallery if not self.chats[2].chat_message_input.is_element_displayed(): self.drivers[2].activate_app(app_package) - SignInView(self.drivers[2]).sign_in() + SignInView(self.drivers[2]).sign_in(user_name=self.usernames[2]) self.homes[2].chats_tab.click() self.homes[2].get_chat(self.chat_name).click() @@ -291,7 +291,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase): # workaround for app closed after navigating back from gallery if not self.chats[2].chats_tab.is_element_displayed(): self.drivers[2].activate_app(app_package) - SignInView(self.drivers[2]).sign_in() + SignInView(self.drivers[2]).sign_in(user_name=self.usernames[2]) self.homes[2].chats_tab.click() self.errors.verify_no_errors() @@ -331,7 +331,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase): # workaround for app closed after opening notifications if not self.homes[0].chats_tab.is_element_displayed(): self.drivers[0].activate_app(app_package) - SignInView(self.drivers[0]).sign_in() + SignInView(self.drivers[0]).sign_in(user_name=self.usernames[0]) self.homes[0].chats_tab.click() self.homes[0].get_chat(self.chat_name).click() diff --git a/test/appium/tests/critical/chats/test_public_chat_browsing.py b/test/appium/tests/critical/chats/test_public_chat_browsing.py index 90aa42bb3f..1acf419b41 100644 --- a/test/appium/tests/critical/chats/test_public_chat_browsing.py +++ b/test/appium/tests/critical/chats/test_public_chat_browsing.py @@ -42,7 +42,7 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase): self.channel.send_message(text_message) self.channel.chat_element_by_text(text_message).wait_for_visibility_of_element() - self.channel.reopen_app() + self.channel.reopen_app(user_name=self.username) if not self.channel.chat_element_by_text(text_message).is_element_displayed(30): self.drivers[0].fail("Not navigated to channel view after reopening app") @@ -158,7 +158,8 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase): def test_restore_multiaccount_with_waku_backup_remove_profile_switch(self): self.home.reopen_app(sign_in=False) self.home.just_fyi("Restore user with predefined communities and contacts") - self.sign_in.recover_access(passphrase=waku_user.seed, second_user=True) + recover_user_name = 'Recover user' + self.sign_in.recover_access(passphrase=waku_user.seed, second_user=True, username=recover_user_name) self.home.just_fyi("Check contacts/blocked users") self.home.chats_tab.click() @@ -216,10 +217,7 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase): profile.perform_backup_button.click() self.home.just_fyi("Check that can login with different user") - self.home.reopen_app(sign_in=False) - self.sign_in.show_profiles_button.wait_and_click() - self.sign_in.element_by_text(self.username).click() - self.sign_in.sign_in() + self.home.reopen_app(user_name=self.username) self.home.navigate_back_to_home_view() self.home.communities_tab.click() if self.home.element_by_text(waku_user.communities['admin_open']).is_element_displayed(30): @@ -227,7 +225,6 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase): self.home.just_fyi("Check that can remove user from logged out state") self.home.reopen_app(sign_in=False) - self.sign_in.show_profiles_button.wait_and_click() user_card = self.sign_in.get_user_profile_by_name(username=self.username) user_card.open_user_options() self.sign_in.remove_profile_button.click() @@ -237,8 +234,6 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase): self.home.just_fyi("Check that removed user is not shown in the list anymore") self.home.reopen_app(sign_in=False) - self.sign_in.explore_new_status_button.click_until_presence_of_element(self.sign_in.show_profiles_button) - self.sign_in.show_profiles_button.wait_and_click() if self.sign_in.element_by_text(self.username).is_element_displayed(): self.errors.append("Removed user is re-appeared after relogin!") @@ -248,15 +243,14 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase): def test_community_discovery(self): try: # workaround for case if a user is logged out in the previous test - self.sign_in.get_user_profile_by_index(index=1).click() - self.sign_in.sign_in() + self.sign_in.sign_in(user_name=self.username) except NoSuchElementException: pass self.home.navigate_back_to_home_view() self.home.just_fyi("Turn off testnet in the profile settings") profile = self.home.profile_button.click() profile.switch_network() - self.sign_in.sign_in() + self.sign_in.sign_in(user_name=self.username) self.home.just_fyi("Check Discover Communities content") self.home.communities_tab.click() @@ -1192,7 +1186,7 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase): self.home_1.just_fyi("Device 1 goes back online") self.home_1.driver.activate_app(app_package) - self.device_1.sign_in() + self.device_1.sign_in(user_name=self.username_1) self.home_2.just_fyi("Device 2 checks that he's joined the community") exp_text = "You joined ā€œ%sā€" % community_name diff --git a/test/appium/tests/critical/test_deep_and_universal_links.py b/test/appium/tests/critical/test_deep_and_universal_links.py index a8babea534..94bfe7070e 100644 --- a/test/appium/tests/critical/test_deep_and_universal_links.py +++ b/test/appium/tests/critical/test_deep_and_universal_links.py @@ -131,7 +131,7 @@ class TestDeepLinksOneDevice(MultipleSharedDeviceTestCase): self.driver.terminate_app(app_package) community_url = "https://status.app/c/Ow==#zQ3shbmfT3hvh4mKa1v6uAjjyztQEroh8Mfn6Ckegjd7LT3XK" self.home.open_link_from_google_search_app(community_url, app_package) - self.sign_in.sign_in() + self.sign_in.sign_in(user_name=self.username) if not self.community_view.join_button.is_element_displayed(10): self.errors.append("Closed community was not requested to join by the url %s" % community_url) diff --git a/test/appium/tests/critical/test_wallet.py b/test/appium/tests/critical/test_wallet.py index b272587eb2..bcf5c5eddc 100644 --- a/test/appium/tests/critical/test_wallet.py +++ b/test/appium/tests/critical/test_wallet.py @@ -83,8 +83,8 @@ class TestWalletMultipleDevice(MultipleSharedDeviceTestCase): self.wallet_2.wallet_tab.is_element_displayed() time.sleep(10) self.loop.run_until_complete( - run_in_parallel(((self.home_1.reopen_app,), - (self.home_2.reopen_app,)))) + run_in_parallel(((self.home_1.reopen_app, {'user_name': self.sender_username}), + (self.home_2.reopen_app, {'user_name': self.receiver_username})))) self.wallet_1.wallet_tab.wait_and_click() self.wallet_2.wallet_tab.wait_and_click() self.wallet_1.select_network(network_name='Arbitrum') @@ -216,7 +216,7 @@ class TestWalletOneDevice(MultipleSharedDeviceTestCase): def test_wallet_balance_mainnet(self): self.profile_view = self.home_view.profile_button.click() self.profile_view.switch_network() - self.sign_in_view.sign_in() + self.sign_in_view.sign_in(user_name=self.sender_username) self.sign_in_view.wallet_tab.click() self.wallet_view.just_fyi("Checking total balance") diff --git a/test/appium/views/base_view.py b/test/appium/views/base_view.py index bef651e1c1..60c833db81 100644 --- a/test/appium/views/base_view.py +++ b/test/appium/views/base_view.py @@ -703,14 +703,14 @@ class BaseView(object): time.sleep(1) raise TimeoutException(msg="Status app is not terminated after %s sec" % wait_time) - def reopen_app(self, password=common_password, sign_in=True): + def reopen_app(self, password=common_password, sign_in=True, user_name=None): app_package = self.driver.current_package self.driver.terminate_app(app_package) self.wait_for_application_to_not_run(app_package=app_package) self.driver.activate_app(app_package) if sign_in: sign_in_view = self.get_sign_in_view() - sign_in_view.sign_in(password) + sign_in_view.sign_in(user_name, password) def close_share_popup(self): self.driver.info("Closing share popup") diff --git a/test/appium/views/sign_in_view.py b/test/appium/views/sign_in_view.py index 769bac5374..e10c9c362f 100644 --- a/test/appium/views/sign_in_view.py +++ b/test/appium/views/sign_in_view.py @@ -269,7 +269,6 @@ class SignInView(BaseView): self.create_profile_button.click_until_presence_of_element(self.generate_keys_button) self.not_now_button.wait_and_click() else: - self.show_profiles_button.wait_and_click(20) self.plus_profiles_button.click() self.create_new_profile_button.click() self.use_recovery_phrase_button.click() @@ -302,8 +301,9 @@ class SignInView(BaseView): self.enter_sync_code_input.send_keys(sync_code) self.confirm_button.click() - def sign_in(self, password=common_password): + def sign_in(self, user_name, password=common_password): self.driver.info("## Sign in (password: %s)" % password, device=False) + self.get_user_profile_by_name(user_name).click() self.password_input.wait_for_visibility_of_element(10) self.password_input.send_keys(password) self.login_button.click()