From efc4589cc7c863f2c9d0f1dd28f02b4523c09b3c Mon Sep 17 00:00:00 2001 From: Carlos Alvarez Date: Tue, 18 Aug 2020 16:49:24 -0700 Subject: [PATCH 1/6] Re-authenticate only if we have stored credentials --- src/lib/Network.js | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/lib/Network.js b/src/lib/Network.js index 7c2ab7dc8c5f6..ae6fd247d86e6 100644 --- a/src/lib/Network.js +++ b/src/lib/Network.js @@ -200,24 +200,29 @@ function request(command, data, type = 'post') { if (!reauthenticating && responseData.jsonCode === 407 && data.doNotRetry !== true) { reauthenticating = true; return Ion.get(IONKEYS.CREDENTIALS) - .then(({login, password}) => xhr('Authenticate', { - useExpensifyLogin: false, - partnerName: CONFIG.EXPENSIFY.PARTNER_NAME, - partnerPassword: CONFIG.EXPENSIFY.PARTNER_PASSWORD, - partnerUserID: login, - partnerUserSecret: password, - twoFactorAuthCode: '' - }) - .then((response) => { - reauthenticating = false; - return setSuccessfulSignInData(response); - }) - .then(() => xhr(command, data, type)) - .catch(() => { - reauthenticating = false; - redirectToSignIn(); - return Promise.reject(); - })); + .then((credentials) => { + if (credentials && credentials.login && credentials.password) { + return xhr('Authenticate', { + useExpensifyLogin: false, + partnerName: CONFIG.EXPENSIFY.PARTNER_NAME, + partnerPassword: CONFIG.EXPENSIFY.PARTNER_PASSWORD, + partnerUserID: credentials.login, + partnerUserSecret: credentials.password, + twoFactorAuthCode: '' + }) + .then((response) => { + reauthenticating = false; + return setSuccessfulSignInData(response); + }) + .then(() => xhr(command, data, type)) + .catch(() => { + reauthenticating = false; + redirectToSignIn(); + return Promise.reject(); + }); + } + return redirectToSignIn(); + }); } return responseData; }); From 18dd5d68a6f92efe196bf4ceeb8bad7e2d7fb09d Mon Sep 17 00:00:00 2001 From: Carlos Alvarez Date: Tue, 18 Aug 2020 16:59:18 -0700 Subject: [PATCH 2/6] Simplify --- src/lib/Network.js | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/lib/Network.js b/src/lib/Network.js index ae6fd247d86e6..0c33a3e0f201f 100644 --- a/src/lib/Network.js +++ b/src/lib/Network.js @@ -201,27 +201,31 @@ function request(command, data, type = 'post') { reauthenticating = true; return Ion.get(IONKEYS.CREDENTIALS) .then((credentials) => { - if (credentials && credentials.login && credentials.password) { - return xhr('Authenticate', { - useExpensifyLogin: false, - partnerName: CONFIG.EXPENSIFY.PARTNER_NAME, - partnerPassword: CONFIG.EXPENSIFY.PARTNER_PASSWORD, - partnerUserID: credentials.login, - partnerUserSecret: credentials.password, - twoFactorAuthCode: '' - }) - .then((response) => { - reauthenticating = false; - return setSuccessfulSignInData(response); - }) - .then(() => xhr(command, data, type)) - .catch(() => { - reauthenticating = false; - redirectToSignIn(); - return Promise.reject(); - }); + // The first time we load the app we won't have credentials to re-authenticate with + // so we send the user to the signin page + if (!credentials || !credentials.login || !credentials.password) { + return redirectToSignIn(); } - return redirectToSignIn(); + + // If we have login credentials stored in Ion, we use them to re-authenticate + return xhr('Authenticate', { + useExpensifyLogin: false, + partnerName: CONFIG.EXPENSIFY.PARTNER_NAME, + partnerPassword: CONFIG.EXPENSIFY.PARTNER_PASSWORD, + partnerUserID: credentials.login, + partnerUserSecret: credentials.password, + twoFactorAuthCode: '' + }) + .then((response) => { + reauthenticating = false; + return setSuccessfulSignInData(response); + }) + .then(() => xhr(command, data, type)) + .catch(() => { + reauthenticating = false; + redirectToSignIn(); + return Promise.reject(); + }); }); } return responseData; From 9876bfc32c233469f8a1289949097ad0c01176b6 Mon Sep 17 00:00:00 2001 From: Carlos Alvarez Date: Tue, 18 Aug 2020 16:59:25 -0700 Subject: [PATCH 3/6] Account for when we don't have anything stored Specifically, when we haven't saved CURRENT_URL and FIRST_REPORT_ID in the store --- src/page/HomePage/SidebarView.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/page/HomePage/SidebarView.js b/src/page/HomePage/SidebarView.js index 788784d857bee..d68d0f89b9ead 100644 --- a/src/page/HomePage/SidebarView.js +++ b/src/page/HomePage/SidebarView.js @@ -132,8 +132,8 @@ export default WithIon({ collectionID: 'reportID', loader: () => fetchAll().then(() => { Ion.multiGet([IONKEYS.CURRENT_URL, IONKEYS.FIRST_REPORT_ID]).then((values) => { - const currentURL = values[IONKEYS.CURRENT_URL] || ''; - const firstReportID = values[IONKEYS.FIRST_REPORT_ID] || 0; + const currentURL = values && values[IONKEYS.CURRENT_URL] ? values[IONKEYS.CURRENT_URL] : ''; + const firstReportID = values && values[IONKEYS.FIRST_REPORT_ID] ? values[IONKEYS.FIRST_REPORT_ID] : 0; // If we're on the home page, then redirect to the first report ID if (currentURL === '/' && firstReportID) { From 0262c79756d0b2bb52b363bfc7da3abf8d8e3fbb Mon Sep 17 00:00:00 2001 From: Carlos Alvarez Date: Tue, 18 Aug 2020 17:14:16 -0700 Subject: [PATCH 4/6] Avoid JSON.parse(undefined) --- src/lib/Ion.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/lib/Ion.js b/src/lib/Ion.js index f64c0e7f58b67..0f84f22e3dcc5 100644 --- a/src/lib/Ion.js +++ b/src/lib/Ion.js @@ -140,11 +140,20 @@ function multiGet(keys) { // This method will transform the data into a better JSON format like: // {'@MyApp_user': 'myUserValue', '@MyApp_key': 'myKeyValue'} return AsyncStorage.multiGet(keys) - .then(arrayOfData => _.reduce(arrayOfData, (finalData, keyValuePair) => ({ - ...finalData, - [keyValuePair[0]]: JSON.parse(keyValuePair[1]), - }), {})) - .catch(err => console.error(`Unable to get item from persistent storage. Error: ${err}`, keys)); + .then(arrayOfData => _.reduce(arrayOfData, (finalData, keyValuePair) => { + // If we don't find a value in the store for the key we're looking for we return undefined + let value; + try { + value = JSON.parse(keyValuePair[1]); + } catch (e) { + value = undefined; + } + return { + ...finalData, + [keyValuePair[0]]: value, + }; + }), {}) + .catch(err => console.error(`Unable to get item from persistent storage. Error: ${err.stack}`, keys)); } /** From 1daa8d9c8abacbd4c03c4ba7645020acb415e0d1 Mon Sep 17 00:00:00 2001 From: Carlos Alvarez Date: Tue, 18 Aug 2020 17:17:26 -0700 Subject: [PATCH 5/6] Revert "Avoid JSON.parse(undefined)" This reverts commit 0262c79756d0b2bb52b363bfc7da3abf8d8e3fbb. --- src/lib/Ion.js | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/lib/Ion.js b/src/lib/Ion.js index 0f84f22e3dcc5..f64c0e7f58b67 100644 --- a/src/lib/Ion.js +++ b/src/lib/Ion.js @@ -140,20 +140,11 @@ function multiGet(keys) { // This method will transform the data into a better JSON format like: // {'@MyApp_user': 'myUserValue', '@MyApp_key': 'myKeyValue'} return AsyncStorage.multiGet(keys) - .then(arrayOfData => _.reduce(arrayOfData, (finalData, keyValuePair) => { - // If we don't find a value in the store for the key we're looking for we return undefined - let value; - try { - value = JSON.parse(keyValuePair[1]); - } catch (e) { - value = undefined; - } - return { - ...finalData, - [keyValuePair[0]]: value, - }; - }), {}) - .catch(err => console.error(`Unable to get item from persistent storage. Error: ${err.stack}`, keys)); + .then(arrayOfData => _.reduce(arrayOfData, (finalData, keyValuePair) => ({ + ...finalData, + [keyValuePair[0]]: JSON.parse(keyValuePair[1]), + }), {})) + .catch(err => console.error(`Unable to get item from persistent storage. Error: ${err}`, keys)); } /** From dc8a889fd77ee4dac2e3679e60bc60528bcd6e8e Mon Sep 17 00:00:00 2001 From: Carlos Alvarez Date: Tue, 18 Aug 2020 17:36:33 -0700 Subject: [PATCH 6/6] Revert "Account for when we don't have anything stored" This reverts commit 9876bfc32c233469f8a1289949097ad0c01176b6. --- src/page/HomePage/SidebarView.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/page/HomePage/SidebarView.js b/src/page/HomePage/SidebarView.js index d68d0f89b9ead..788784d857bee 100644 --- a/src/page/HomePage/SidebarView.js +++ b/src/page/HomePage/SidebarView.js @@ -132,8 +132,8 @@ export default WithIon({ collectionID: 'reportID', loader: () => fetchAll().then(() => { Ion.multiGet([IONKEYS.CURRENT_URL, IONKEYS.FIRST_REPORT_ID]).then((values) => { - const currentURL = values && values[IONKEYS.CURRENT_URL] ? values[IONKEYS.CURRENT_URL] : ''; - const firstReportID = values && values[IONKEYS.FIRST_REPORT_ID] ? values[IONKEYS.FIRST_REPORT_ID] : 0; + const currentURL = values[IONKEYS.CURRENT_URL] || ''; + const firstReportID = values[IONKEYS.FIRST_REPORT_ID] || 0; // If we're on the home page, then redirect to the first report ID if (currentURL === '/' && firstReportID) {