-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use app environment to determine olddot URL and update staging env #14944
Conversation
@rushatgabhane @Gonals One of you needs to copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
asked @s77rt to review this |
Should I assign @s77rt to the issue as C+ as well as for the review? |
@rushatgabhane Sorry, but I have not been asked for that 😅 Perhaps you mis-tagged? |
Yeah, it seems we're doing a similar thing and IMO we should pack related functionality to ApiUtils (or UrlUtils) instead, so that URLs are retrieved/managed from one place instead of be scatter through Environment and other places I want to make a few notes on the code as well (will post a review in a bit) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a few notes
Additionally I think we should rename ApiUtils
from my PR to UrlUtils
and handle API urls and Old Dot URLs there
.env.staging
Outdated
NEW_EXPENSIFY_URL=https://staging.new.expensify.com/ | ||
SECURE_EXPENSIFY_URL=https://secure.expensify.com/ | ||
EXPENSIFY_URL=https://www.expensify.com/ | ||
EXPENSIFY_URL=https://staging.expensify.com/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can simplify .env.{name}
configs by moving the URLs out of them
- Native uses
.env.production
to build the production as well as the staging app - We have a API toggle that tries to toggle between the URL set here (
EXPENSIFY_URL
) and the staging URL. So if we setEXPENSIFY_URL
tohttps://staging.expensify.com/
this would stop working - current logic expectsEXPENSIFY_URL
to be the prod url (e.g. trace howURL_API_ROOT
and how it's used insrc/libs/HttpUtils.js
I propose to declare all the URLs in one place, like you already do in src/CONST.js
Then use environment information to select the correct underlying API, like I try to do in: #15178
This way we also reduce copy pasted code across .env files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can simplify .env.{name} configs by moving the URLs out of them
I propose to declare all the URLs in one place, like you already do in src/CONST.js
This way we also reduce copy pasted code across .env files
Yes, I like this idea. Let's do it. Just for visibility we can post this in slack.
So if we set EXPENSIFY_URL to https://staging.expensify.com/ this would stop working - current logic expects EXPENSIFY_URL to be the prod url (e.g. trace how URL_API_ROOT and how it's used in src/libs/HttpUtils.js
Sorry, I didn't get this. Could you please explain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On Staging, there's a Settings -> Preferences -> Test Preferences menu, where you can toggle between the STAGING and PROD APIs, and this depends on EXPENSIFY_URL
(from .env.staging) to point to the PROD api
See how the code works here
Lines 110 to 114 in 6971b98
let apiRoot = shouldUseSecure ? CONFIG.EXPENSIFY.SECURE_EXPENSIFY_URL : CONFIG.EXPENSIFY.URL_API_ROOT; | |
if (shouldUseStagingServer(stagingServerToggleState)) { | |
apiRoot = shouldUseSecure ? CONFIG.EXPENSIFY.STAGING_SECURE_EXPENSIFY_URL : CONFIG.EXPENSIFY.STAGING_EXPENSIFY_URL; | |
} |
URL_API_ROOT
is resolved from EXPENSIFY_URL
With the change you propose the code would evaluate to something like this:
HttpUtil on Web Staging
let apiRoot = 'https://staging.expensify.com/';
if (shouldUseStagingServer(stagingServerToggleState)) {
apiRoot = 'https://staging.expensify.com/';
}
Right now the code works correctly because EXPENSIFY_URL
is https://www.expensify.com/
so we have this
HttpUtil on Web Staging
let apiRoot = 'https://www.expensify.com/';
if (shouldUseStagingServer(stagingServerToggleState)) {
apiRoot = 'https://staging.expensify.com/';
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah got it! Thanks for explanation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking more about this. Looks like the two features -
a). Redirecting to appropriate olddot app and
b). Making API calls from app to appropriate domain should behave in different ways.
For a). the redirection from newdot to olddot should occur to corresponding environment. i.e. staging to staging, prod to prod and dev to dev.
Whereas in b). the API calls should be made to staging server if "user staging server" setting is toggled on, else should be made to production server.
So, I have reverted the change in .env.staging
file that was breaking this behavior and is unrelated to this PR. Thanks for catching it. I am +1 to move all this URL logic to a lib and remove them from env files, but I think it should be done in a different PR. We can discuss that and make a new PR to cleanup the logic.
src/CONST.js
Outdated
@@ -279,6 +279,9 @@ const CONST = { | |||
CFPB_PREPAID_URL: 'https://cfpb.gov/prepaid', | |||
STAGING_NEW_EXPENSIFY_URL: 'https://staging.new.expensify.com', | |||
NEWHELP_URL: 'https://help.expensify.com', | |||
DEV_EXPENSIFY_URL: 'https://www.expensify.com.dev', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC DEV_EXPENSIFY_URL
is the same as PROD
This address doesn't work: https://www.expensify.com.dev
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to have a local VM for this to work so this works only for internal developers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, dev is different from prod. It links to internal engineer's VM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me the name DEV_EXPENSIFY_URL
is confusing, because in dev we use the PROD url
If this is meant only as a reference to OLD DOT, perhaps it should be listed as DEV_OLD_DOT_URL
Since this won't work for external contributors, perhaps there should be a comment about it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe rename this to INTERNAL_DEV_EXPENSIFY_URL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's update it to Internal as contributors dev use Prod URL. 👍
src/libs/actions/Link.js
Outdated
return `${CONFIG.EXPENSIFY.EXPENSIFY_URL}${url}${hasHashParams || hasURLParams ? '&' : '?'}${params}`; | ||
return Environment.getOldDotEnvironmentURL() | ||
.then((environmentURL) => { | ||
const oldDotDomain = Url.addTrailingForwardSlash(environmentURL || CONFIG.EXPENSIFY.EXPENSIFY_URL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Is it possible for
environmentURL
to benull | undefined
here? Why? - Is it OK to fallback to the production address? If yes, why not make
getOldDotEnvironmentURL()
have the fallback
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible for environmentURL to be null | undefined here? Why?
Usually not. We can remove it. I added just for a safety. I see promise is always resolved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If for some reason getOldDotEnvironmentURL
doesn't work as expected, the fallback here would hide the bug instead of point it out
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, I can't think of a case where it would fail. I am going to remove it.
src/libs/Environment/Environment.js
Outdated
/** | ||
* Get the corresponding oldDot URL based on the environment we are in | ||
* | ||
* @returns {Promise} | ||
*/ | ||
function getOldDotEnvironmentURL() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes!
if the API toggle is set to production?
I guess this is when "Use staging server" is toggled off
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, looking into the above problem, we should clarify this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if the API toggle is set to production?
I guess this is when "Use staging server" is toggled off
Correct
Do we know if this should depend on the staging api toggle (see Preferences / Settings / Test Settings)
Wait, looking into the above problem, we should clarify this.
I'm not sure either, can you ask on the issue related to the current PR, or open a slack thread about it
src/libs/Environment/Environment.js
Outdated
return new Promise((resolve) => { | ||
getEnvironment() | ||
.then(environment => resolve(OLDDOT_ENVIRONMENT_URLS[environment])); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrapping with new Promise((resolve => )
is unnecessary - getEnvironment
already returns a promise you can just do this:
return getEnvironment()
.then(environment => OLDDOT_ENVIRONMENT_URLS[environment]);
src/libs/Environment/Environment.js
Outdated
/** | ||
* Get the corresponding oldDot URL based on the environment we are in | ||
* | ||
* @returns {Promise} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* @returns {Promise} | |
* @returns {Promise<String>} |
Returns a Promise that resolves to a string
@MonilBhavsar Bumping this one, are we waiting on some discussion to conclude? |
Sorry, for some delay, I have addressed reviews. I think we should discuss to cleanup the URL logic and get rid of different and confusing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me now but gotta ask @rushatgabhane or some C+ for doing the checklist
Adding @s77rt to go though the checklist and testing steps |
The bridge works fine on dev for me |
* @returns {Promise<string>} | ||
*/ | ||
function getOldDotEnvironmentURL() { | ||
return getEnvironment() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using getEnvironment
will break olddot urls for those who don't use .env
file. The olddot url will fallback to the dev url which is not accessible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But how one can not have .env file. I think you meant contributors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, external contributors are setup so that they don't need an .env
file, even if they have one, they won't be able to access https://www.expensify.com.dev
(this value comes directly from CONST and not from .env)
Is it OK if this functionality doesn't work for external contributors, when they are using the DEV build?
Since external contributors are using the PROD API (In DEV via proxy), perhaps this link should point to https://www.expensify.com for external contributors during DEV
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a low priority bug, it's only at DEV time, if we can fix this with the least work it would be great otherwise we can just point this on the README file so contributors can overwrite the getOldDotEnvironmentURL
for testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it,
So technically this doesn't sound like a bug.
As @s77rt, We can ask contributors to make it work by overriding the URL in CONST or updating getOldDotEnvironmentURL()
Not sure, if we should add it to README
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can post in slack and give a heads up to contributors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah README is an overkill for such minor detail that contributors may not even have to deal with. Let's do nothing for now, if we get reports on this we may consider adding it to README then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good! Thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Posting this on Slack seems as a good idea, let's do it.
I can't really modify the - .then(environment => OLDDOT_ENVIRONMENT_URLS[environment]);
+ .then(environment => OLDDOT_ENVIRONMENT_URLS["production"]); |
Reviewer Checklist
Screenshots/VideosWeb
Mobile Web - Chrome
Mobile Web - Safari
Desktop
iOS
Android
|
Overall looking good just need to address the raised concern here #14944 (comment). I was only able to test case 1. Case 2 I didn't get the 2FA prompt although it's disabled and case 3 seems internal, right? |
@s77rt I replied to that comment.
It can be tested externally. I updated the steps to build the staging app and point to staging API. |
For case 2: Kooha-2023-03-09-11-54-24.mp4For case 3: Kooha-2023-03-09-12-10-41.mp4 |
Ah, yes case 2 needs to be internal to get that account in VERIFYING state and see 2FA prompt |
I think that is expected behavior. We discussed and decided that "Use staging server" switch should have no effect on redirection. |
@MonilBhavsar Great, thanks for the confirmation. Can you let me know what are the next steps now? |
Thanks! Let's merge it then 🚀 |
@MonilBhavsar We didn't get a final decision on this one #14944 (comment) |
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
Ah sorry, I missed that. Commented in the thread, but looks like no action will be required |
🚀 Deployed to staging by https://github.com/MonilBhavsar in version: 1.2.82-0 🚀
|
🚀 Deployed to production by https://github.com/Julesssss in version: 1.2.82-4 🚀
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
// If the URL contains # or ?, we can assume they don't need to have the `?` token to start listing url parameters. | ||
return `${oldDotDomain}${url}${hasHashParams || hasURLParams ? '&' : '?'}${params}`; | ||
}); | ||
} | ||
|
||
if (isNetworkOffline) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MonilBhavsar A bit late, but don't we need to make changes here? Linking.openURL
expects a string not a promise.
buildOldDotURL().then((oldDotUrl) => {
Linking.openURL(oldDotUrl);
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We missed it. It was fixed here #15923
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh too late then. Sorry about that
cc @AndrewGable
Details
Fixed Issues
$ #14820
PROPOSAL: https://expensify.slack.com/archives/C03TQ48KC/p1675664867491769
Tests
Use case 1
Use case 2
Have 2FA disabled on olddot.
Now, updated .env file and added
ENVIRONMENT=staging
Tested both use cases above, ensured it redirects to staging olddot URL
Similarly, updated .env file and added
ENVIRONMENT=production
Tested both use cases above, ensured it redirects to production olddot URL
For mobile native, updated
getEnvironment()
insrc/libs/Environment/getEnvironment/index.native.js
to return early and simulate staging envfunction getEnvironment() { return new Promise((resolve) => { // If we've already set the environment, use the current value + return resolve(CONST.ENVIRONMENT.STAGING); if (environment) {
Use case 3 - building Staging app
Note:
(For internal engineer) For testing on mobile web, update
DEV_EXPENSIFY_URL
in CONST.js to your ngrok URLVerify that no errors appear in the JS console
Offline tests
QA Steps
Use case 1
Use case 2
Have 2FA disabled on olddot.
PR Author Checklist
### Fixed Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)src/languages/*
files and using the translation methodWaiting for Copy
label for a copy review on the original GH to get the correct copy.STYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)/** comment above it */
this
properly so there are no scoping issues (i.e. foronClick={this.submit}
the methodthis.submit
should be bound tothis
in the constructor)this
are necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);
ifthis.submit
is never passed to a component event handler likeonClick
)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)ScrollView
component to make it scrollable when more elements are added to the page.Screenshots/Videos
Web
Screen.Recording.2023-02-15.at.6.02.06.PM.mov
Mobile Web - Chrome
Screen.Recording.2023-02-15.at.7.22.28.PM.mov
Mobile Web - Safari
Screen.Recording.2023-02-15.at.7.06.05.PM.mov
Desktop
Screen.Recording.2023-02-15.at.6.24.41.PM.mov
iOS
Screen.Recording.2023-02-15.at.7.11.15.PM.mov
Android
Screen.Recording.2023-02-16.at.12.54.36.AM.mov