From 025b9839c83d9a43565eb9853329cbaf19e8edeb Mon Sep 17 00:00:00 2001
From: Taras Smakula <tarassmakula@gmail.com>
Date: Thu, 29 Feb 2024 16:37:07 +0200
Subject: [PATCH] Add forgot password uia

---
 .../auth/feature/log_in/LoginDataSource.kt    | 17 ++++++++++-------
 .../circles/auth/feature/uia/UIADataSource.kt |  4 ++++
 .../validate_email/ValidateEmailDataSource.kt | 19 +++++++++++++++----
 .../validate_email/ValidateEmailFragment.kt   | 12 +++++++++++-
 .../validate_email/ValidateEmailViewModel.kt  |  1 +
 5 files changed, 41 insertions(+), 12 deletions(-)

diff --git a/auth/src/main/java/org/futo/circles/auth/feature/log_in/LoginDataSource.kt b/auth/src/main/java/org/futo/circles/auth/feature/log_in/LoginDataSource.kt
index b262c87c4..6e3a96ef5 100644
--- a/auth/src/main/java/org/futo/circles/auth/feature/log_in/LoginDataSource.kt
+++ b/auth/src/main/java/org/futo/circles/auth/feature/log_in/LoginDataSource.kt
@@ -5,11 +5,12 @@ import dagger.hilt.android.qualifiers.ApplicationContext
 import org.futo.circles.auth.R
 import org.futo.circles.auth.feature.uia.UIADataSource
 import org.futo.circles.auth.feature.uia.UIADataSource.Companion.DIRECT_LOGIN_PASSWORD_TYPE
+import org.futo.circles.auth.feature.uia.UIADataSource.Companion.ENROLL_BSSPEKE_SAVE_TYPE
+import org.futo.circles.auth.feature.uia.UIADataSource.Companion.ENROLL_EMAIL_SUBMIT_TOKEN_TYPE
 import org.futo.circles.auth.feature.uia.UIADataSource.Companion.LOGIN_BSSPEKE_VERIFY_TYPE
+import org.futo.circles.auth.feature.uia.UIADataSource.Companion.LOGIN_EMAIL_SUBMIT_TOKEN_TYPE
 import org.futo.circles.auth.feature.uia.UIADataSource.Companion.LOGIN_PASSWORD_TYPE
 import org.futo.circles.auth.feature.uia.UIADataSource.Companion.LOGIN_PASSWORD_USER_ID_TYPE
-import org.futo.circles.auth.feature.uia.UIADataSource.Companion.ENROLL_BSSPEKE_SAVE_TYPE
-import org.futo.circles.auth.feature.uia.UIADataSource.Companion.ENROLL_EMAIL_SUBMIT_TOKEN_TYPE
 import org.futo.circles.auth.feature.uia.UIADataSource.Companion.TYPE_PARAM_KEY
 import org.futo.circles.auth.feature.uia.UIADataSource.Companion.USER_PARAM_KEY
 import org.futo.circles.auth.feature.uia.UIADataSourceProvider
@@ -22,12 +23,10 @@ import javax.inject.Inject
 
 class LoginDataSource @Inject constructor(
     @ApplicationContext private val context: Context,
-    uiaFactory: UIADataSource.Factory
+    private val uiaFactory: UIADataSource.Factory
 ) {
 
-    private val uiaDataSource by lazy {
-        UIADataSourceProvider.create(UIAFlowType.Login, uiaFactory)
-    }
+
     private val authService by lazy { MatrixInstanceProvider.matrix.authenticationService() }
 
     suspend fun startLogin(
@@ -37,6 +36,10 @@ class LoginDataSource @Inject constructor(
     ) = createResult {
         authService.cancelPendingLoginOrRegistration()
         val stages = prepareLoginStages(userName, domain, isForgotPassword)
+        val uiaDataSource = UIADataSourceProvider.create(
+            if (isForgotPassword) UIAFlowType.ForgotPassword else UIAFlowType.Login,
+            uiaFactory
+        )
         uiaDataSource.startUIAStages(stages, domain, userName)
     }
 
@@ -85,7 +88,7 @@ class LoginDataSource @Inject constructor(
     private fun getCircleStagesForForgotPassword(flows: List<List<Stage>>): List<Stage>? =
         flows.firstOrNull { stages ->
             val containsEmailStage = stages.firstOrNull { stage ->
-                (stage as? Stage.Other)?.type == ENROLL_EMAIL_SUBMIT_TOKEN_TYPE
+                (stage as? Stage.Other)?.type == LOGIN_EMAIL_SUBMIT_TOKEN_TYPE
             } != null
             val containsSetPassword = stages.firstOrNull { stage ->
                 (stage as? Stage.Other)?.type == ENROLL_BSSPEKE_SAVE_TYPE
diff --git a/auth/src/main/java/org/futo/circles/auth/feature/uia/UIADataSource.kt b/auth/src/main/java/org/futo/circles/auth/feature/uia/UIADataSource.kt
index 83bf5a80c..01a620e78 100644
--- a/auth/src/main/java/org/futo/circles/auth/feature/uia/UIADataSource.kt
+++ b/auth/src/main/java/org/futo/circles/auth/feature/uia/UIADataSource.kt
@@ -127,7 +127,9 @@ abstract class UIADataSource {
 
         LOGIN_REGISTRATION_TOKEN_TYPE -> UIANavigationEvent.TokenValidation
         SUBSCRPTION_GOOGLE_TYPE -> UIANavigationEvent.Subscription
+        LOGIN_EMAIL_REQUEST_TOKEN_TYPE,
         ENROLL_EMAIL_REQUEST_TOKEN_TYPE -> UIANavigationEvent.ValidateEmail
+        LOGIN_EMAIL_SUBMIT_TOKEN_TYPE,
         ENROLL_EMAIL_SUBMIT_TOKEN_TYPE -> null //stay on same screen
         ENROLL_USERNAME_TYPE -> UIANavigationEvent.Username
         ENROLL_PASSWORD_TYPE,
@@ -170,6 +172,8 @@ abstract class UIADataSource {
         const val SUBSCRPTION_GOOGLE_TYPE = "org.futo.subscriptions.google_play"
 
         //stages email
+        const val LOGIN_EMAIL_REQUEST_TOKEN_TYPE = "m.login.email.request_token"
+        const val LOGIN_EMAIL_SUBMIT_TOKEN_TYPE = "m.login.email.submit_token"
         const val ENROLL_EMAIL_REQUEST_TOKEN_TYPE = "m.enroll.email.request_token"
         const val ENROLL_EMAIL_SUBMIT_TOKEN_TYPE = "m.enroll.email.submit_token"
 
diff --git a/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailDataSource.kt b/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailDataSource.kt
index 04395ccf4..7a369e356 100644
--- a/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailDataSource.kt
+++ b/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailDataSource.kt
@@ -2,6 +2,8 @@ package org.futo.circles.auth.feature.uia.stages.validate_email
 
 import org.futo.circles.auth.feature.uia.UIADataSource.Companion.ENROLL_EMAIL_REQUEST_TOKEN_TYPE
 import org.futo.circles.auth.feature.uia.UIADataSource.Companion.ENROLL_EMAIL_SUBMIT_TOKEN_TYPE
+import org.futo.circles.auth.feature.uia.UIADataSource.Companion.LOGIN_EMAIL_REQUEST_TOKEN_TYPE
+import org.futo.circles.auth.feature.uia.UIADataSource.Companion.LOGIN_EMAIL_SUBMIT_TOKEN_TYPE
 import org.futo.circles.auth.feature.uia.UIADataSource.Companion.TYPE_PARAM_KEY
 import org.futo.circles.auth.feature.uia.UIADataSourceProvider
 import org.futo.circles.core.extensions.Response
@@ -14,11 +16,10 @@ class ValidateEmailDataSource @Inject constructor() {
     private val uiaDataSource = UIADataSourceProvider.getDataSourceOrThrow()
 
     suspend fun sendValidationCode(
-        email: String,
-        subscribeToUpdates: Boolean
+        email: String, subscribeToUpdates: Boolean
     ): Response<RegistrationResult> = uiaDataSource.performUIAStage(
         mapOf(
-            TYPE_PARAM_KEY to ENROLL_EMAIL_REQUEST_TOKEN_TYPE,
+            TYPE_PARAM_KEY to if (isLogin()) LOGIN_EMAIL_REQUEST_TOKEN_TYPE else ENROLL_EMAIL_REQUEST_TOKEN_TYPE,
             EMAIL_PARAM_KEY to email,
             SUBSCRIBE_TO_LIST to subscribeToUpdates
         )
@@ -27,11 +28,20 @@ class ValidateEmailDataSource @Inject constructor() {
     suspend fun validateEmail(code: String): Response<RegistrationResult> =
         uiaDataSource.performUIAStage(
             mapOf(
-                TYPE_PARAM_KEY to ENROLL_EMAIL_SUBMIT_TOKEN_TYPE,
+                TYPE_PARAM_KEY to if (isLogin()) LOGIN_EMAIL_REQUEST_TOKEN_TYPE else ENROLL_EMAIL_SUBMIT_TOKEN_TYPE,
                 TOKEN_PARAM_KEY to code
             )
         )
 
+    private fun isLogin(): Boolean {
+        val currentStageKey = UIADataSourceProvider.getDataSourceOrThrow().getCurrentStageKey()
+        return currentStageKey == LOGIN_EMAIL_REQUEST_TOKEN_TYPE || currentStageKey == LOGIN_EMAIL_SUBMIT_TOKEN_TYPE
+    }
+
+    fun getPrefilledEmail(): String? =
+        if (isLogin()) ((uiaDataSource.currentStage as? Stage.Other)?.params?.get(EMAILS_LIST_KEY) as? List<*>)?.firstOrNull()
+            ?.toString() else null
+
     fun shouldShowSubscribeToEmail(): Boolean =
         (uiaDataSource.currentStage as? Stage.Other)?.params?.get(OFFER_LIST_SUBSCRIPTION_KEY) as? Boolean
             ?: false
@@ -41,5 +51,6 @@ class ValidateEmailDataSource @Inject constructor() {
         private const val TOKEN_PARAM_KEY = "token"
         private const val SUBSCRIBE_TO_LIST = "subscribe_to_list"
         private const val OFFER_LIST_SUBSCRIPTION_KEY = "offer_list_subscription"
+        private const val EMAILS_LIST_KEY = "addresses"
     }
 }
\ No newline at end of file
diff --git a/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailFragment.kt b/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailFragment.kt
index 8a216fa21..96f7ff493 100644
--- a/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailFragment.kt
+++ b/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailFragment.kt
@@ -2,6 +2,7 @@ package org.futo.circles.auth.feature.uia.stages.validate_email
 
 import android.os.Bundle
 import android.view.View
+import androidx.core.view.isVisible
 import androidx.core.widget.doAfterTextChanged
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.viewModels
@@ -37,6 +38,7 @@ class ValidateEmailFragment : ParentBackPressOwnerFragment(R.layout.fragment_val
 
     private fun setupViews() {
         with(binding) {
+            setAlwaysDisabledViews(listOf(binding.etEmail))
             tilEmail.editText?.doAfterTextChanged {
                 it?.let { btnSendCode.isEnabled = it.isValidEmail() }
             }
@@ -57,7 +59,7 @@ class ValidateEmailFragment : ParentBackPressOwnerFragment(R.layout.fragment_val
             }
             btnSendCode.setOnClickListener {
                 startLoading(btnSendCode)
-                viewModel.sendCode(getEmailInput(), cbEmailUpdates.isChecked)
+                viewModel.sendCode(getEmailInput(), cbEmailUpdates.isChecked && cbEmailUpdates.isVisible)
             }
             btnValidate.setOnClickListener {
                 startLoading(btnValidate)
@@ -75,6 +77,14 @@ class ValidateEmailFragment : ParentBackPressOwnerFragment(R.layout.fragment_val
         viewModel.showSubscribeCheckLiveData.observeData(this) {
             binding.cbEmailUpdates.setIsVisible(it)
         }
+        viewModel.usersEmailLiveData.observeData(this) {email->
+            email?.let {
+                binding.etEmail.apply {
+                    setText(it)
+                    isEnabled = false
+                }
+            }
+        }
     }
 
     private fun getEmailInput(): String = binding.tilEmail.getText()
diff --git a/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailViewModel.kt b/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailViewModel.kt
index 0f119f467..b7a1b86fd 100644
--- a/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailViewModel.kt
+++ b/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailViewModel.kt
@@ -18,6 +18,7 @@ class ValidateEmailViewModel @Inject constructor(
     val validateEmailLiveData = SingleEventLiveData<Response<RegistrationResult>>()
 
     val showSubscribeCheckLiveData = MutableLiveData(dataSource.shouldShowSubscribeToEmail())
+    val usersEmailLiveData = MutableLiveData(dataSource.getPrefilledEmail())
 
     fun sendCode(email: String, subscribeToUpdates: Boolean) {
         launchBg {
-- 
GitLab