mirror of
https://github.com/element-hq/element-android
synced 2024-12-18 15:24:33 +03:00
Login screens: set initial device name
This commit is contained in:
parent
ac377fceba
commit
20ad3abb60
6 changed files with 59 additions and 77 deletions
|
@ -38,10 +38,15 @@ interface Authenticator {
|
||||||
* @param homeServerConnectionConfig this param is used to configure the Homeserver
|
* @param homeServerConnectionConfig this param is used to configure the Homeserver
|
||||||
* @param login the login field
|
* @param login the login field
|
||||||
* @param password the password field
|
* @param password the password field
|
||||||
|
* @param deviceName the initial device name
|
||||||
* @param callback the matrix callback on which you'll receive the result of authentication.
|
* @param callback the matrix callback on which you'll receive the result of authentication.
|
||||||
* @return return a [Cancelable]
|
* @return return a [Cancelable]
|
||||||
*/
|
*/
|
||||||
fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig, login: String, password: String, callback: MatrixCallback<Session>): Cancelable
|
fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||||
|
login: String,
|
||||||
|
password: String,
|
||||||
|
deviceName: String,
|
||||||
|
callback: MatrixCallback<Session>): Cancelable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if there is an authenticated [Session].
|
* Check if there is an authenticated [Session].
|
||||||
|
|
|
@ -77,10 +77,11 @@ internal class DefaultAuthenticator @Inject constructor(@Unauthenticated
|
||||||
override fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig,
|
override fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||||
login: String,
|
login: String,
|
||||||
password: String,
|
password: String,
|
||||||
|
deviceName: String,
|
||||||
callback: MatrixCallback<Session>): Cancelable {
|
callback: MatrixCallback<Session>): Cancelable {
|
||||||
val job = GlobalScope.launch(coroutineDispatchers.main) {
|
val job = GlobalScope.launch(coroutineDispatchers.main) {
|
||||||
val sessionOrFailure = runCatching {
|
val sessionOrFailure = runCatching {
|
||||||
authenticate(homeServerConnectionConfig, login, password)
|
authenticate(homeServerConnectionConfig, login, password, deviceName)
|
||||||
}
|
}
|
||||||
sessionOrFailure.foldToCallback(callback)
|
sessionOrFailure.foldToCallback(callback)
|
||||||
}
|
}
|
||||||
|
@ -97,12 +98,13 @@ internal class DefaultAuthenticator @Inject constructor(@Unauthenticated
|
||||||
|
|
||||||
private suspend fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig,
|
private suspend fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||||
login: String,
|
login: String,
|
||||||
password: String) = withContext(coroutineDispatchers.io) {
|
password: String,
|
||||||
|
deviceName: String) = withContext(coroutineDispatchers.io) {
|
||||||
val authAPI = buildAuthAPI(homeServerConnectionConfig)
|
val authAPI = buildAuthAPI(homeServerConnectionConfig)
|
||||||
val loginParams = if (Patterns.EMAIL_ADDRESS.matcher(login).matches()) {
|
val loginParams = if (Patterns.EMAIL_ADDRESS.matcher(login).matches()) {
|
||||||
PasswordLoginParams.thirdPartyIdentifier(ThreePidMedium.EMAIL, login, password, "Mobile")
|
PasswordLoginParams.thirdPartyIdentifier(ThreePidMedium.EMAIL, login, password, deviceName)
|
||||||
} else {
|
} else {
|
||||||
PasswordLoginParams.userIdentifier(login, password, "Mobile")
|
PasswordLoginParams.userIdentifier(login, password, deviceName)
|
||||||
}
|
}
|
||||||
val credentials = executeRequest<Credentials> {
|
val credentials = executeRequest<Credentials> {
|
||||||
apiCall = authAPI.login(loginParams)
|
apiCall = authAPI.login(loginParams)
|
||||||
|
|
|
@ -23,7 +23,7 @@ sealed class LoginAction : VectorViewModelAction {
|
||||||
data class UpdateServerType(val serverType: ServerType) : LoginAction()
|
data class UpdateServerType(val serverType: ServerType) : LoginAction()
|
||||||
data class UpdateHomeServer(val homeServerUrl: String) : LoginAction()
|
data class UpdateHomeServer(val homeServerUrl: String) : LoginAction()
|
||||||
data class UpdateSignMode(val signMode: SignMode) : LoginAction()
|
data class UpdateSignMode(val signMode: SignMode) : LoginAction()
|
||||||
data class Login(val login: String, val password: String) : LoginAction()
|
data class Login(val login: String, val password: String, val initialDeviceName: String) : LoginAction()
|
||||||
data class WebLoginSuccess(val credentials: Credentials) : LoginAction()
|
data class WebLoginSuccess(val credentials: Credentials) : LoginAction()
|
||||||
data class InitWith(val loginConfig: LoginConfig) : LoginAction()
|
data class InitWith(val loginConfig: LoginConfig) : LoginAction()
|
||||||
data class ResetPassword(val email: String, val newPassword: String) : LoginAction()
|
data class ResetPassword(val email: String, val newPassword: String) : LoginAction()
|
||||||
|
@ -31,7 +31,7 @@ sealed class LoginAction : VectorViewModelAction {
|
||||||
// Register actions
|
// Register actions
|
||||||
open class RegisterAction : LoginAction()
|
open class RegisterAction : LoginAction()
|
||||||
|
|
||||||
data class RegisterWith(val username: String, val password: String) : RegisterAction()
|
data class RegisterWith(val username: String, val password: String, val initialDeviceName: String) : RegisterAction()
|
||||||
data class AddEmail(val email: String) : RegisterAction()
|
data class AddEmail(val email: String) : RegisterAction()
|
||||||
data class AddMsisdn(val msisdn: String) : RegisterAction()
|
data class AddMsisdn(val msisdn: String) : RegisterAction()
|
||||||
data class ConfirmMsisdn(val code: String) : RegisterAction()
|
data class ConfirmMsisdn(val code: String) : RegisterAction()
|
||||||
|
|
|
@ -66,8 +66,8 @@ class LoginFragment @Inject constructor(
|
||||||
|
|
||||||
when (loginViewModel.signMode) {
|
when (loginViewModel.signMode) {
|
||||||
SignMode.Unknown -> error("developer error")
|
SignMode.Unknown -> error("developer error")
|
||||||
SignMode.SignUp -> loginViewModel.handle(LoginAction.RegisterWith(login, password))
|
SignMode.SignUp -> loginViewModel.handle(LoginAction.RegisterWith(login, password, getString(R.string.login_mobile_device)))
|
||||||
SignMode.SignIn -> loginViewModel.handle(LoginAction.Login(login, password))
|
SignMode.SignIn -> loginViewModel.handle(LoginAction.Login(login, password, getString(R.string.login_mobile_device)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ import im.vector.riotx.features.session.SessionListener
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO To speed up registration, consider fetching registration flow instead of login flow at startup
|
*
|
||||||
*/
|
*/
|
||||||
class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginViewState,
|
class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginViewState,
|
||||||
private val authenticator: Authenticator,
|
private val authenticator: Authenticator,
|
||||||
|
@ -113,12 +113,7 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleConfirmMsisdn(action: LoginAction.ConfirmMsisdn) {
|
private fun handleConfirmMsisdn(action: LoginAction.ConfirmMsisdn) {
|
||||||
setState {
|
setState { copy(asyncRegistration = Loading()) }
|
||||||
copy(
|
|
||||||
asyncRegistration = Loading()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
currentTask = registrationWizard?.confirmMsisdn(action.code, registrationCallback)
|
currentTask = registrationWizard?.confirmMsisdn(action.code, registrationCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +129,7 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
||||||
|
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
asyncRegistration = Success(data)
|
asyncRegistration = Uninitialized
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,53 +150,32 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleAddMsisdn(action: LoginAction.AddMsisdn) {
|
private fun handleAddMsisdn(action: LoginAction.AddMsisdn) {
|
||||||
setState {
|
setState { copy(asyncRegistration = Loading()) }
|
||||||
copy(
|
|
||||||
asyncRegistration = Loading()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
currentTask = registrationWizard?.addMsisdn(action.msisdn, registrationCallback)
|
currentTask = registrationWizard?.addMsisdn(action.msisdn, registrationCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleAddEmail(action: LoginAction.AddEmail) {
|
private fun handleAddEmail(action: LoginAction.AddEmail) {
|
||||||
setState {
|
setState { copy(asyncRegistration = Loading()) }
|
||||||
copy(
|
|
||||||
asyncRegistration = Loading()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
currentTask = registrationWizard?.addEmail(action.email, registrationCallback)
|
currentTask = registrationWizard?.addEmail(action.email, registrationCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleAcceptTerms() {
|
private fun handleAcceptTerms() {
|
||||||
setState {
|
setState { copy(asyncRegistration = Loading()) }
|
||||||
copy(
|
|
||||||
asyncRegistration = Loading()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
currentTask = registrationWizard?.acceptTerms(registrationCallback)
|
currentTask = registrationWizard?.acceptTerms(registrationCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleRegisterDummy() {
|
private fun handleRegisterDummy() {
|
||||||
setState {
|
setState { copy(asyncRegistration = Loading()) }
|
||||||
copy(
|
|
||||||
asyncRegistration = Loading()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
currentTask = registrationWizard?.dummy(registrationCallback)
|
currentTask = registrationWizard?.dummy(registrationCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleRegisterWith(action: LoginAction.RegisterWith) {
|
private fun handleRegisterWith(action: LoginAction.RegisterWith) {
|
||||||
setState {
|
setState { copy(asyncRegistration = Loading()) }
|
||||||
copy(
|
currentTask = registrationWizard?.createAccount(
|
||||||
asyncRegistration = Loading()
|
action.username,
|
||||||
)
|
action.password,
|
||||||
}
|
action.initialDeviceName,
|
||||||
|
object : MatrixCallbackDelegate<RegistrationResult>(registrationCallback) {
|
||||||
currentTask = registrationWizard?.createAccount(action.username, action.password, null /* TODO InitialDisplayName */, object : MatrixCallbackDelegate<RegistrationResult>(registrationCallback) {
|
|
||||||
override fun onSuccess(data: RegistrationResult) {
|
override fun onSuccess(data: RegistrationResult) {
|
||||||
isPasswordSent = true
|
isPasswordSent = true
|
||||||
// Not sure that this will work:
|
// Not sure that this will work:
|
||||||
|
@ -212,12 +186,7 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleCaptchaDone(action: LoginAction.CaptchaDone) {
|
private fun handleCaptchaDone(action: LoginAction.CaptchaDone) {
|
||||||
setState {
|
setState { copy(asyncRegistration = Loading()) }
|
||||||
copy(
|
|
||||||
asyncRegistration = Loading()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
currentTask = registrationWizard?.performReCaptcha(action.captchaResponse, registrationCallback)
|
currentTask = registrationWizard?.performReCaptcha(action.captchaResponse, registrationCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,7 +306,12 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
currentTask = authenticator.authenticate(homeServerConnectionConfigFinal, action.login, action.password, object : MatrixCallback<Session> {
|
currentTask = authenticator.authenticate(
|
||||||
|
homeServerConnectionConfigFinal,
|
||||||
|
action.login,
|
||||||
|
action.password,
|
||||||
|
action.initialDeviceName,
|
||||||
|
object : MatrixCallback<Session> {
|
||||||
override fun onSuccess(data: Session) {
|
override fun onSuccess(data: Session) {
|
||||||
onSessionCreated(data)
|
onSessionCreated(data)
|
||||||
}
|
}
|
||||||
|
@ -358,9 +332,11 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
||||||
val homeServerConnectionConfigFinal = homeServerConnectionConfig
|
val homeServerConnectionConfigFinal = homeServerConnectionConfig
|
||||||
|
|
||||||
if (homeServerConnectionConfigFinal == null) {
|
if (homeServerConnectionConfigFinal == null) {
|
||||||
|
// Notify the user
|
||||||
|
_viewEvents.post(LoginViewEvents.RegistrationError(Throwable("Bad configuration")))
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
asyncRegistration = Fail(Throwable("Bad configuration"))
|
asyncRegistration = Uninitialized
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -17,13 +17,12 @@
|
||||||
package im.vector.riotx.features.login
|
package im.vector.riotx.features.login
|
||||||
|
|
||||||
import com.airbnb.mvrx.*
|
import com.airbnb.mvrx.*
|
||||||
import im.vector.matrix.android.api.auth.registration.RegistrationResult
|
|
||||||
|
|
||||||
data class LoginViewState(
|
data class LoginViewState(
|
||||||
val asyncLoginAction: Async<Unit> = Uninitialized,
|
val asyncLoginAction: Async<Unit> = Uninitialized,
|
||||||
val asyncHomeServerLoginFlowRequest: Async<LoginMode> = Uninitialized,
|
val asyncHomeServerLoginFlowRequest: Async<LoginMode> = Uninitialized,
|
||||||
val asyncResetPassword: Async<Unit> = Uninitialized,
|
val asyncResetPassword: Async<Unit> = Uninitialized,
|
||||||
val asyncRegistration: Async<RegistrationResult> = Uninitialized
|
val asyncRegistration: Async<Unit> = Uninitialized
|
||||||
) : MvRxState {
|
) : MvRxState {
|
||||||
|
|
||||||
fun isLoading(): Boolean {
|
fun isLoading(): Boolean {
|
||||||
|
|
Loading…
Reference in a new issue