Skip to content

Commit

Permalink
[firebase_auth] AuthCredential for email and link (flutter#1458)
Browse files Browse the repository at this point in the history
* Add `getCredentialWithLink`
  • Loading branch information
creativecreatorormaybenot authored and collinjackson committed Apr 8, 2019
1 parent 6af4818 commit 5d5116c
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 5 deletions.
4 changes: 4 additions & 0 deletions packages/firebase_auth/CHANGELOG.md
@@ -1,3 +1,7 @@
## 0.8.4+1

* Adds credential for email authentication with link.

## 0.8.4

* Adds support for email link authentication.
Expand Down
Expand Up @@ -416,8 +416,13 @@ private AuthCredential getCredential(Map<String, Object> arguments) {
case EmailAuthProvider.PROVIDER_ID:
{
String email = data.get("email");
String password = data.get("password");
credential = EmailAuthProvider.getCredential(email, password);
if (data.containsKey("password")) {
String password = data.get("password");
credential = EmailAuthProvider.getCredential(email, password);
} else {
String link = data.get("link");
credential = EmailAuthProvider.getCredentialWithLink(email, link);
}
break;
}
case GoogleAuthProvider.PROVIDER_ID:
Expand Down
9 changes: 7 additions & 2 deletions packages/firebase_auth/ios/Classes/FirebaseAuthPlugin.m
Expand Up @@ -353,8 +353,13 @@ - (FIRAuthCredential *)getCredential:(NSDictionary *)arguments {
FIRAuthCredential *credential;
if ([FIREmailAuthProviderID isEqualToString:provider]) {
NSString *email = data[@"email"];
NSString *password = data[@"password"];
credential = [FIREmailAuthProvider credentialWithEmail:email password:password];
if ([data objectForKey:@"password"]) {
NSString *password = data[@"password"];
credential = [FIREmailAuthProvider credentialWithEmail:email password:password];
} else {
NSString *link = data[@"link"];
credential = [FIREmailAuthProvider credentialWithEmail:email link:link];
}
} else if ([FIRGoogleAuthProviderID isEqualToString:provider]) {
NSString *idToken = data[@"idToken"];
NSString *accessToken = data[@"accessToken"];
Expand Down
Expand Up @@ -16,4 +16,14 @@ class EmailAuthProvider {
'password': password,
});
}

static AuthCredential getCredentialWithLink({
String email,
String link,
}) {
return AuthCredential._(providerId, <String, String>{
'email': email,
'link': link,
});
}
}
4 changes: 4 additions & 0 deletions packages/firebase_auth/lib/src/firebase_auth.dart
Expand Up @@ -268,6 +268,8 @@ class FirebaseAuth {
/// Resolve this case by calling [fetchSignInMethodsForEmail] and then asking the user to sign in using one of them.
/// This error will only be thrown if the "One account per email address" setting is enabled in the Firebase console (recommended).
/// • `ERROR_OPERATION_NOT_ALLOWED` - Indicates that Google accounts are not enabled.
/// • `ERROR_INVALID_ACTION_CODE` - If the action code in the link is malformed, expired, or has already been used.
/// This can only occur when using [EmailAuthProvider.getCredentialWithLink] to obtain the credential.
Future<FirebaseUser> signInWithCredential(AuthCredential credential) async {
assert(credential != null);
// TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
Expand Down Expand Up @@ -428,6 +430,8 @@ class FirebaseAuth {
/// • `ERROR_REQUIRES_RECENT_LOGIN` - If the user's last sign-in time does not meet the security threshold. Use reauthenticate methods to resolve.
/// • `ERROR_PROVIDER_ALREADY_LINKED` - If the current user already has an account of this type linked.
/// • `ERROR_OPERATION_NOT_ALLOWED` - Indicates that this type of account is not enabled.
/// • `ERROR_INVALID_ACTION_CODE` - If the action code in the link is malformed, expired, or has already been used.
/// This can only occur when using [EmailAuthProvider.getCredentialWithLink] to obtain the credential.
Future<FirebaseUser> linkWithCredential(AuthCredential credential) async {
assert(credential != null);
// TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
Expand Down
2 changes: 1 addition & 1 deletion packages/firebase_auth/pubspec.yaml
Expand Up @@ -4,7 +4,7 @@ description: Flutter plugin for Firebase Auth, enabling Android and iOS
like Google, Facebook and Twitter.
author: Flutter Team <flutter-dev@googlegroups.com>
homepage: https://github.com/flutter/plugins/tree/master/packages/firebase_auth
version: "0.8.4"
version: "0.8.4+1"

flutter:
plugin:
Expand Down
76 changes: 76 additions & 0 deletions packages/firebase_auth/test/firebase_auth_test.dart
Expand Up @@ -213,6 +213,82 @@ void main() {
);
});

test('EmailAuthProvider (withLink) linkWithCredential', () async {
final AuthCredential credential = EmailAuthProvider.getCredentialWithLink(
email: 'test@example.com',
link: '<Url with domain from your Firebase project>',
);
final FirebaseUser user = await auth.linkWithCredential(credential);
verifyUser(user);
expect(
log,
<Matcher>[
isMethodCall(
'linkWithCredential',
arguments: <String, dynamic>{
'app': auth.app.name,
'provider': 'password',
'data': <String, String>{
'email': 'test@example.com',
'link': '<Url with domain from your Firebase project>',
},
},
),
],
);
});

test('EmailAuthProvider (withLink) signInWithCredential', () async {
final AuthCredential credential = EmailAuthProvider.getCredentialWithLink(
email: 'test@example.com',
link: '<Url with domain from your Firebase project>',
);
final FirebaseUser user = await auth.signInWithCredential(credential);
verifyUser(user);
expect(
log,
<Matcher>[
isMethodCall(
'signInWithCredential',
arguments: <String, dynamic>{
'app': auth.app.name,
'provider': 'password',
'data': <String, String>{
'email': 'test@example.com',
'link': '<Url with domain from your Firebase project>',
},
},
),
],
);
});

test('EmailAuthProvider (withLink) reauthenticateWithCredential', () async {
final FirebaseUser user = await auth.currentUser();
log.clear();
final AuthCredential credential = EmailAuthProvider.getCredentialWithLink(
email: 'test@example.com',
link: '<Url with domain from your Firebase project>',
);
await user.reauthenticateWithCredential(credential);
expect(
log,
<Matcher>[
isMethodCall(
'reauthenticateWithCredential',
arguments: <String, dynamic>{
'app': auth.app.name,
'provider': 'password',
'data': <String, String>{
'email': 'test@example.com',
'link': '<Url with domain from your Firebase project>',
}
},
),
],
);
});

test('TwitterAuthProvider linkWithCredential', () async {
final AuthCredential credential = TwitterAuthProvider.getCredential(
authToken: kMockIdToken,
Expand Down

0 comments on commit 5d5116c

Please sign in to comment.