[auth][js][android] remove EE based phone auth implementation

This commit is contained in:
Salakar 2017-08-23 23:19:11 +01:00
parent 48c74ff1d7
commit 93079c2f01
8 changed files with 6493 additions and 10227 deletions

View File

@ -6,7 +6,6 @@ import android.support.annotation.NonNull;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -26,14 +25,11 @@ import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseException;
import com.google.firebase.auth.ActionCodeResult;
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.PhoneAuthCredential;
import com.google.firebase.auth.PhoneAuthProvider;
import com.google.firebase.auth.ProviderQueryResult;
import com.google.firebase.auth.TwitterAuthProvider;
import com.google.firebase.auth.UserInfo;
@ -565,127 +561,6 @@ class RNFirebaseAuth extends ReactContextBaseJavaModule {
}
}
/**
* signInWithPhoneNumber
*
* @param appName
* @param phoneNumber
* @param phoneAuthRequestKey
*/
@ReactMethod
public void signInWithPhoneNumber(final String appName, final String phoneNumber, final String phoneAuthRequestKey) {
Log.d(TAG, "signInWithPhoneNumber");
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp);
// Reset the verification Id
mVerificationId = null;
PhoneAuthProvider.getInstance(firebaseAuth).verifyPhoneNumber(phoneNumber, 60, TimeUnit.SECONDS,
mReactContext.getCurrentActivity(), new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onVerificationCompleted(final PhoneAuthCredential phoneAuthCredential) {
// User has been automatically verified, log them in
firebaseAuth.signInWithCredential(phoneAuthCredential)
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult authResult) {
Log.d(TAG, "signInWithPhoneNumber:autoVerified:success");
WritableMap event = Arguments.createMap();
WritableMap user = firebaseUserToMap(authResult.getUser());
event.putMap("user", user);
event.putString("type", "user");
event.putString("appName", appName);
event.putString("smsCode", phoneAuthCredential.getSmsCode());
event.putString("phoneAuthRequestKey", phoneAuthRequestKey);
Utils.sendEvent(mReactContext, "phone_auth_event", event);
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
Log.e(TAG, "signInWithPhoneNumber:autoVerified:failure", exception);
WritableMap event = Arguments.createMap();
WritableMap error = getJSError(exception);
event.putMap("error", error);
event.putString("type", "error");
event.putString("appName", appName);
event.putString("phoneAuthRequestKey", phoneAuthRequestKey);
Utils.sendEvent(mReactContext, "phone_auth_event", event);
}
});
}
@Override
public void onVerificationFailed(FirebaseException e) {
Log.d(TAG, "signInWithPhoneNumber:verification:failed");
WritableMap event = Arguments.createMap();
WritableMap error = getJSError(e);
event.putMap("error", error);
event.putString("type", "error");
event.putString("appName", appName);
event.putString("phoneAuthRequestKey", phoneAuthRequestKey);
Utils.sendEvent(mReactContext, "phone_auth_event", event);
}
@Override
public void onCodeSent(String verificationId, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
WritableMap verificationMap = Arguments.createMap();
verificationMap.putString("appName", appName);
verificationMap.putString("type", "confirm");
verificationMap.putString("verificationId", verificationId);
verificationMap.putString("phoneAuthRequestKey", phoneAuthRequestKey);
Utils.sendEvent(mReactContext, "phone_auth_event", verificationMap);
}
@Override
public void onCodeAutoRetrievalTimeOut(String verificationId) {
super.onCodeAutoRetrievalTimeOut(verificationId);
// Purposefully not doing anything with this at the moment
}
});
}
@ReactMethod
public void _confirmVerificationCode(final String appName, final String phoneAuthRequestKey, String verificationId, String verificationCode, final Promise promise) {
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(firebaseApp);
// Log.d(TAG, "_confirmVerificationCode:verificationId: " + verificationId);
// Log.d(TAG, "_confirmVerificationCode:verificationCode: " + verificationCode);
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, verificationCode);
firebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "_confirmVerificationCode:signInWithCredential:onComplete:success");
WritableMap event = Arguments.createMap();
WritableMap user = firebaseUserToMap(task.getResult().getUser());
event.putMap("user", user);
event.putString("type", "user");
event.putString("appName", appName);
event.putString("phoneAuthRequestKey", phoneAuthRequestKey);
Utils.sendEvent(mReactContext, "phone_auth_event", event);
promiseWithUser(task.getResult().getUser(), promise);
} else {
Exception exception = task.getException();
Log.e(TAG, "_confirmVerificationCode:signInWithCredential:onComplete:failure", exception);
WritableMap event = Arguments.createMap();
WritableMap error = getJSError(exception);
event.putMap("error", error);
event.putString("type", "error");
event.putString("appName", appName);
event.putString("phoneAuthRequestKey", phoneAuthRequestKey);
Utils.sendEvent(mReactContext, "phone_auth_event", event);
promiseRejectAuthException(promise, exception);
}
}
});
}
/**
* confirmPasswordReset
*

View File

@ -1,37 +0,0 @@
/**
* @url https://firebase.google.com/docs/reference/js/firebase.User
*/
export default class ConfirmationResult {
_auth: Object;
_verificationId: string;
_phoneAuthRequestKey: string;
/**
*
* @param auth
* @param verificationId The phone number authentication operation's verification ID.
* @param phoneAuthRequestKey
*/
constructor(auth: Object, verificationId: string, phoneAuthRequestKey: string) {
this._auth = auth;
this._verificationId = verificationId;
this._phoneAuthRequestKey = phoneAuthRequestKey;
}
/**
*
* @param verificationCode
* @return {*}
*/
confirm(verificationCode: string): Promise<Object> {
return this._auth._native._confirmVerificationCode(
this._phoneAuthRequestKey,
this._verificationId,
verificationCode,
);
}
get verificationId(): String | null {
return _verificationId;
}
}

View File

@ -1,13 +1,9 @@
// @flow
import User from './user';
import INTERNALS from './../../internals';
import ModuleBase from './../../utils/ModuleBase';
import { nativeToJSError, generatePushID, isFunction } from './../../utils';
import ConfirmationResult from './ConfirmationResult';
// providers
import EmailAuthProvider from './providers/Email';
import PhoneAuthProvider from './providers/Phone';
import GoogleAuthProvider from './providers/Google';
import GithubAuthProvider from './providers/Github';
import TwitterAuthProvider from './providers/Twitter';
@ -33,48 +29,9 @@ export default class Auth extends ModuleBase {
this._onAuthStateChanged.bind(this),
);
this.addListener(
// sub to phone auth native event - this can
// be either a code sent confirmation result
// event, a successful signIn event or an
// error event
this._getAppEventName('phone_auth_event'),
this._onPhoneAuthEvent.bind(this),
);
this._native.addAuthStateListener();
}
/**
* Handles an incoming phone auth event and emits to the internal once listeners.
* @param event
* @private
*/
_onPhoneAuthEvent(event) {
const { type, phoneAuthRequestKey } = event;
if (type === 'confirm') {
return this.emit(
`phone:auth:${phoneAuthRequestKey}:confirm`,
new ConfirmationResult(this, event.verificationId, phoneAuthRequestKey),
);
}
if (type === 'user') {
return this.emit(
`phone:auth:${phoneAuthRequestKey}:user`,
this._onAuthStateChanged({ authenticated: true, user: event.user }, false),
);
}
if (type === 'error') {
const { code, message } = event.error;
return this.emit(`phone:auth:${phoneAuthRequestKey}:error`, nativeToJSError(code, message));
}
throw new Error('Internal RNFirebase Error: Invalid phone auth event received.');
}
/**
* Internal auth changed listener
* @param auth
@ -189,53 +146,6 @@ export default class Auth extends ModuleBase {
);
}
/**
*
* @param phoneNumber
* @return Object
*/
signInWithPhoneNumber(phoneNumber: string): Promise<Object> {
const phoneAuthRequestKey = generatePushID();
return {
onCodeSent: (cb) => {
if (!isFunction(cb)) {
throw new Error(INTERNALS.STRINGS.ERROR_MISSING_CB('onCodeSent'));
}
this.once(`phone:auth:${phoneAuthRequestKey}:confirm`, cb);
return new Promise((resolve, reject) => {
// start auth flow
this._native.signInWithPhoneNumber(
phoneNumber,
phoneAuthRequestKey,
);
let hadEvent = false;
const successEvent = `phone:auth:${phoneAuthRequestKey}:user`;
const errorEvent = `phone:auth:${phoneAuthRequestKey}:error`;
this.once(successEvent, (user) => {
if (!hadEvent) {
hadEvent = true;
this.removeListener(errorEvent, reject);
resolve(user);
}
});
this.once(errorEvent, (error) => {
if (!hadEvent) {
hadEvent = true;
this.removeListener(successEvent, resolve);
reject(error);
}
});
});
},
};
}
/**
* Send reset password instructions via email
* @param {string} email The email to send password reset instructions

View File

@ -1,10 +0,0 @@
export default {
credential(verificationId, code) {
return {
token: verificationId,
secret: code,
provider: 'phone',
providerId: 'phone',
};
},
};

View File

@ -23,11 +23,8 @@ const NATIVE_MODULE_EVENTS = {
],
Auth: [
'onAuthStateChanged',
'phone_auth_event',
],
Database: [
// 'database_on_event',
// 'database_cancel_event',
'database_transaction_event',
// 'database_server_offset', // TODO
],

16344
tests/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,108 +0,0 @@
import React, { Component } from 'react';
import { View, Button, Text, TextInput, Image } from 'react-native';
import fb from './firebase';
const firebase = fb.native;
if (firebase.auth().currentUser) firebase.auth().signOut();
const successImageUri = 'https://cdn.pixabay.com/photo/2015/06/09/16/12/icon-803718_1280.png';
export default class PhoneAuthTest extends Component {
constructor(props) {
super(props);
this.state = {
user: null,
message: '',
codeInput: '',
phoneNumber: '+447',
confirmResult: null,
};
}
signIn = () => {
const { phoneNumber } = this.state;
this.setState({ message: 'Sending code ...' });
firebase.auth()
.signInWithPhoneNumber(phoneNumber)
.onCodeSent(confirmResult => this.setState({ confirmResult, message: 'Code has been sent!' }))
.then(user => this.setState({ user: user.toJSON() }))
.catch(console.error);
};
confirmCode = () => {
const { codeInput, confirmResult } = this.state;
if (confirmResult && codeInput.length) {
confirmResult.confirm(codeInput)
.then(() => this.setState({ message: 'Code Confirmed!' }))
.catch(error => this.setState({ message: `Code Confirm Error: ${error.message}` }));
}
};
render() {
const { message, user, codeInput, confirmResult, phoneNumber } = this.state;
return (
<View style={{ flex: 1 }}>
{!user && !confirmResult ? (
<View style={{ padding: 25 }}>
<Text>Enter phone number:</Text>
<TextInput
autoFocus
style={{ height: 40, marginTop: 15, marginBottom: 15 }}
onChangeText={value => this.setState({ phoneNumber: value })}
placeholder={'Phone number ... '}
value={phoneNumber}
/>
<Button title="Sign In" color="green" onPress={this.signIn} />
</View>
) : null}
{message.length ? (
<Text style={{ padding: 5, backgroundColor: '#000', color: '#fff' }}>{message}</Text>) : null}
{!user && confirmResult ? (
<View style={{ marginTop: 25, padding: 25 }}>
<Text>Enter verification code below:</Text>
<TextInput
autoFocus
style={{ height: 40, marginTop: 15, marginBottom: 15 }}
onChangeText={value => this.setState({ codeInput: value })}
placeholder={'Code ... '}
value={codeInput}
/>
<Button title="Confirm Code" color="#841584" onPress={this.confirmCode} />
</View>
) : null}
{ user ? (
<View
style={{
padding: 15,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#77dd77',
flex: 1,
}}
>
<Image source={{ uri: successImageUri }} style={{ width: 100, height: 100, marginBottom: 25 }} />
<Text style={{ fontSize: 25 }}>Signed In!</Text>
<Text>{JSON.stringify(user)}</Text>
<Button
title="Logout"
color="#841584"
onPress={() => {
firebase.auth().signOut().then(() => {
this.setState({
user: null,
message: '',
codeInput: '',
phoneNumber: '+44',
confirmResult: null,
});
});
}}
/>
</View>
) : null}
</View>
);
}
}

View File

@ -1,6 +1,7 @@
import { Platform } from 'react-native';
import firebase from 'firebase';
import RNfirebase from './../firebase/firebase';
import { Platform } from 'react-native';
import DatabaseContents from './tests/support/DatabaseContents';