Skip to content

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

Open
@IshchikGL

Description

@IshchikGL

Is there an existing issue for this?

  • 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

Metadata

Metadata

Assignees

Labels

Needs AttentionThis issue needs maintainer attention.platform: androidIssues / PRs which are specifically for Android.platform: iosIssues / PRs which are specifically for iOS.plugin: authtype: bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions