amplify-android: no proper error callback triggers for `confirmSignIn()` when incorrect OTP is entered

Before opening, please confirm:

Language and Async Model

Kotlin

Amplify Categories

Authentication

Gradle script dependencies


// Amplify core dependency
    implementation 'com.amplifyframework:core:2.2.2'
    implementation 'com.amplifyframework:aws-auth-cognito:2.2.2'

Environment information

# Put output below this line

Please include any relevant guides or documentation you’re referencing

https://github.com/aws-amplify/amplify-android/issues/2227

Describe the bug

I tried version 2.2.2 on Android. But the issue is still exist as mentioned on this ticket https://github.com/aws-amplify/amplify-android/issues/2227. SDK doesn’t return anything when I enter wrong OTP or auth challenge. Therefore there is no way to handle retrying Amplify.Auth.confirmSignIn(). Please kindly help to resolve this issue.

Also we found that iOS also has reported a similar issue and We verified that iOS issue has resolved in the latest SDK https://github.com/aws-amplify/amplify-swift/pull/2617

Reproduction steps (if applicable)

Steps to reproduce the behavior:

  1. Call SignIn
  2. Call Amplify.Auth.confirmSignIn() with the wrong code or auth challenge
  3. SDK doesn’t return anything

Code Snippet

// Put your code below this line.
try {
        Amplify.Auth.confirmSignIn(
                otpNumber,
                { result ->
                    if (result.isSignedIn) {
                        LogUtil.printDebug("AuthQuickstart", "Confirm sign in succeeded: $result")
                        

                    } else {
                        LogUtil.printError(
                            "AuthQuickstart",
                            "Confirm sign in not complete. There might be additional steps: ${result.nextStep}"
                        )
                    }
                },
                { error ->
                    LogUtil.printError("AuthQuickstart", "Failed to confirm sign in - $error")
                }
            )
        } catch (error: Exception) {
            LogUtil.printError("AuthQuickstart", "Failed to confirm sign in - $error")
        }

Log output

// Put your logs below this line

amplifyconfiguration.json

No response

GraphQL Schema

// Put your schema below this line


Additional information and screenshots

Device Logs Screenshot 2023-03-21 at 6 24 55 PM

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 1
  • Comments: 18 (9 by maintainers)

Most upvoted comments

Hi @sameera26 I am actively looking into this and Will provide an update shortly.

Hi @Domnis that is certainly the kind of information I was looking for and will help me investigate further.

I will get back to you soon.

Hello ! I’m facing the same issue in my project. But I found something that could help to resolve the issue. The Amplify SDK (version 2.8.5 in my case) works as expected only if the flow is configured to accept only 1 attempt. In that case, if the code provide by the user is incorrect, the lambda fill the response object with this values

event.response.issueTokens = false;
event.response.failAuthentication = true;

and in app, method Amplify.Auth.confirmSignIn(challengeResponse) throw an exception NotAuthorizedException(message=Incorrect username or password.).

On the other hand, if our signIn flow is configured to accept multiple attempts, in case of wrong code provide by user, our lambda will the response with

event.response.issueTokens = false;
event.response.failAuthentication = false;
event.response.challengeName = "CUSTOM_CHALLENGE";

to let know we’re still waiting for a correct response and user can still retry for the same last code sent. But in this case, SDK’s method Amplify.Auth.confirmSignIn(challengeResponse) never return a response nor throw an exception, so app stay in pending result state.

As noted in first post, iOS SDK have fix this issue. I also found this ticket https://github.com/aws-amplify/aws-sdk-android/issues/2653 which seems to be related to this issue.

The code is merged in @sameera26 tracking for release this week. Once released I will communicate here with the release version. Thank you.

The fix is present in release 2.10.0. Please update and let us know if you have any issues. I will keep this ticket open for a week in case there are any issues.

Friendly follow-up on my previous comment.

Hi @gpanshu I have the same issue as @sameera26. I used CUSTOM_AUTH_WITHOUT_SRP auth flow and has no response after calling confirmSignIn with incorrect OTP code. However the auth flow would be triggered AuthSignInStep.DONE as expected and signed in successfully if I entered a correct OTP code.

Here is my pseudocode and logs:

   suspend fun signIn(
        account: String
    ) = suspendCancellableCoroutine<CognitoAuthResult> { continuation ->
        Timber.i("Ready to sign in: $account")
        Amplify.Auth.signIn(
            account,
            null,
            AWSCognitoAuthSignInOptions.CognitoBuilder()
                .authFlowType(AuthFlowType.CUSTOM_AUTH_WITHOUT_SRP)
                .build(),
            {
                Timber.i("signIn ${it.nextStep.additionalInfo?.get("USERNAME")} ${it.nextStep.additionalInfo?.get("XXXX")}")
                continuation.resume(
                    CognitoAuthResult(
                        it.isSignedIn,
                        it.nextStep.additionalInfo?.get("USERNAME") ?: "",
                        it.nextStep.additionalInfo?.get("XXXX") ?: ""
                    )
                )
            },
            {
                continuation.cancel(it)
                Timber.e(it)
            }
        )
    }

   suspend fun confirmSignIn(
        challengeCode: String,
        XXXX: String,
        YYYY: String
    ) = suspendCancellableCoroutine<CognitoAuthResult> { continuation ->
        Timber.i("confirmSignIn input: $challengeCode")
        Amplify.Auth.confirmSignIn(
            challengeCode,
            AWSCognitoAuthConfirmSignInOptions.builder()
                .metadata(
                    mapOf(
                        "XXXX" to XXXX,
                        "YYYY" to YYYY
                    )
                )
                .build(),
            {
                Timber.i("confirmSignIn result: $it")
                continuation.resume(
                    CognitoAuthResult(
                        it.isSignedIn,
                        "",
                        serviceSessionId
                    )
                )
            },
            {
                Timber.e(it)
                continuation.cancel(it)
            }
        )
    }
2023-04-28 13:47:34.686 CognitoLoginDelegate    com.example.ininmm                    I  Ready to sign in: 0988556687_TW
2023-04-28 13:47:37.254 CognitoLog...ate$signIn com.example.ininmm                    I  signIn 0988556687_TW 644b5df9af9285befe702d47
2023-04-28 13:47:41.685 CognitoLoginDelegate    com.example.ininmm                    I  confirmSignIn input: 000000