flutterfire icon indicating copy to clipboard operation
flutterfire copied to clipboard

[firebase_auth]: Inconsistent error handling for TOTP multi-factor auth

Open IshchikGL opened this issue 8 months ago • 7 comments

Is there an existing issue for this?

  • [x] I have searched the existing issues.

Which plugins are affected?

Auth

Which platforms are affected?

Android, iOS

Description

We have enabled the TOTP MFA in our project. The main issue I faced was the mismatch between the error representation on Android and iOS platforms produced by the same test case.

The cases we want to cover are:

  1. Invalid TOTP code. The user has entered the wrong code from the authenticator app.
  • Android: an exception is thrown invalid-verification-code code
  • iOS: an exception is thrown with resolve-signin-failed code and The multifactor verification code used to create the auth credential is invalid. Re-collect the verification code and be sure to use the verification code provided by the user. message
  1. TOTP session timeout. User stayed too long on the 2FA verification page before submitting the code.
  • Android: an exception is thrown with unknown error code and An internal error has occurred. [TOTP_CHALLENGE_TIMEOUT:TOTP challenge timeout, provide first factor again.] message.
  • iOS: an exception is thrown with resolve-signin-failed and An internal error has occurred, print and inspect the error details for more information. message.
  1. The number of attempts is exceeded. When the exceeded the maximum allowed number of the retries.
  • Android: an exception is thrown with too-many-requests code
  • iOS: an exception is thrown with resolve-signin-failed code and Exceeded quota. message

It feels really bad to have different behaviours among the platforms if it's related to the same functionality. It would be great to map the error codes for 2FA from the native implementations and have them documented it as for iOS link

Reproduces on:

  firebase_auth: ^5.1.2
  firebase_core: ^3.2.0

Reproducing the issue

Firebase auth wrapper:

***
  final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
  // MultiFactorResolver that was provided from the most recent auth attempt but failed on 2FA exception from Firebase
MultiFactorResolver? _resolver;
***
Future<User?> signInWithEmailAndPassword(
    String email,
    String password,
  ) async {
    try {
      final result = await firebaseAuth.signInWithEmailAndPassword(
        email: email,
        password: password,
      );

      final user = result.user;

      return user;
    } on FirebaseAuthMultiFactorException catch (e) {
      _resolver = e.resolver;

      rethrow;
    }
  }

***
// Resolve the 2FA sign in
Future<User?> resolveTFASignIn(String code) async {
    final resolver = _resolver;
    if (resolver == null) {
      throw Exception('No recent authentication attempts detected');
    }

    // Currently we support only 2FA with TOTP
    // Check for hints.factorId in case more than one factor is supported
    final enrollmentId = resolver.hints.first.uid;

    final assertion = await TotpMultiFactorGenerator.getAssertionForSignIn(
      enrollmentId,
      code,
    );

    final resultCredentials = await resolver.resolveSignIn(assertion);
    final user = resultCredentials.user;

    return user;
  }

Use the wrapper:

Future<core.User> verifyTFACode({required String code}) async {
    try {
      final firebaseUser = await firebaseAuthWrapper.resolveTFASignIn(code);

      return firebaseUser.toUser;
    } on firebase.FirebaseAuthException catch (e) {
      print(e);
}

Firebase Core version

3.2.0

Flutter Version

3.22.3

Relevant Log Output


Flutter dependencies

Expand Flutter dependencies snippet

Replace this line with the contents of your `flutter pub deps -- --style=compact`.

Additional context and comments

No response

IshchikGL avatar Mar 31 '25 14:03 IshchikGL

Hi @IshchikGL, could you update your FlutterFire plugins and check if the issue still persists?

SelaseKay avatar Apr 02 '25 07:04 SelaseKay

@SelaseKay sorry for the late response So I upgraded to firebase_core: ^3.13.0 and firebase_auth: ^5.5.2. Flutter pub deps output:

- firebase_auth 5.5.2 [firebase_auth_platform_interface firebase_auth_web firebase_core firebase_core_platform_interface flutter meta]
- firebase_core 3.13.0 [firebase_core_platform_interface firebase_core_web flutter meta]

- firebase_auth_platform_interface 7.6.2 [_flutterfire_internals collection firebase_core flutter meta plugin_platform_interface]
- firebase_auth_web 5.14.2 [firebase_auth_platform_interface firebase_core firebase_core_web flutter flutter_web_plugins http_parser meta web]
- firebase_core_platform_interface 5.4.0 [collection flutter flutter_test meta plugin_platform_interface]
- firebase_core_web 2.22.0 [firebase_core_platform_interface flutter flutter_web_plugins meta web]

Exception codes:

  1. Invalid code
  • Android: code invalid-verification-code with message The verification code from SMS/TOTP is invalid. Please check and enter the correct verification code again.
  • iOS: code resolve-signin-failed with message The multifactor verification code used to create the auth credential is invalid. Re-collect the verification code and be sure to use the verification code provided by the user.
  1. TOTP session timeout
  • Android: code unknown with message: An internal error has occurred. [ TOTP_CHALLENGE_TIMEOUT:TOTP challenge timeout, provide first factor again.
  • iOS: code resolve-signin-failed with message An internal error has occurred, print and inspect the error details for more information.
  1. Quota exceeded
  • Android: code too-many-requests with message We have blocked all requests from this device due to unusual activity. Try again later.
  • iOS: code resolve-signin-failed with message Exceeded quota.

Looks like the issue still persists

IshchikGL avatar Apr 06 '25 12:04 IshchikGL

Hi @IshchikGL, thanks for the additional feedback. After further investigation, I've noticed some few things. While we aim to throw native error codes, the behavior can vary across platforms, which is often outside our control. That said, the second issue you mentioned (TOTP session timeout) does seem unusual. Android returning an unknown error code is not expected. I will go ahead and create a PR to address that.

SelaseKay avatar Apr 25 '25 15:04 SelaseKay

@SelaseKay thanks for the effort So, in case of iOS session timeout, will we be getting that message pointing to nothing? We can't fully rely on the code we get Let me know if I can assist

IshchikGL avatar Apr 25 '25 15:04 IshchikGL

Hey there, after trying to reproduce, we been getting different errors. [enroll-failed] every time for any issue. Can you please provide some steps you took to get the exact error codes?

MichaelVerdon avatar Apr 30 '25 12:04 MichaelVerdon

@MichaelVerdon we have users already enrolled for TOTP 2FA. Please, check the cases described above. User has to use any of available sign-in methods from FirebaseAuth and then he's prompted to enter the TOTP code. After that there are few cases you can try to reproduce:

  1. The user has entered the wrong code from the authenticator app.
  2. User stayed too long on the 2FA verification page before submitting the code.
  3. The number of attempts is exceeded. When the exceeded the maximum allowed number of the retries.

Please, let me know if you need any information

IshchikGL avatar May 01 '25 13:05 IshchikGL

Hi there, understood. We tried exactly that and got different errors retrieved but will give it a go again.

MichaelVerdon avatar May 02 '25 08:05 MichaelVerdon

Hello, differences in errors could be likely due to just how the native packages handle errors as there are usually discrepancy's between them, I think it is likely this is what it is for some of it.

MichaelVerdon avatar Oct 17 '25 12:10 MichaelVerdon

Hey @IshchikGL. We need more information to resolve this issue but there hasn't been an update in 7 weekdays. I'm marking the issue as stale and if there are no new updates in the next 7 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

google-oss-bot avatar Oct 27 '25 18:10 google-oss-bot

Since there haven't been any recent updates here, I am going to close this issue.

@IshchikGL if you're still experiencing this problem and want to continue the discussion just leave a comment here and we are happy to re-open this.

google-oss-bot avatar Nov 04 '25 18:11 google-oss-bot