Skip to content

Commit

Permalink
feat: show correct error message when a user login with handle when 2…
Browse files Browse the repository at this point in the history
… is enabled [WPB-1813] (#3688)
  • Loading branch information
MohamadJaara authored Dec 6, 2024
1 parent b27fe6a commit 885ec53
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -307,13 +307,22 @@ fun LoginErrorDialog(
dismissOnClickOutside = false
)

LoginState.Error.DialogError.PasswordNeededToRegisterClient -> TODO()

else -> LoginDialogErrorData(
title = stringResource(R.string.error_unknown_title),
body = AnnotatedString(stringResource(R.string.error_unknown_message)),
onDismiss = onDialogDismiss
)
LoginState.Error.DialogError.Request2FAWithHandle -> {
LoginDialogErrorData(
title = stringResource(R.string.login_error_request_2fa_with_handle_title),
body = AnnotatedString(stringResource(R.string.login_error_request_2fa_with_handle_message)),
onDismiss = onDialogDismiss
)
}
LoginState.Error.TextFieldError.InvalidValue,
LoginState.Error.DialogError.PasswordNeededToRegisterClient,
LoginState.Error.TooManyDevicesError -> {
LoginDialogErrorData(
title = stringResource(R.string.error_unknown_title),
body = AnnotatedString(stringResource(R.string.error_unknown_message)),
onDismiss = onDialogDismiss
)
}
}

WireDialog(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ sealed class LoginState {
data object InvalidSSOCodeError : DialogError()
data object UserAlreadyExists : DialogError()
data object PasswordNeededToRegisterClient : DialogError()
data object Request2FAWithHandle : DialogError()
data class SSOResultError(val result: SSOFailureCodes) :
DialogError()
data object ServerVersionNotSupported : DialogError()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,14 @@ class LoginEmailViewModel @Inject constructor(
}

private suspend fun request2FACode(authScope: AuthenticationScope) {
val email = userIdentifierTextState.text.trim().toString()
val email = userIdentifierTextState.text.trim().toString().also {
// user is using handle to login when 2FA is required
if (!it.contains("@")) {
updateEmailFlowState(LoginState.Error.DialogError.Request2FAWithHandle)
return
}
}

val result = authScope.requestSecondFactorVerificationCode(
email = email,
verifiableAction = VerifiableAction.LOGIN_OR_CLIENT_REGISTRATION
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,8 @@
<string name="login_sso_code_label">SSO CODE OR EMAIL</string>
<string name="login_error_invalid_sso_code">Please enter a valid SSO code.</string>
<string name="login_error_invalid_sso_code_format">Enter a valid SSO code</string>
<string name="login_error_request_2fa_with_handle_title">Login with email</string>
<string name="login_error_request_2fa_with_handle_message">You can\'t use your username as two-factor authentication is activated. Please log in with your email instead.</string>
<string name="deleted_user_error_title">Deleted account</string>
<string name="deleted_user_error_message">You were logged out because your account was
deleted.
Expand Down Expand Up @@ -1637,5 +1639,4 @@ In group conversations, the group admin can overwrite this setting.</string>
<string name="personal_to_team_migration_error_message_already_in_team">You\'ve created or joined a team with this email address on another device.</string>
<string name="personal_to_team_migration_error_message_slow_network">Wire could not complete your team creation due to a slow internet connection.</string>
<string name="personal_to_team_migration_error_message_unknown_error">Wire could not complete your team creation due to an unknown error.</string>

</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runTest
import org.amshove.kluent.internal.assertEquals
import org.amshove.kluent.shouldBe
import org.amshove.kluent.shouldBeEqualTo
import org.amshove.kluent.shouldBeInstanceOf
Expand Down Expand Up @@ -491,6 +492,20 @@ class LoginEmailViewModelTest {
coVerify(exactly = 1) { getOrRegisterClientUseCase(match { it.secondFactorVerificationCode == null }) }
}

@Test
fun `given 2fa is needed, when user used handle to login, then show correct error message`() = runTest {
val email = "some.handle"
val code = "123456"
coEvery { loginUseCase(any(), any(), any(), any(), any()) } returns AuthenticationResult.Failure.InvalidCredentials.Missing2FA

loginViewModel.userIdentifierTextState.setTextAndPlaceCursorAtEnd(email)
loginViewModel.secondFactorVerificationCodeTextState.setTextAndPlaceCursorAtEnd(code)
advanceUntilIdle()
coVerify(exactly = 0) { addAuthenticatedUserUseCase(any(), any(), any(), any()) }
coVerify(exactly = 0) { getOrRegisterClientUseCase(any()) }
assertEquals(LoginState.Error.DialogError.Request2FAWithHandle, loginViewModel.loginState.flowState)
}

companion object {
val CLIENT = TestClient.CLIENT
val SSO_ID: SsoId = SsoId("scim_id", null, null)
Expand Down

0 comments on commit 885ec53

Please sign in to comment.