Amplify-android: Amplify Android "CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE" not handled by Amplify/AWSCognitoAuthPlugin

Created on 4 Sep 2020  路  3Comments  路  Source: aws-amplify/amplify-android

Describe the bug
The confirmSignIn method doesn't handle the CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE. It used to be possible with the AWSMobileClient, but it seems it's not possible anymore through Amplify.

To Reproduce
Steps to reproduce the behavior:

  1. Use the signIn(...) method with the CUSTOM_AUTH flow in your amplify-configuration.json file
  2. Try to confirmSignIn(...) with (for example) the code received by SMS. You will have an error:
confirmSignIn called on unsupported operation, please file a feature request

Look at the switch in the confirmSignIn(...) method:

final CognitoIdentityProviderContinuation detectedContinuation;
switch (signInState) {
    case SMS_MFA:
        signInMfaContinuation.setMfaCode(signInChallengeResponse);
        signInMfaContinuation.setClientMetaData(clientMetadata);
        detectedContinuation = signInMfaContinuation;
        signInCallback = new InternalCallback<SignInResult>(callback);
        break;
    case NEW_PASSWORD_REQUIRED:
        ((NewPasswordContinuation) signInChallengeContinuation).setPassword(signInChallengeResponse);
        signInChallengeContinuation.setClientMetaData(clientMetadata);
        detectedContinuation = signInChallengeContinuation;
        signInCallback = new InternalCallback<SignInResult>(callback);
        break;
    case DONE:
        callback.onError(new IllegalStateException("confirmSignIn called after signIn has succeeded"));
        return;
    default:
        callback.onError(new IllegalStateException("confirmSignIn called on unsupported operation, " +
            "please file a feature request"));
        return;
}

Expected behavior
The confirmSignIn(...) method through Amplify / AWSCognitoAuthPlugin should be able to handle the case of CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE.

Additional context
If I try directly to use AWSMobileClient, there is no problem.

Auth Feature Request

Most helpful comment

What's going on with this issue?

I ended up by implementing it by myself (still with rxJava2, but should be almost the same with rxJava3). But I would expect it already in the new lib :/

fun RxAuthCategoryBehavior.confirmSignInWithCustomChallenge(secret: String): Single<AuthSignInResult> =
    (Amplify.Auth.getPlugin("awsCognitoAuthPlugin").escapeHatch as AWSMobileClient).rxConfirmSignIn(mutableMapOf(CognitoServiceConstants.CHLG_RESP_ANSWER to secret))
        .map { signInResult -> signInResult.authSignInResult }
/**
 * Rx wrapper for [AWSMobileClient.confirmSignIn]
 */
fun AWSMobileClient.rxConfirmSignIn(signInChallengeResponse: MutableMap<String, String>): Single<SignInResult> =
    Single.create { emitter ->
        confirmSignIn(signInChallengeResponse, object : Callback<SignInResult> {
            override fun onResult(result: SignInResult) {
                emitter.onSuccess(result)
            }

            override fun onError(e: Exception) {
                emitter.onError(e)
            }
        })
    }
/**
 * Copied from [com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin].
 * Same as com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin#convertSignInResult
 */
private val SignInResult.authSignInResult: AuthSignInResult
    @Throws(AuthException::class)
    get() = AuthSignInResult(
        SignInState.DONE == signInState,
        AuthNextSignInStep(
            SignInStateConverter.getAuthSignInStep(signInState),
            if (parameters == null) emptyMap() else parameters,
            codeDetails.authCodeDeliveryDetails
        )
    )

/**
 * Copied from [com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin].
 * Same as com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin#convertCodeDeliveryDetails
 */
private val UserCodeDeliveryDetails?.authCodeDeliveryDetails: AuthCodeDeliveryDetails?
    get() = this?.let {
        AuthCodeDeliveryDetails(
            it.destination,
            AuthCodeDeliveryDetails.DeliveryMedium.fromString(it.deliveryMedium),
            it.attributeName
        )
    }

And then I use it like this:

 RxAmplify.Auth.confirmSignInWithCustomChallenge("[RECEIVED_CODE]")

All 3 comments

Thanks @AntoEko . Will have a member of the Android team reproduce this.

What's going on with this issue?

I ended up by implementing it by myself (still with rxJava2, but should be almost the same with rxJava3). But I would expect it already in the new lib :/

fun RxAuthCategoryBehavior.confirmSignInWithCustomChallenge(secret: String): Single<AuthSignInResult> =
    (Amplify.Auth.getPlugin("awsCognitoAuthPlugin").escapeHatch as AWSMobileClient).rxConfirmSignIn(mutableMapOf(CognitoServiceConstants.CHLG_RESP_ANSWER to secret))
        .map { signInResult -> signInResult.authSignInResult }
/**
 * Rx wrapper for [AWSMobileClient.confirmSignIn]
 */
fun AWSMobileClient.rxConfirmSignIn(signInChallengeResponse: MutableMap<String, String>): Single<SignInResult> =
    Single.create { emitter ->
        confirmSignIn(signInChallengeResponse, object : Callback<SignInResult> {
            override fun onResult(result: SignInResult) {
                emitter.onSuccess(result)
            }

            override fun onError(e: Exception) {
                emitter.onError(e)
            }
        })
    }
/**
 * Copied from [com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin].
 * Same as com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin#convertSignInResult
 */
private val SignInResult.authSignInResult: AuthSignInResult
    @Throws(AuthException::class)
    get() = AuthSignInResult(
        SignInState.DONE == signInState,
        AuthNextSignInStep(
            SignInStateConverter.getAuthSignInStep(signInState),
            if (parameters == null) emptyMap() else parameters,
            codeDetails.authCodeDeliveryDetails
        )
    )

/**
 * Copied from [com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin].
 * Same as com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin#convertCodeDeliveryDetails
 */
private val UserCodeDeliveryDetails?.authCodeDeliveryDetails: AuthCodeDeliveryDetails?
    get() = this?.let {
        AuthCodeDeliveryDetails(
            it.destination,
            AuthCodeDeliveryDetails.DeliveryMedium.fromString(it.deliveryMedium),
            it.attributeName
        )
    }

And then I use it like this:

 RxAmplify.Auth.confirmSignInWithCustomChallenge("[RECEIVED_CODE]")

Same issue here. At the moment I handle this via AWSMobileClient

Was this page helpful?
0 / 5 - 0 ratings