-
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
[HOLD for payment 2023-02-08] [$1000] Backend - Attachment links capture the environment they are from #14227
Comments
Triggered auto assignment to @bfitzexpensify ( |
Job added to Upwork: https://www.upwork.com/jobs/~01911d83399c4bca37 |
Current assignee @bfitzexpensify is eligible for the External assigner, not assigning anyone new. |
Triggered auto assignment to Contributor-plus team member for initial proposal review - @mananjadhav ( |
Triggered auto assignment to @mountiny ( |
This happens when you upload the attachment on |
Can you point where this is happening? I think the HTML is formed on the backend If the <img src="/chat-attachments/{path}" /> |
ProposalExclude the origin (the protocol and the domain name) for chat attachment links Instead of saving an html containing More Infoexcluding the origin from When I'm on
While if I view the same from
Wherever the HTML is generated I think we should skip hardcoding the origin from the source as explained above Here's more info on how and why that would work: https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_is_a_URL#absolute_urls_vs._relative_urls
|
Asking in Slack for clarification https://expensify.slack.com/archives/C049HHMV9SM/p1673539365623209?thread_ts=1673289214.225929&cid=C049HHMV9SM |
I think it's ok to have same url for both staging and production as we are already sharing user data between staging and production. And if from backend we remove base url from html it will not work for Android and iOS. we have to explicitly set base url. |
This is inconsistent behavior - if it should be possible to load |
That means we have to send the picture both to |
We don't need to send to both, if staging can access attachments from I think attachments are stored in the same place and can be accessed with different urls, like I've pointed out here: https://expensify.slack.com/archives/C049HHMV9SM/p1673541181055489?thread_ts=1673289214.225929&cid=C049HHMV9SM You can open the sam attachment by changing |
For more context, we're trying to change the way we load attachments and start to use an authentication header When we are on So an alternative might be to configure CORS and allow requests from new.staging to www.expensify and the various combinations:
And keep in mind to update this if in the future attachments can be saved under I think it would be simpler to save the attachment and excluding the origin and allow to load it from all these domains |
After further investigation I found logic inside App that expects attachment URLs to be coming from App/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.js Lines 38 to 45 in 81855c2
So it seems the intended way to render user attachments (that were uploaded to Expensify) it so load them from Of course Traced the original change to this commit: bcca418 There seems to be 3 ways to solve this 1. Handle multiple expensify domains and rewrite the source(No backend changes - handle more than one origins on the client side) /**
* Update the image URL so images can be accessed depending on the config environment
*
* @param {String} urlString
* @returns {*|String}
*/
function mapSource(urlString) {
const url = new URL(urlString);
if (/expensify/i.test(url.origin)) {
return `${Config.EXPENSIFY.URL_API_ROOT}${url.pathname.slice(1)}`;
}
return urlString;
}
const previewSource = mapSource(htmlAttribs.src);
const source = mapSource(isAttachment
? htmlAttribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE]
: htmlAttribs.src); 2. Always save attachments to
|
Discovered a related problem regarding PDF document previews If a PDF was uploaded on staging and later viewed on prod, clicking on the attachment would result in an Error New.Expensify.-.Google.Chrome.2023-01-16.16-19-38.mp4Clicking the [Download] button would also print the same error, but it would open the link in a new window (it should just download the file instead of opening a window) |
@mountiny I don't think I can do anything about it in the scope of the current ticket (needs backend update, can't be fixed with client side changes) |
Yeah I think this might be better to abstract into its own issue. Would you be bale to write down exactly what we need to allow in the servers to avoid the CORS issues? I could try to get someone from infra team involved to help with this. If you post it here as and issue body, I can create the new issue and take it from there for clarity |
@mountiny we want to disable the |
@mountiny
SummaryWe are removing the auth token from the URL part of an attachment/image and instead placing it in a HTTP header called As a consequence (for adding this header) browsers start to make preflight (OPTIONS method) requests The preflight requests are being made because the API url (we request the image from) is from a different origin Right now the OPTIONS request, seems unexpected and the API redirects with a response to an error page and we get the following error Web:
Desktop:
What can we doI think this needs to be planned internally Perhaps the simplest thing would be to update the backend to handle cross origin request coming from these origins
Typically servers support a CORS configuration that can specify to allow and properly respond to request (including preflight) from these origin Alternatively we can avoid CORS altogether if the API is resolved from the same origin where the app is hosted Perhaps more alternative exist and someone can propose something better |
Created a new issue here, keeping this open for payment to @mananjadhav |
Hey @mountiny I noticed something else while inspecting actual staging & prod environments
App/src/libs/tryResolveUrlFromApiRoot.js Lines 22 to 24 in 72a2950
So attachment requests are always made against
The I saw this in Line 3 in 8bc6f52
But then I've asked myself "if URL_API_ROOT is not staging.expensify.com, how come the staging app is making COMMAND requests against The answer is here: Lines 112 to 114 in 7c53f31
I'm not sure what the reason for this comment Lines 11 to 12 in 7c53f31
Why should desktop and web default to staging? IMO they should default to whatever .env.staging says should be the API url All that said, we see that resolving attachments from But if we do make the following a fact
We'd need to place the same I'm not a fan of this, because we already missed it once - it's not obvious unless someone points out that I think this should be redesigned in such a way so that we import |
This means we would like web staging and web desktop to point to staging APIs by default, the toggle in settings can change it to production if we want to yes. I am also not sure if we should actively be fixing this now as it worked like this for a while :D I am wondering though why the .env.staging has non-staging url defined, not sure. @kidroca Could we use the |
These staging/ production things are super annoying especially since native works a bit differently with them too |
Hmm, I didn't understand the comment like that Only after, seeing your comment and tracing the code I see that this is meant as the default value for the toggle if Onyx doesn't have any value for it at the moment And not meaning that by default web/desktop should be using staging api My question though is more about, what's the problem with the other platforms - why can't we simple use CONFIG as the default value: Instead of this: const shouldDefaultToStaging = _.contains([CONST.PLATFORM.WEB, CONST.PLATFORM.DESKTOP], getPlatform()); Have this: const defaultStagingServerToggleState = CONFIG.IS_IN_STAGING;
Inspecting the code, I see the toggle We could apply a workaround and use IMO instead of imperative checks testing for certain conditions, the logic used here (and other URL dealing places) should be setup in a declarative way where it just says const apiRoot = getApiRoot(request); Where This also solves another problem (at least for me), The flag value is probably based on the command or something like that, this can be made more transparent if the conditions for a secure URL are declared in the same place e.g. use secure API for a list of command names I think we should discuss this on Slack and agree whether we should
I also would like to either continue in a new ticket or increase the scope/payment for the current one |
Because native apps are only build once using the staging config, then after QA is done, the staging build is pushed to production, but there is no new compilation occurring. Hence for native the Config on production is still staging so that is why we need a different approach for those.
Yeah I am not sure straight from top of my head which commands use it in NewDot its possible we are deprecating this too and we are moving the secure commands to normal API, it is a relict and it will be deprecated down the line I believe.
Would you start that discussion? I think we would like to make sure that if the staging toggle is turned to staging we should resolve the attachments form there too. Declarative way makes sense to me, this part of the code is not super clear because of the platform dependency.
We can create a new ticket after the discussion and after we decide what is needed, does that work for you? |
@bfitzexpensify would you be able to also pay out @kidroca for this job? |
@bfitzexpensify Bumping this one! |
Created a new ticket for the issue mentioned here |
@mountiny Saw the new ticket |
Solution:
|
@spreadmycode thanks for the proposal, can you check issues which have Help Wanted label though, there you can be assigned to work on them, this one is being closed. I think @bfitzexpensify has paid out what was needed here so closing |
If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!
Action Performed:
Expected Result:
all attachment URLs to be resolved relative to current environment
E.g. when I’m on staging.new I expect all attachments to be resolved from https://staging.new.expensify.com/chat-attachments/…
Or when Im on prod I expect all attachments to be resolved from https://new.expensify.com/chat-attachments/…
Actual Result:
some attachment urls are resolved from staging.expensify.com others from new.expensify.com
Workaround:
unknown
Platforms:
Which of our officially supported platforms is this issue occurring on?
Version Number: 1.2.52-4
Reproducible in staging?: y
Reproducible in production?: y
If this was caught during regression testing, add the test name, ID and link from TestRail:
Email or phone of affected tester (no customers):
Logs: https://stackoverflow.com/c/expensify/questions/4856
Notes/Photos/Videos:
Expensify/Expensify Issue URL:
Issue reported by: @kidroca
Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1673289214225929
View all open jobs on GitHub
Upwork Automation - Do Not Edit
The text was updated successfully, but these errors were encountered: