/* global alert */ import { reduxForm } from 'redux-form'; import { compose } from 'redux'; import { AccessToken } from 'react-native-fbsdk'; import { AsyncStorage } from 'react-native'; import { graphql, gql, withApollo } from 'react-apollo'; import axios from 'axios'; import { withState } from 'recompose'; import LoginForm from '../../components/LoginForm'; const AUTH0_URL = 'https://rafa93br.auth0.com/oauth/access_token'; const AUTH0_CLIENT_ID = 'Bdte7rvlXysilkTWYhmv5sTCvSAJ2zzx'; /** * Form validation */ const validate = values => null; const signinUserMutation = gql` mutation($email:String!, $password: String!) { signinUser(input: { email: { email: $email, password: $password, }, clientMutationId: "123", }){ token viewer { user { id email picture name } } } } `; const createUserWithAuth0Mutation = gql` mutation createUser($name: String, $picture: String, $idToken: String!) { createUser(input: { name: $name, picture: $picture, authProvider: { auth0: { idToken: $idToken, }, }, clientMutationId: "123", }) { user { id name picture } clientMutationId } }`; const getFacebookInfo = accessToken => axios.get('https://graph.facebook.com/v2.9/me', { params: { access_token: accessToken, fields: 'picture.type(large){url,width,height,is_silhouette},email,name,id', }, }); const getAuth0Info = (url, clientId, accessToken) => axios.post(url, { client_id: clientId, access_token: accessToken, connection: 'facebook', scope: 'openid', }); const updateLocalStore = (proxy, mutationResult) => { if (mutationResult && mutationResult.data && mutationResult.data.signinUser && mutationResult.data.signinUser.viewer && mutationResult.data.signinUser.viewer.user) { const query = gql` query { viewer { user { id email } } } `; proxy.writeQuery({ query, data: mutationResult.data.signinUser, }); } }; export default compose( /** * Get access to client object to call client.resetStore */ withApollo, /** * State */ withState('loading', 'setLoading', false), /** * Auth0 Authentication */ graphql(createUserWithAuth0Mutation, ({ props: ({ ownProps: { client, setLoading }, mutate }) => ({ loginWithFacebook: async (error, result) => { if (error) { alert(`login has error: ${result.error}`); return; } if (result.isCancelled) { alert('login is cancelled.'); return; } setLoading(true); try { const accessTokenData = await AccessToken.getCurrentAccessToken(); const accessToken = accessTokenData.accessToken.toString(); const auth0Response = await getAuth0Info(AUTH0_URL, AUTH0_CLIENT_ID, accessToken); const idToken = auth0Response.data.id_token; const fbResponse = await getFacebookInfo(accessToken); const picture = fbResponse.data.picture.data.url; const name = fbResponse.data.name; const email = fbResponse.data.email; // TODO: contact email AsyncStorage.setItem('token', idToken); try { await mutate({ variables: { name, picture, idToken, }, }); } catch (err) { console.log(err); } } catch (err) { setLoading(false); alert(err.toString()); } finally { client.resetStore(); } }, }), })), /** * E-mail Authentication */ graphql(signinUserMutation, { props: ({ ownProps: { setLoading }, mutate }) => ({ loginWithEmail: async ({ email, password }) => { setLoading(true); try { /** * Sign in with given email and password */ const response = await mutate({ variables: { email, password, }, /** * On success, update the local Apollo store to update the UI and draw MainNavigation */ update: updateLocalStore, }); /** * Write obtained token to local STORAGE */ const token = response.data.signinUser.token; if (token) { AsyncStorage.setItem('token', token); } else { throw new Error('No token on response'); } } catch (err) { setLoading(false); alert(err.toString()); } }, }), }), /** * Form */ reduxForm({ form: 'login', validate, }), )(LoginForm);