This commit is contained in:
Salakar 2017-05-25 14:56:24 +01:00
commit d175996cd1
10 changed files with 147 additions and 11 deletions

View File

@ -25,7 +25,9 @@ import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException;
import com.google.firebase.auth.GithubAuthProvider;
import com.google.firebase.auth.ProviderQueryResult;
import com.google.firebase.auth.TwitterAuthProvider;
import com.google.firebase.auth.UserInfo;
import com.google.firebase.auth.UserProfileChangeRequest;
@ -633,6 +635,40 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
}
}
/**
* fetchProvidersForEmail
*
* @param promise
*/
@ReactMethod
public void fetchProvidersForEmail(final String email, final Promise promise) {
Log.d(TAG, "fetchProvidersForEmail");
mAuth.fetchProvidersForEmail(email)
.addOnCompleteListener(new OnCompleteListener<ProviderQueryResult>() {
@Override
public void onComplete(@NonNull Task<ProviderQueryResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "fetchProvidersForEmail:onComplete:success");
List<String> providers = task.getResult().getProviders();
WritableArray array = Arguments.createArray();
if (providers != null) {
for(String provider : providers) {
array.pushString(provider);
}
}
promise.resolve(array);
} else {
Exception exception = task.getException();
Log.d(TAG, "fetchProvidersForEmail:onComplete:failure", exception);
promiseRejectAuthException(promise, exception);
}
}
});
}
/* ------------------
* INTERNAL HELPERS
* ---------------- */
@ -645,7 +681,7 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
*/
private void promiseNoUser(Promise promise, Boolean isError) {
if (isError) {
promise.reject("auth/no_current_user", "No user currently signed in.");
promise.reject("auth/no-current-user", "No user currently signed in.");
} else {
promise.resolve(null);
}
@ -675,6 +711,7 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
private void promiseRejectAuthException(Promise promise, Exception exception) {
String code = "UNKNOWN";
String message = exception.getMessage();
String invalidEmail = "The email address is badly formatted.";
try {
FirebaseAuthException authException = (FirebaseAuthException) exception;
@ -695,7 +732,7 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
message = "The supplied auth credential is malformed or has expired.";
break;
case "INVALID_EMAIL":
message = "The email address is badly formatted.";
message = invalidEmail;
break;
case "WRONG_PASSWORD":
message = "The password is invalid or the user does not have a password.";
@ -737,6 +774,11 @@ public class RNFirebaseAuth extends ReactContextBaseJavaModule {
}
}
if (code.equals("UNKNOWN") && exception instanceof FirebaseAuthInvalidCredentialsException) {
code = "INVALID_EMAIL";
message = invalidEmail;
}
code = "auth/" + code.toLowerCase().replace("error_", "").replace('_', '-');
promise.reject(code, message, exception);
}

View File

@ -433,6 +433,27 @@ RCT_EXPORT_METHOD(reauthenticate:(NSString *)provider authToken:(NSString *)auth
}
}
/**
fetchProvidersForEmail
@param NSString email
@param RCTPromiseResolveBlock resolve
@param RCTPromiseRejectBlock reject
@return
*/
RCT_EXPORT_METHOD(fetchProvidersForEmail:(NSString *)email resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject) {
[[FIRAuth auth] fetchProvidersForEmail:email completion:^(NSArray<NSString *> *_Nullable providers, NSError *_Nullable error) {
if (error) {
[self promiseRejectAuthException:reject error:error];
} else if (!providers) {
NSMutableArray *emptyResponse = [[NSMutableArray alloc] init];
resolve(emptyResponse);
} else {
resolve(providers);
}
}];
}
/**
getCredentialForProvider
@ -472,7 +493,7 @@ RCT_EXPORT_METHOD(reauthenticate:(NSString *)provider authToken:(NSString *)auth
*/
- (void) promiseNoUser:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject isError:(BOOL) isError {
if (isError) {
reject(@"auth/no_current_user", @"No user currently signed in.", nil);
reject(@"auth/no-current-user", @"No user currently signed in.", nil);
} else {
resolve([NSNull null]);
}

View File

@ -156,6 +156,14 @@ export default class Auth extends Base {
return this._interceptUserValue(FirebaseAuth.getCurrentUser());
}
/**
* Returns a list of authentication providers that can be used to sign in a given user (identified by its main email address).
* @return {Promise}
*/
fetchProvidersForEmail(email: string): Promise<Object> {
return FirebaseAuth.fetchProvidersForEmail(email);
}
/**
* Get the currently signed in user
* @return {Promise}

View File

@ -4,6 +4,7 @@ export default {
token: email,
secret: password,
provider: 'password',
providerId: 'password',
};
},
};

View File

@ -4,6 +4,7 @@ export default {
token,
secret: '',
provider: 'facebook',
providerId: 'facebook',
};
},
};

View File

@ -4,6 +4,7 @@ export default {
token,
secret: '',
provider: 'github',
providerId: 'github',
};
},
};

View File

@ -4,6 +4,7 @@ export default {
token,
secret,
provider: 'google',
providerId: 'google',
};
},
};

View File

@ -4,6 +4,7 @@ export default {
token,
secret,
provider: 'twitter',
providerId: 'twitter',
};
},
};

View File

@ -113,7 +113,7 @@ export default class User {
*
* @param credential
*/
link(credential: CredentialType) {
linkWithCredential(credential: CredentialType) {
return this._auth._interceptUserValue(FirebaseAuth.link(credential.provider, credential.token, credential.secret));
}
@ -121,11 +121,10 @@ export default class User {
* Re-authenticate a user with a third-party authentication provider
* @return {Promise} A promise resolved upon completion
*/
reauthenticate(credential: CredentialType) {
reauthenticateWithCredential(credential: CredentialType) {
return this._auth._interceptUserValue(FirebaseAuth.reauthenticate(credential.provider, credential.token, credential.secret));
}
/**
* Reload the current user
* @return {Promise}
@ -136,9 +135,19 @@ export default class User {
/**
* get the token of current user
* @deprecated Deprecated getToken in favor of getIdToken.
* @return {Promise}
*/
getToken(forceRefresh: Boolean = false): Promise<Object> {
console.warn('Deprecated firebase.User.prototype.getToken in favor of firebase.User.prototype.getIdToken.');
return FirebaseAuth.getToken(forceRefresh);
}
/**
* get the token of current user
* @return {Promise}
*/
getIdToken(forceRefresh: Boolean = false): Promise<Object> {
return FirebaseAuth.getToken(forceRefresh);
}

View File

@ -49,7 +49,7 @@ function authTests({ tryCatch, describe, it, firebase }) {
const credential = firebase.native.auth.EmailAuthProvider.credential(email, pass);
return currentUser
.link(credential)
.linkWithCredential(credential)
.then((linkedUser) => {
linkedUser.should.be.an.Object();
linkedUser.uid.should.be.a.String();
@ -84,7 +84,7 @@ function authTests({ tryCatch, describe, it, firebase }) {
const credential = firebase.native.auth.EmailAuthProvider.credential(email, pass);
return currentUser
.link(credential)
.linkWithCredential(credential)
.then(() => {
return firebase.native.auth().signOut().then(() => {
return Promise.reject(new Error('Did not error on link'));
@ -149,6 +149,7 @@ function authTests({ tryCatch, describe, it, firebase }) {
};
const failureCb = (error) => {
console.log('ERROR', error)
error.code.should.equal('auth/wrong-password');
error.message.should.equal('The password is invalid or the user does not have a password.');
return Promise.resolve();
@ -246,6 +247,56 @@ function authTests({ tryCatch, describe, it, firebase }) {
});
});
describe('Email - Providers', () => {
it('it should return password provider for an email address', () => {
return new Promise((resolve, reject) => {
const successCb = tryCatch((providers) => {
providers.should.be.a.Array();
providers.should.containEql('password');
resolve();
}, reject);
const failureCb = tryCatch(() => {
reject(new Error('Should not have an error.'));
}, reject);
return firebase.native.auth().fetchProvidersForEmail('test@test.com').then(successCb).catch(failureCb);
});
});
it('it should return an empty array for a not found email', () => {
return new Promise((resolve, reject) => {
const successCb = tryCatch((providers) => {
providers.should.be.a.Array();
providers.should.be.empty();
resolve();
}, reject);
const failureCb = tryCatch(() => {
reject(new Error('Should not have an error.'));
}, reject);
return firebase.native.auth().fetchProvidersForEmail('test@i-do-not-exist.com').then(successCb).catch(failureCb);
});
});
it('it should return an error for a bad email address', () => {
return new Promise((resolve, reject) => {
const successCb = tryCatch(() => {
reject(new Error('Should not have successfully resolved.'));
}, reject);
const failureCb = tryCatch((error) => {
error.code.should.equal('auth/invalid-email');
error.message.should.equal('The email address is badly formatted.');
resolve();
}, reject);
return firebase.native.auth().fetchProvidersForEmail('foobar').then(successCb).catch(failureCb);
});
});
});
describe('Misc', () => {
it('it should delete a user', () => {
const random = randomString(12, '#aA');
@ -264,7 +315,7 @@ function authTests({ tryCatch, describe, it, firebase }) {
return firebase.native.auth().createUserWithEmailAndPassword(email, pass).then(successCb);
});
it('it should return a token via getToken', () => {
it('it should return a token via getIdToken', () => {
const random = randomString(12, '#aA');
const email = `${random}@${random}.com`;
const pass = random;
@ -276,7 +327,7 @@ function authTests({ tryCatch, describe, it, firebase }) {
newUser.isAnonymous.should.equal(false);
newUser.providerId.should.equal('firebase');
return newUser.getToken().then((token) => {
return newUser.getIdToken().then((token) => {
token.should.be.a.String();
token.length.should.be.greaterThan(24);
return firebase.native.auth().currentUser.delete();
@ -297,7 +348,7 @@ function authTests({ tryCatch, describe, it, firebase }) {
}, reject);
const failureCb = tryCatch((error) => {
error.code.should.equal('auth/no_current_user');
error.code.should.equal('auth/no-current-user');
error.message.should.equal('No user currently signed in.');
resolve();
}, reject);