diff --git a/packages/firebase_auth/firebase_auth/android/src/main/java/io/flutter/plugins/firebase/auth/FlutterFirebaseAuthPlugin.java b/packages/firebase_auth/firebase_auth/android/src/main/java/io/flutter/plugins/firebase/auth/FlutterFirebaseAuthPlugin.java index 9565bb9ebd32..92d05399b746 100755 --- a/packages/firebase_auth/firebase_auth/android/src/main/java/io/flutter/plugins/firebase/auth/FlutterFirebaseAuthPlugin.java +++ b/packages/firebase_auth/firebase_auth/android/src/main/java/io/flutter/plugins/firebase/auth/FlutterFirebaseAuthPlugin.java @@ -1128,6 +1128,10 @@ private Task> linkUserWithCredential(Map arg taskCompletionSource.setResult(parseAuthResult(authResult)); } catch (Exception e) { + if (e.getCause() instanceof FirebaseAuthMultiFactorException) { + handleMultiFactorException(arguments, taskCompletionSource, e); + return; + } String message = e.getMessage(); if (message != null @@ -1169,7 +1173,11 @@ private Task> reauthenticateUserWithCredential( Tasks.await(firebaseUser.reauthenticateAndRetrieveData(credential)); taskCompletionSource.setResult(parseAuthResult(authResult)); } catch (Exception e) { - taskCompletionSource.setException(e); + if (e.getCause() instanceof FirebaseAuthMultiFactorException) { + handleMultiFactorException(arguments, taskCompletionSource, e); + } else { + taskCompletionSource.setException(e); + } } }); diff --git a/packages/firebase_auth/firebase_auth/ios/Classes/FLTFirebaseAuthPlugin.m b/packages/firebase_auth/firebase_auth/ios/Classes/FLTFirebaseAuthPlugin.m index c1b7ed284b62..491978374ebb 100644 --- a/packages/firebase_auth/firebase_auth/ios/Classes/FLTFirebaseAuthPlugin.m +++ b/packages/firebase_auth/firebase_auth/ios/Classes/FLTFirebaseAuthPlugin.m @@ -1064,7 +1064,13 @@ - (void)userLinkWithCredential:(id)arguments [currentUser linkWithCredential:credential completion:^(FIRAuthDataResult *authResult, NSError *error) { if (error != nil) { - result.error(nil, nil, nil, error); + if (error.code == FIRAuthErrorCodeSecondFactorRequired) { + [self handleMultiFactorError:arguments + withResult:result + withError:error]; + } else { + result.error(nil, nil, nil, error); + } } else { result.success(authResult); } @@ -1090,7 +1096,13 @@ - (void)userReauthenticateUserWithCredential:(id)arguments [currentUser reauthenticateWithCredential:credential completion:^(FIRAuthDataResult *authResult, NSError *error) { if (error != nil) { - result.error(nil, nil, nil, error); + if (error.code == FIRAuthErrorCodeSecondFactorRequired) { + [self handleMultiFactorError:arguments + withResult:result + withError:error]; + } else { + result.error(nil, nil, nil, error); + } } else { result.success(authResult); } diff --git a/packages/firebase_auth/firebase_auth/lib/src/user.dart b/packages/firebase_auth/firebase_auth/lib/src/user.dart index ce6391269d3b..0cf504fa513b 100644 --- a/packages/firebase_auth/firebase_auth/lib/src/user.dart +++ b/packages/firebase_auth/firebase_auth/lib/src/user.dart @@ -184,10 +184,16 @@ class User { /// - Thrown if the credential is a [PhoneAuthProvider.credential] and the /// verification ID of the credential is not valid. Future linkWithCredential(AuthCredential credential) async { - return UserCredential._( - _auth, - await _delegate.linkWithCredential(credential), - ); + try { + return UserCredential._( + _auth, + await _delegate.linkWithCredential(credential), + ); + } on FirebaseAuthMultiFactorExceptionPlatform catch (e) { + throw FirebaseAuthMultiFactorException._(_auth, e); + } catch (e) { + rethrow; + } } /// Links with an AuthProvider using native authentication flow. @@ -273,10 +279,16 @@ class User { Future reauthenticateWithProvider( AuthProvider provider, ) async { - return UserCredential._( - _auth, - await _delegate.reauthenticateWithProvider(provider), - ); + try { + return UserCredential._( + _auth, + await _delegate.reauthenticateWithProvider(provider), + ); + } on FirebaseAuthMultiFactorExceptionPlatform catch (e) { + throw FirebaseAuthMultiFactorException._(_auth, e); + } catch (e) { + rethrow; + } } /// Re-authenticates a user using a popup on Web. @@ -480,12 +492,18 @@ class User { // also clear that instance before proceeding. bool mustClear = verifier == null; verifier ??= RecaptchaVerifier(auth: _delegate.auth); - final result = - await _delegate.linkWithPhoneNumber(phoneNumber, verifier.delegate); - if (mustClear) { - verifier.clear(); + try { + final result = + await _delegate.linkWithPhoneNumber(phoneNumber, verifier.delegate); + if (mustClear) { + verifier.clear(); + } + return ConfirmationResult._(_auth, result); + } on FirebaseAuthMultiFactorExceptionPlatform catch (e) { + throw FirebaseAuthMultiFactorException._(_auth, e); + } catch (e) { + rethrow; } - return ConfirmationResult._(_auth, result); } /// Re-authenticates a user using a fresh credential. @@ -520,10 +538,16 @@ class User { Future reauthenticateWithCredential( AuthCredential credential, ) async { - return UserCredential._( - _auth, - await _delegate.reauthenticateWithCredential(credential), - ); + try { + return UserCredential._( + _auth, + await _delegate.reauthenticateWithCredential(credential), + ); + } on FirebaseAuthMultiFactorExceptionPlatform catch (e) { + throw FirebaseAuthMultiFactorException._(_auth, e); + } catch (e) { + rethrow; + } } /// Refreshes the current user, if signed in. diff --git a/packages/firebase_auth/firebase_auth_web/lib/firebase_auth_web.dart b/packages/firebase_auth/firebase_auth_web/lib/firebase_auth_web.dart index d9653262b487..7ef5524f7234 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/firebase_auth_web.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/firebase_auth_web.dart @@ -57,8 +57,12 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { if (webUser == null) { return null; } else { - return UserWeb(this, - MultiFactorWeb(this, multi_factor.multiFactor(webUser)), webUser); + return UserWeb( + this, + MultiFactorWeb(this, multi_factor.multiFactor(webUser)), + webUser, + _webAuth, + ); } }).listen((UserWeb? webUser) { _authStateChangesListeners[app.name]!.add(webUser); @@ -70,8 +74,12 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { if (webUser == null) { return null; } else { - return UserWeb(this, - MultiFactorWeb(this, multi_factor.multiFactor(webUser)), webUser); + return UserWeb( + this, + MultiFactorWeb(this, multi_factor.multiFactor(webUser)), + webUser, + _webAuth, + ); } }).listen((UserWeb? webUser) { _idTokenChangesListeners[app.name]!.add(webUser); @@ -136,9 +144,11 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { } return UserWeb( - this, - MultiFactorWeb(this, multi_factor.multiFactor(delegate.currentUser!)), - delegate.currentUser!); + this, + MultiFactorWeb(this, multi_factor.multiFactor(delegate.currentUser!)), + delegate.currentUser!, + _webAuth, + ); } @override @@ -192,6 +202,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { return UserCredentialWeb( this, await delegate.createUserWithEmailAndPassword(email, password), + _webAuth, ); } catch (e) { throw getFirebaseAuthException(e); @@ -210,7 +221,11 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { @override Future getRedirectResult() async { try { - return UserCredentialWeb(this, await delegate.getRedirectResult()); + return UserCredentialWeb( + this, + await delegate.getRedirectResult(), + _webAuth, + ); } catch (e) { throw getFirebaseAuthException(e); } @@ -297,20 +312,27 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { @override Future signInAnonymously() async { try { - return UserCredentialWeb(this, await delegate.signInAnonymously()); + return UserCredentialWeb( + this, + await delegate.signInAnonymously(), + _webAuth, + ); } catch (e) { - throw getFirebaseAuthException(e); + throw getFirebaseAuthException(e, _webAuth); } } @override Future signInWithCredential( - AuthCredential credential) async { + AuthCredential credential, + ) async { try { return UserCredentialWeb( - this, - await delegate - .signInWithCredential(convertPlatformCredential(credential)!)); + this, + await delegate + .signInWithCredential(convertPlatformCredential(credential)!), + _webAuth, + ); } catch (e) { throw getFirebaseAuthException(e, _webAuth); } @@ -320,7 +342,10 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { Future signInWithCustomToken(String token) async { try { return UserCredentialWeb( - this, await delegate.signInWithCustomToken(token)); + this, + await delegate.signInWithCustomToken(token), + _webAuth, + ); } catch (e) { throw getFirebaseAuthException(e, _webAuth); } @@ -331,7 +356,10 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { String email, String password) async { try { return UserCredentialWeb( - this, await delegate.signInWithEmailAndPassword(email, password)); + this, + await delegate.signInWithEmailAndPassword(email, password), + _webAuth, + ); } catch (e) { throw getFirebaseAuthException(e, _webAuth); } @@ -342,7 +370,10 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { String email, String emailLink) async { try { return UserCredentialWeb( - this, await delegate.signInWithEmailLink(email, emailLink)); + this, + await delegate.signInWithEmailLink(email, emailLink), + _webAuth, + ); } catch (e) { throw getFirebaseAuthException(e, _webAuth); } @@ -358,7 +389,10 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { auth_interop.RecaptchaVerifier verifier = applicationVerifier.delegate; return ConfirmationResultWeb( - this, await delegate.signInWithPhoneNumber(phoneNumber, verifier)); + this, + await delegate.signInWithPhoneNumber(phoneNumber, verifier), + _webAuth, + ); } catch (e) { throw getFirebaseAuthException(e, _webAuth); } @@ -370,6 +404,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { return UserCredentialWeb( this, await delegate.signInWithPopup(convertPlatformAuthProvider(provider)), + _webAuth, ); } catch (e) { throw getFirebaseAuthException(e, _webAuth); diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_confirmation_result.dart b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_confirmation_result.dart index 80fbf1d6cd3e..ccaa91b9c94b 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_confirmation_result.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_confirmation_result.dart @@ -14,18 +14,25 @@ import 'utils/web_utils.dart'; /// The web delegate implementation for [ConfirmationResultPlatform]. class ConfirmationResultWeb extends ConfirmationResultPlatform { /// Creates a new [ConfirmationResultWeb] instance. - ConfirmationResultWeb(this._auth, this._webConfirmationResult) - : super(_webConfirmationResult.verificationId); + ConfirmationResultWeb( + this._auth, + this._webConfirmationResult, + this._webAuth, + ) : super(_webConfirmationResult.verificationId); final FirebaseAuthPlatform _auth; final auth_interop.ConfirmationResult _webConfirmationResult; + final auth_interop.Auth? _webAuth; @override Future confirm(String verificationCode) async { try { return UserCredentialWeb( - _auth, await _webConfirmationResult.confirm(verificationCode)); + _auth, + await _webConfirmationResult.confirm(verificationCode), + _webAuth, + ); } catch (e) { throw getFirebaseAuthException(e); } diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_multi_factor.dart b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_multi_factor.dart index f6bb6525aaab..9c45e578cb84 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_multi_factor.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_multi_factor.dart @@ -10,6 +10,7 @@ import 'package:firebase_auth_web/firebase_auth_web.dart'; import 'package:firebase_auth_web/src/firebase_auth_web_user_credential.dart'; import 'interop/auth.dart' as auth; +import 'interop/auth.dart' as auth_interop; import 'interop/multi_factor.dart' as multi_factor_interop; import 'utils/web_utils.dart'; @@ -92,9 +93,11 @@ class MultiFactorResolverWeb extends MultiFactorResolverPlatform { MultiFactorSession session, this._auth, this._webMultiFactorResolver, + this._webAuth, ) : super(hints, session); final multi_factor_interop.MultiFactorResolver _webMultiFactorResolver; + final auth_interop.Auth? _webAuth; final FirebaseAuthWeb _auth; @override @@ -106,6 +109,7 @@ class MultiFactorResolverWeb extends MultiFactorResolverPlatform { return UserCredentialWeb( _auth, await _webMultiFactorResolver.resolveSignIn(webAssertion.assertion), + _webAuth, ); } } diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user.dart b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user.dart index f196da71992e..c60faff4b519 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user.dart @@ -20,8 +20,11 @@ final DateFormat _dateFormat = DateFormat('EEE, d MMM yyyy HH:mm:ss', 'en_US'); class UserWeb extends UserPlatform { /// Creates a new [UserWeb] instance. UserWeb( - FirebaseAuthPlatform auth, MultiFactorPlatform multiFactor, this._webUser) - : super(auth, multiFactor, { + FirebaseAuthPlatform auth, + MultiFactorPlatform multiFactor, + this._webUser, + this._webAuth, + ) : super(auth, multiFactor, { 'displayName': _webUser.displayName, 'email': _webUser.email, 'emailVerified': _webUser.emailVerified, @@ -56,6 +59,7 @@ class UserWeb extends UserPlatform { }); final auth_interop.User _webUser; + final auth_interop.Auth? _webAuth; @override Future delete() async { @@ -91,11 +95,13 @@ class UserWeb extends UserPlatform { _assertIsSignedOut(auth); try { return UserCredentialWeb( - auth, - await _webUser - .linkWithCredential(convertPlatformCredential(credential))); + auth, + await _webUser + .linkWithCredential(convertPlatformCredential(credential)), + _webAuth, + ); } catch (e) { - throw getFirebaseAuthException(e); + throw getFirebaseAuthException(e, _webAuth); } } @@ -103,10 +109,13 @@ class UserWeb extends UserPlatform { Future linkWithPopup(AuthProvider provider) async { _assertIsSignedOut(auth); try { - return UserCredentialWeb(auth, - await _webUser.linkWithPopup(convertPlatformAuthProvider(provider))); + return UserCredentialWeb( + auth, + await _webUser.linkWithPopup(convertPlatformAuthProvider(provider)), + _webAuth, + ); } catch (e) { - throw getFirebaseAuthException(e); + throw getFirebaseAuthException(e, _webAuth); } } @@ -115,7 +124,7 @@ class UserWeb extends UserPlatform { try { return _webUser.linkWithRedirect(convertPlatformAuthProvider(provider)); } catch (e) { - throw getFirebaseAuthException(e); + throw getFirebaseAuthException(e, _webAuth); } } @@ -132,9 +141,10 @@ class UserWeb extends UserPlatform { return ConfirmationResultWeb( auth, await _webUser.linkWithPhoneNumber(phoneNumber, verifier), + _webAuth, ); } catch (e) { - throw getFirebaseAuthException(e); + throw getFirebaseAuthException(e, _webAuth); } } @@ -145,9 +155,9 @@ class UserWeb extends UserPlatform { try { auth_interop.UserCredential userCredential = await _webUser .reauthenticateWithCredential(convertPlatformCredential(credential)!); - return UserCredentialWeb(auth, userCredential); + return UserCredentialWeb(auth, userCredential, _webAuth); } catch (e) { - throw getFirebaseAuthException(e); + throw getFirebaseAuthException(e, _webAuth); } } @@ -158,9 +168,9 @@ class UserWeb extends UserPlatform { try { auth_interop.UserCredential userCredential = await _webUser .reauthenticateWithPopup(convertPlatformAuthProvider(provider)); - return UserCredentialWeb(auth, userCredential); + return UserCredentialWeb(auth, userCredential, _webAuth); } catch (e) { - throw getFirebaseAuthException(e); + throw getFirebaseAuthException(e, _webAuth); } } @@ -183,7 +193,7 @@ class UserWeb extends UserPlatform { await _webUser.reload(); auth.sendAuthChangesEvent(auth.app.name, auth.currentUser); } catch (e) { - throw getFirebaseAuthException(e); + throw getFirebaseAuthException(e, _webAuth); } } @@ -196,7 +206,7 @@ class UserWeb extends UserPlatform { convertPlatformActionCodeSettings(actionCodeSettings), ); } catch (e) { - throw getFirebaseAuthException(e); + throw getFirebaseAuthException(e, _webAuth); } } @@ -205,9 +215,14 @@ class UserWeb extends UserPlatform { _assertIsSignedOut(auth); try { - return UserWeb(auth, multiFactor, await _webUser.unlink(providerId)); + return UserWeb( + auth, + multiFactor, + await _webUser.unlink(providerId), + _webAuth, + ); } catch (e) { - throw getFirebaseAuthException(e); + throw getFirebaseAuthException(e, _webAuth); } } @@ -220,7 +235,7 @@ class UserWeb extends UserPlatform { await _webUser.reload(); auth.sendAuthChangesEvent(auth.app.name, auth.currentUser); } catch (e) { - throw getFirebaseAuthException(e); + throw getFirebaseAuthException(e, _webAuth); } } @@ -233,7 +248,7 @@ class UserWeb extends UserPlatform { await _webUser.reload(); auth.sendAuthChangesEvent(auth.app.name, auth.currentUser); } catch (e) { - throw getFirebaseAuthException(e); + throw getFirebaseAuthException(e, _webAuth); } } @@ -247,7 +262,7 @@ class UserWeb extends UserPlatform { await _webUser.reload(); auth.sendAuthChangesEvent(auth.app.name, auth.currentUser); } catch (e) { - throw getFirebaseAuthException(e); + throw getFirebaseAuthException(e, _webAuth); } } @@ -278,7 +293,7 @@ class UserWeb extends UserPlatform { await _webUser.reload(); auth.sendAuthChangesEvent(auth.app.name, auth.currentUser); } catch (e) { - throw getFirebaseAuthException(e); + throw getFirebaseAuthException(e, _webAuth); } } @@ -294,7 +309,7 @@ class UserWeb extends UserPlatform { convertPlatformActionCodeSettings(actionCodeSettings), ); } catch (e) { - throw getFirebaseAuthException(e); + throw getFirebaseAuthException(e, _webAuth); } } } diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user_credential.dart b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user_credential.dart index 319e5d6a2e8f..3a10c6bc7a86 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user_credential.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user_credential.dart @@ -17,6 +17,7 @@ class UserCredentialWeb extends UserCredentialPlatform { UserCredentialWeb( FirebaseAuthPlatform auth, auth_interop.UserCredential webUserCredential, + auth_interop.Auth? webAuth, ) : super( auth: auth, additionalUserInfo: convertWebAdditionalUserInfo( @@ -24,8 +25,10 @@ class UserCredentialWeb extends UserCredentialPlatform { ), credential: convertWebOAuthCredential(webUserCredential), user: UserWeb( - auth, - MultiFactorWeb(auth, multiFactor(webUserCredential.user!)), - webUserCredential.user!), + auth, + MultiFactorWeb(auth, multiFactor(webUserCredential.user!)), + webUserCredential.user!, + webAuth, + ), ); } diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/utils/web_utils.dart b/packages/firebase_auth/firebase_auth_web/lib/src/utils/web_utils.dart index 8a961fe5f2f0..1e260b3bcea2 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/utils/web_utils.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/utils/web_utils.dart @@ -80,6 +80,7 @@ FirebaseAuthException getFirebaseAuthException( MultiFactorSessionWeb('web', resolverWeb.session), FirebaseAuthWeb.instance, resolverWeb, + auth, ), ); }