From a8a65496dbedd1c1521e26376032b3646710c4d3 Mon Sep 17 00:00:00 2001 From: Taras Smakula <tarassmakula@gmail.com> Date: Thu, 21 Mar 2024 16:39:59 +0200 Subject: [PATCH] Add savig password with password manager --- .../circles/auth/feature/uia/UIADataSource.kt | 3 ++ .../feature/uia/flow/LoginStagesDataSource.kt | 2 +- .../uia/stages/password/PasswordFragment.kt | 6 +++- .../uia/stages/password/PasswordViewModel.kt | 32 +++++++++++++++---- 4 files changed, 35 insertions(+), 8 deletions(-) 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 01a620e78..0f790b86e 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 @@ -95,6 +95,8 @@ abstract class UIADataSource { else -> LoginFlowTypes.TERMS } + fun getUserId() = "@${userName}:${domain}" + private fun isStageRetry(result: RegistrationResult?): Boolean { val nextStageType = ((result as? RegistrationResult.FlowResponse)?.flowResult?.missingStages?.firstOrNull() as? Stage.Other)?.type @@ -129,6 +131,7 @@ abstract class UIADataSource { 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 diff --git a/auth/src/main/java/org/futo/circles/auth/feature/uia/flow/LoginStagesDataSource.kt b/auth/src/main/java/org/futo/circles/auth/feature/uia/flow/LoginStagesDataSource.kt index b685d2782..2de99217e 100644 --- a/auth/src/main/java/org/futo/circles/auth/feature/uia/flow/LoginStagesDataSource.kt +++ b/auth/src/main/java/org/futo/circles/auth/feature/uia/flow/LoginStagesDataSource.kt @@ -53,7 +53,7 @@ class LoginStagesDataSource @Inject constructor( } private fun getIdentifier() = mapOf( - USER_PARAM_KEY to "@$userName:$domain", + USER_PARAM_KEY to getUserId(), TYPE_PARAM_KEY to LOGIN_PASSWORD_USER_ID_TYPE ) } \ No newline at end of file diff --git a/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/password/PasswordFragment.kt b/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/password/PasswordFragment.kt index 33884332d..ed079c87c 100644 --- a/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/password/PasswordFragment.kt +++ b/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/password/PasswordFragment.kt @@ -49,7 +49,11 @@ class PasswordFragment : ParentBackPressOwnerFragment(R.layout.fragment_password setText(getString(if (isSignupMode()) R.string.set_password else R.string.log_in)) setOnClickListener { startLoading(btnLogin) - viewModel.processPasswordStage(tilPassword.getText()) + viewModel.processPasswordStage( + tilPassword.getText(), + isSignupMode(), + requireContext() + ) } } tilPassword.editText?.apply { diff --git a/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/password/PasswordViewModel.kt b/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/password/PasswordViewModel.kt index febaa25ce..f656588a5 100644 --- a/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/password/PasswordViewModel.kt +++ b/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/password/PasswordViewModel.kt @@ -1,6 +1,7 @@ package org.futo.circles.auth.feature.uia.stages.password import android.content.Context +import androidx.credentials.CreatePasswordRequest import androidx.credentials.CredentialManager import androidx.credentials.GetCredentialRequest import androidx.credentials.GetPasswordOption @@ -23,17 +24,17 @@ class PasswordViewModel @Inject constructor( val passwordResponseLiveData = SingleEventLiveData<Response<Unit>>() val passwordSelectedEventLiveData = SingleEventLiveData<String>() - fun processPasswordStage(password: String) { - launchBg { handlePasswordRequest(password) } + fun processPasswordStage(password: String, isSignup: Boolean, activityContext: Context) { + launchBg { handlePasswordRequest(password, isSignup, activityContext) } } fun getCredentials(activityContext: Context) { launchBg { tryOrNull { val credentialManager = CredentialManager.create(activityContext) - val userName = UIADataSourceProvider.getDataSourceOrThrow().userName + val userId = UIADataSourceProvider.getDataSourceOrThrow().getUserId() val request = GetCredentialRequest( - listOf(GetPasswordOption(allowedUserIds = setOf(userName))) + listOf(GetPasswordOption(allowedUserIds = setOf(userId))) ) val result = credentialManager.getCredential( @@ -44,17 +45,36 @@ class PasswordViewModel @Inject constructor( if (result is PasswordCredential) { val password = result.password passwordSelectedEventLiveData.postValue(password) - handlePasswordRequest(password) + handlePasswordRequest(password, false, activityContext) } } } } - private suspend fun handlePasswordRequest(password: String) { + private suspend fun handlePasswordRequest( + password: String, + isSignup: Boolean, + activityContext: Context + ) { + if (isSignup) registerPassword(activityContext, password) val result = passwordDataSource.processPasswordStage(password) passwordResponseLiveData.postValue(result) } + private suspend fun registerPassword(activityContext: Context, password: String) { + tryOrNull { + val uiaDataSource = UIADataSourceProvider.getDataSourceOrThrow() + val createPasswordRequest = CreatePasswordRequest( + id = uiaDataSource.getUserId(), + password = password + ) + CredentialManager.create(activityContext).createCredential( + activityContext, + createPasswordRequest + ) + } + } + fun isPasswordWarningConfirmed() = isPasswordWarningConfirmed fun confirmPasswordWarning() { isPasswordWarningConfirmed = true -- GitLab