Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(auth): properly propagate the FirebaseAuthMultiFactorException for all reauthenticate and link methods #9700

Merged
merged 4 commits into from Oct 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -1128,6 +1128,10 @@ private Task<Map<String, Object>> linkUserWithCredential(Map<String, Object> 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
Expand Down Expand Up @@ -1169,7 +1173,11 @@ private Task<Map<String, Object>> 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);
}
}
});

Expand Down
Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand Down
58 changes: 41 additions & 17 deletions packages/firebase_auth/firebase_auth/lib/src/user.dart
Expand Up @@ -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<UserCredential> 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.
Expand Down Expand Up @@ -273,10 +279,16 @@ class User {
Future<UserCredential> 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;
}
}

/// Links the user account with the given provider.
Expand Down Expand Up @@ -407,12 +419,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.
Expand Down Expand Up @@ -447,10 +465,16 @@ class User {
Future<UserCredential> 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.
Expand Down
71 changes: 53 additions & 18 deletions packages/firebase_auth/firebase_auth_web/lib/firebase_auth_web.dart
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -192,6 +202,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform {
return UserCredentialWeb(
this,
await delegate.createUserWithEmailAndPassword(email, password),
_webAuth,
);
} catch (e) {
throw getFirebaseAuthException(e);
Expand All @@ -210,7 +221,11 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform {
@override
Future<UserCredentialPlatform> getRedirectResult() async {
try {
return UserCredentialWeb(this, await delegate.getRedirectResult());
return UserCredentialWeb(
this,
await delegate.getRedirectResult(),
_webAuth,
);
} catch (e) {
throw getFirebaseAuthException(e);
}
Expand Down Expand Up @@ -297,20 +312,27 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform {
@override
Future<UserCredentialPlatform> 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<UserCredentialPlatform> 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);
}
Expand All @@ -320,7 +342,10 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform {
Future<UserCredentialPlatform> signInWithCustomToken(String token) async {
try {
return UserCredentialWeb(
this, await delegate.signInWithCustomToken(token));
this,
await delegate.signInWithCustomToken(token),
_webAuth,
);
} catch (e) {
throw getFirebaseAuthException(e, _webAuth);
}
Expand All @@ -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);
}
Expand All @@ -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);
}
Expand All @@ -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);
}
Expand All @@ -370,6 +404,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform {
return UserCredentialWeb(
this,
await delegate.signInWithPopup(convertPlatformAuthProvider(provider)),
_webAuth,
);
} catch (e) {
throw getFirebaseAuthException(e, _webAuth);
Expand Down
Expand Up @@ -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<UserCredentialPlatform> confirm(String verificationCode) async {
try {
return UserCredentialWeb(
_auth, await _webConfirmationResult.confirm(verificationCode));
_auth,
await _webConfirmationResult.confirm(verificationCode),
_webAuth,
);
} catch (e) {
throw getFirebaseAuthException(e);
}
Expand Down
Expand Up @@ -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';

Expand Down Expand Up @@ -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
Expand All @@ -106,6 +109,7 @@ class MultiFactorResolverWeb extends MultiFactorResolverPlatform {
return UserCredentialWeb(
_auth,
await _webMultiFactorResolver.resolveSignIn(webAssertion.assertion),
_webAuth,
);
}
}
Expand Down