From 64ff7bc178e42c14f193a77114b2ca939e15f7c8 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Tue, 8 Sep 2020 18:08:58 -0400
Subject: [PATCH 1/6] feat(VerifyEmailScreen): Add link to resend verification
email.
---
lib/components/user/user-account-screen.js | 5 +-
lib/components/user/verify-email-screen.js | 83 ++++++++++++++++------
2 files changed, 64 insertions(+), 24 deletions(-)
diff --git a/lib/components/user/user-account-screen.js b/lib/components/user/user-account-screen.js
index 0c77fa85d..27090adaf 100644
--- a/lib/components/user/user-account-screen.js
+++ b/lib/components/user/user-account-screen.js
@@ -88,14 +88,14 @@ class UserAccountScreen extends Component {
// TODO: Update title bar during componentDidMount.
render () {
- const { auth, loggedInUser } = this.props
+ const { auth, config, loggedInUser } = this.props
const { userData } = this.state
let formContents
if (isNewUser(loggedInUser)) {
if (!auth.user.email_verified) {
// Check and prompt for email verification first to avoid extra user wait.
- formContents =
- Please check your email inbox and follow the link in the message - to verify your email address before finishing your account setup. -
-- Once you're verified, click the button below to continue. -
- - -+ Once you're verified, click the button below to continue. +
+Please check your email inbox and follow the link in the message to verify your email address before finishing your account setup. -
Once you're verified, click the button below to continue.
From b9b0ba35ab20c854ca8c40b9229c79ab2b85f092 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 11 Nov 2020 13:33:19 -0500 Subject: [PATCH 5/6] refactor(actions/user): Add separate action to fetch auth0 token. --- lib/actions/user.js | 98 +++++++++---------- .../user/with-logged-in-user-support.js | 25 ++++- 2 files changed, 70 insertions(+), 53 deletions(-) diff --git a/lib/actions/user.js b/lib/actions/user.js index 10a4ef981..2b33449fd 100644 --- a/lib/actions/user.js +++ b/lib/actions/user.js @@ -49,65 +49,63 @@ function getMiddlewareVariables (state) { } } +/** + * Attempts to fetch the auth0 access token and store it in the redux state, under state.user. + * @param auth0 The auth0 context used to obtain the access token for subsequent middleware fetches. + */ +export function fetchAuth0Token (auth0) { + return async function (dispatch, getState) { + try { + const accessToken = await auth0.getAccessTokenSilently() + + dispatch(setCurrentUser({ accessToken })) + } catch (error) { + // TODO: improve UI if there is an errror. + alert('Error obtaining an authorization token.') + } + } +} + /** * Attempts to fetch user preferences (or set initial values if the user is being created) * into the redux state, under state.user. - * @param auth0 If provided, the auth0 login object used to initially obtain the auth0 access token - * for subsequent middleware fetches (and also to initialize new users from auth0 email and id). - * If absent, state.user.accessToken will be used for fetches. + * @param auth0 If provided, the auth0 login object used to initialize the default user object (with email and auth0 id). */ export function fetchOrInitializeUser (auth0) { return async function (dispatch, getState) { const { accessToken, apiBaseUrl, apiKey } = getMiddlewareVariables(getState()) const requestUrl = `${apiBaseUrl}${API_OTPUSER_PATH}/fromtoken` - // Get the Auth0 access token. If one is in state.user, use it, - // otherwise if auth0 is provided, fetch it. - let token - if (accessToken) { - token = accessToken - } else if (auth0) { - try { - token = await auth0.getAccessTokenSilently() - } catch (error) { - // TODO: improve UI if there is an errror. - alert('Error obtaining an authorization token.') - } - } - - // Once accessToken is available, proceed to fetch or initialize loggedInUser. - if (token) { - const { data: user, status } = await secureFetch(requestUrl, token, apiKey) - - // Beware! On AWS API gateway, if a user is not found in the middleware - // (e.g. they just created their Auth0 password but have not completed the account setup form yet), - // the call above will return, for example: - // { - // status: 'success', - // data: { - // "result": "ERR", - // "message": "No user with id=000000 found.", - // "code": 404, - // "detail": null - // } - // } - // - // The same call to a middleware instance that is not behind an API gateway - // will return: - // { - // status: 'error', - // message: 'Error get-ing user...' - // } - // TODO: Improve AWS response. - - const isNewAccount = status === 'error' || (user && user.result === 'ERR') - const userData = isNewAccount ? createNewUser(auth0.user) : user - dispatch(setCurrentUser({ accessToken: token, user: userData })) - - // Also load monitored trips for existing users. - if (!isNewAccount) { - dispatch(fetchUserMonitoredTrips()) - } + const { data: user, status } = await secureFetch(requestUrl, accessToken, apiKey) + + // Beware! On AWS API gateway, if a user is not found in the middleware + // (e.g. they just created their Auth0 password but have not completed the account setup form yet), + // the call above will return, for example: + // { + // status: 'success', + // data: { + // "result": "ERR", + // "message": "No user with id=000000 found.", + // "code": 404, + // "detail": null + // } + // } + // + // The same call to a middleware instance that is not behind an API gateway + // will return: + // { + // status: 'error', + // message: 'Error get-ing user...' + // } + // TODO: Improve AWS response. + + const isNewAccount = status === 'error' || (user && user.result === 'ERR') + const userData = isNewAccount ? createNewUser(auth0.user) : user + dispatch(setCurrentUser({ accessToken, user: userData })) + + // Also load monitored trips for existing users. + if (!isNewAccount) { + dispatch(fetchUserMonitoredTrips()) } } } diff --git a/lib/components/user/with-logged-in-user-support.js b/lib/components/user/with-logged-in-user-support.js index 951c3f743..17b1c5bcf 100644 --- a/lib/components/user/with-logged-in-user-support.js +++ b/lib/components/user/with-logged-in-user-support.js @@ -49,10 +49,26 @@ class UserLoaderScreen extends Component { return auth0 && auth0.isAuthenticated && !loggedInUser } + /** + * Determines whether an auth0 token should be fetched. + * @returns true if the logged-in user has passed Auth0 authentication + * and state.user.accessToken has not been set; false otherwise. + */ + acccessTokenIsUnfetched = () => { + const { accessToken, auth0 } = this.props + return auth0 && auth0.isAuthenticated && !accessToken + } + componentDidUpdate () { - const { auth0, fetchOrInitializeUser } = this.props + const { + auth0, + fetchAuth0Token, + fetchOrInitializeUser + } = this.props - if (this.loggedInUserIsUnfetched()) { + if (this.acccessTokenIsUnfetched()) { + fetchAuth0Token(auth0) + } else if (this.loggedInUserIsUnfetched()) { fetchOrInitializeUser(auth0) } } @@ -77,12 +93,15 @@ class UserLoaderScreen extends Component { // connect to the redux store const mapStateToProps = (state, ownProps) => { + const { accessToken, loggedInUser } = state.user return { - loggedInUser: state.user.loggedInUser + accessToken, + loggedInUser } } const mapDispatchToProps = { + fetchAuth0Token: userActions.fetchAuth0Token, fetchOrInitializeUser: userActions.fetchOrInitializeUser } From 77a1a2c0f422a76331c75fbaea09579946a51692 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 13 Nov 2020 18:53:48 -0500 Subject: [PATCH 6/6] refactor(actions/user): Address PR comments Remove auth0 as arg for resendVerificationEmail; change arg of fetchOrInitializeUser to auth0User; cleanup. --- lib/actions/user.js | 11 +++++------ lib/components/user/user-account-screen.js | 8 ++------ lib/components/user/verify-email-screen.js | 8 ++------ lib/components/user/with-logged-in-user-support.js | 2 +- 4 files changed, 10 insertions(+), 19 deletions(-) diff --git a/lib/actions/user.js b/lib/actions/user.js index 2b33449fd..af53e96d0 100644 --- a/lib/actions/user.js +++ b/lib/actions/user.js @@ -69,9 +69,9 @@ export function fetchAuth0Token (auth0) { /** * Attempts to fetch user preferences (or set initial values if the user is being created) * into the redux state, under state.user. - * @param auth0 If provided, the auth0 login object used to initialize the default user object (with email and auth0 id). + * @param auth0User If provided, the auth0.user object used to initialize the default user object (with email and auth0 id). */ -export function fetchOrInitializeUser (auth0) { +export function fetchOrInitializeUser (auth0User) { return async function (dispatch, getState) { const { accessToken, apiBaseUrl, apiKey } = getMiddlewareVariables(getState()) const requestUrl = `${apiBaseUrl}${API_OTPUSER_PATH}/fromtoken` @@ -100,7 +100,7 @@ export function fetchOrInitializeUser (auth0) { // TODO: Improve AWS response. const isNewAccount = status === 'error' || (user && user.result === 'ERR') - const userData = isNewAccount ? createNewUser(auth0.user) : user + const userData = isNewAccount ? createNewUser(auth0User) : user dispatch(setCurrentUser({ accessToken, user: userData })) // Also load monitored trips for existing users. @@ -153,10 +153,9 @@ export function createOrUpdateUser (userData, silentOnSuccess = false) { /** * Requests the verification email for the new user to be resent. */ -export function resendVerificationEmail (auth0) { +export function resendVerificationEmail () { return async function (dispatch, getState) { - const { apiBaseUrl, apiKey } = getMiddlewareVariables(getState()) - const accessToken = await auth0.getAccessTokenSilently() + const { accessToken, apiBaseUrl, apiKey } = getMiddlewareVariables(getState()) // TODO: add any throttling. const requestUrl = `${apiBaseUrl}${API_OTPUSER_PATH}/verification-email` diff --git a/lib/components/user/user-account-screen.js b/lib/components/user/user-account-screen.js index 81721259e..0143e8508 100644 --- a/lib/components/user/user-account-screen.js +++ b/lib/components/user/user-account-screen.js @@ -74,11 +74,7 @@ class UserAccountScreen extends Component { // Capture whether user is a new user at this stage, and retain that value as long as this screen is active. // Reminder: When a new user progresses through the account steps, // isNewUser(loggedInUser) will change to false as the database gets updated. - isNewUser: isNewUser(props.loggedInUser), - - // Last number and last time we requested a code for (to avoid repeat SMS and not waste SMS quota). - lastPhoneNumberRequested: null, - lastPhoneRequestTime: null + isNewUser: isNewUser(props.loggedInUser) } } @@ -166,7 +162,7 @@ class UserAccountScreen extends Component { if (this.state.isNewUser) { if (!auth0.user.email_verified) { // Check and prompt for email verification first to avoid extra user wait. - formContents =