From c7e35540f5297962ef43de3e1d182028c236e3b8 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Mon, 13 Nov 2017 11:35:01 -0200 Subject: [PATCH] Verify if user has username on login (#64) * get /me from rest api and append to user reducer * Removed comments from login saga * user reducer logic * Jump to set username screen when user is logged without username * lint fix after merge * lint fix --- app/actions/actionsTypes.js | 1 + app/actions/login.js | 5 +++ app/containers/Routes.js | 9 +++- app/containers/routes/NavigationService.js | 23 +++++++++++ app/lib/rocketchat.js | 11 +++++ app/reducers/login.js | 5 +++ app/sagas/login.js | 48 ++++++++++------------ 7 files changed, 74 insertions(+), 28 deletions(-) create mode 100644 app/containers/routes/NavigationService.js diff --git a/app/actions/actionsTypes.js b/app/actions/actionsTypes.js index 7e937e97..fa841ad8 100644 --- a/app/actions/actionsTypes.js +++ b/app/actions/actionsTypes.js @@ -17,6 +17,7 @@ export const LOGIN = createRequestTypes('LOGIN', [ 'REGISTER_SUBMIT', 'REGISTER_REQUEST', 'REGISTER_SUCCESS', + 'REGISTER_INCOMPLETE', 'SET_USERNAME_SUBMIT', 'SET_USERNAME_REQUEST', 'SET_USERNAME_SUCCESS' diff --git a/app/actions/login.js b/app/actions/login.js index f8b12eeb..c603f42b 100644 --- a/app/actions/login.js +++ b/app/actions/login.js @@ -32,6 +32,11 @@ export function registerSuccess(credentials) { credentials }; } +export function registerIncomplete() { + return { + type: types.LOGIN.REGISTER_INCOMPLETE + }; +} export function setUsernameSubmit(credentials) { return { diff --git a/app/containers/Routes.js b/app/containers/Routes.js index 83268096..2255e302 100644 --- a/app/containers/Routes.js +++ b/app/containers/Routes.js @@ -7,6 +7,7 @@ import { appInit } from '../actions'; import AuthRoutes from './routes/AuthRoutes'; import PublicRoutes from './routes/PublicRoutes'; import Loading from '../presentation/Loading'; +import * as NavigationService from './routes/NavigationService'; @connect( state => ({ @@ -27,6 +28,10 @@ export default class Routes extends React.Component { componentWillMount() { this.props.appInit(); } + + componentDidUpdate() { + NavigationService.setNavigator(this.navigator); + } render() { const { login, app } = this.props; @@ -35,9 +40,9 @@ export default class Routes extends React.Component { } if ((login.token && !login.failure && !login.isRegistering) || app.ready) { - return (); + return ( this.navigator = nav} />); } - return (); + return ( this.navigator = nav} />); } } diff --git a/app/containers/routes/NavigationService.js b/app/containers/routes/NavigationService.js new file mode 100644 index 00000000..0be7f410 --- /dev/null +++ b/app/containers/routes/NavigationService.js @@ -0,0 +1,23 @@ +import { NavigationActions } from 'react-navigation'; + +const config = {}; + +export function setNavigator(nav) { + if (nav) { + config.navigator = nav; + } +} + +export function navigate(routeName, params) { + if (config.navigator && routeName) { + const action = NavigationActions.navigate({ routeName, params }); + config.navigator.dispatch(action); + } +} + +export function goBack() { + if (config.navigator) { + const action = NavigationActions.back({}); + config.navigator.dispatch(action); + } +} diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index 81bc55f4..60aec341 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -122,6 +122,17 @@ const RocketChat = { }); }, + me({ server, token, userId }) { + return fetch(`${ server }/api/v1/me`, { + method: 'get', + headers: { + 'Content-Type': 'application/json', + 'X-Auth-Token': token, + 'X-User-Id': userId + } + }).then(response => response.json()); + }, + register({ credentials }) { return new Promise((resolve, reject) => { Meteor.call('registerUser', credentials, (err, userId) => { diff --git a/app/reducers/login.js b/app/reducers/login.js index 4964ccba..b6bacffc 100644 --- a/app/reducers/login.js +++ b/app/reducers/login.js @@ -74,6 +74,11 @@ export default function login(state = initialState, action) { isFetching: false, isRegistering: false }; + case types.LOGIN.REGISTER_INCOMPLETE: + return { + ...state, + isRegistering: true + }; case types.FORGOT_PASSWORD.INIT: return initialState; case types.FORGOT_PASSWORD.REQUEST: diff --git a/app/sagas/login.js b/app/sagas/login.js index c16e9f1b..302b5604 100644 --- a/app/sagas/login.js +++ b/app/sagas/login.js @@ -5,6 +5,7 @@ import { loginRequest, loginSubmit, registerRequest, + registerIncomplete, loginSuccess, loginFailure, setToken, @@ -16,6 +17,7 @@ import { forgotPasswordFailure } from '../actions/login'; import RocketChat from '../lib/rocketchat'; +import * as NavigationService from '../containers/routes/NavigationService'; const TOKEN_KEY = 'reactnativemeteor_usertoken'; const getUser = state => state.login; @@ -24,6 +26,7 @@ const loginCall = args => (args.resume ? RocketChat.login(args) : RocketChat.log const registerCall = args => RocketChat.register(args); const setUsernameCall = args => RocketChat.setUsername(args); const logoutCall = args => RocketChat.logout(args); +const meCall = args => RocketChat.me(args); const forgotPasswordCall = args => RocketChat.forgotPassword(args); const getToken = function* getToken() { @@ -43,35 +46,17 @@ const getToken = function* getToken() { }; const handleLoginWhenServerChanges = function* handleLoginWhenServerChanges() { - // do { try { yield take(types.METEOR.SUCCESS); yield call(getToken); - // const { navigator } = yield select(state => state); const user = yield select(getUser); if (user.token) { yield put(loginRequest({ resume: user.token })); - // console.log('AEEEEEEEEOOOOO'); - // // wait for a response - // const { error } = yield race({ - // success: take(types.LOGIN.SUCCESS), - // error: take(types.LOGIN.FAILURE) - // }); - // console.log('AEEEEEEEEOOOOO', error); - // if (!error) { - // navigator.resetTo({ - // screen: 'Rooms' - // }); - // } } - // navigator.resetTo({ - // screen: 'Rooms' - // }); } catch (e) { console.log(e); } - // } while (true); }; const saveToken = function* saveToken() { @@ -82,8 +67,20 @@ const saveToken = function* saveToken() { const handleLoginRequest = function* handleLoginRequest({ credentials }) { try { - const response = yield call(loginCall, credentials); - yield put(loginSuccess(response)); + const server = yield select(getServer); + const user = yield call(loginCall, credentials); + + // GET /me from REST API + const me = yield call(meCall, { server, token: user.token, userId: user.id }); + + // if user has username + if (me.username) { + user.username = me.username; + } else { + yield put(registerIncomplete()); + } + + yield put(loginSuccess(user)); } catch (err) { if (err.error === 403) { yield put(logout()); @@ -98,13 +95,7 @@ const handleLoginSubmit = function* handleLoginSubmit({ credentials }) { }; const handleRegisterSubmit = function* handleRegisterSubmit({ credentials }) { - // put a login request yield put(registerRequest(credentials)); - // wait for a response - // yield race({ - // success: take(types.LOGIN.REGISTER_SUCCESS), - // error: take(types.LOGIN.FAILURE) - // }); }; const handleRegisterRequest = function* handleRegisterRequest({ credentials }) { @@ -141,6 +132,10 @@ const handleLogout = function* handleLogout() { yield call(logoutCall, { server }); }; +const handleRegisterIncomplete = function* handleRegisterIncomplete() { + yield call(NavigationService.navigate, 'Register'); +}; + const handleForgotPasswordRequest = function* handleForgotPasswordRequest({ email }) { try { yield call(forgotPasswordCall, email); @@ -158,6 +153,7 @@ const root = function* root() { yield takeLatest(types.LOGIN.REGISTER_REQUEST, handleRegisterRequest); yield takeLatest(types.LOGIN.REGISTER_SUBMIT, handleRegisterSubmit); yield takeLatest(types.LOGIN.REGISTER_SUCCESS, handleRegisterSuccess); + yield takeLatest(types.LOGIN.REGISTER_INCOMPLETE, handleRegisterIncomplete); yield takeLatest(types.LOGIN.SET_USERNAME_SUBMIT, handleSetUsernameSubmit); yield takeLatest(types.LOGIN.SET_USERNAME_REQUEST, handleSetUsernameRequest); yield takeLatest(types.LOGOUT, handleLogout);