Skip to content

Opening resource picker results in empty picker and refresh #8

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

Closed
limoniapps opened this issue Sep 6, 2020 · 17 comments
Closed

Opening resource picker results in empty picker and refresh #8

limoniapps opened this issue Sep 6, 2020 · 17 comments
Labels
bug Something isn't working

Comments

@limoniapps
Copy link

limoniapps commented Sep 6, 2020

Describe the bug

Opening a resource picker in an embedded app results in an empty resource picker followed by a refresh of the iFrame.
This happens the first time the picker is displayed. After the refresh the problem does not reoccur.

To Reproduce

Create a resource picker using ResourcePicker.create():
Call picker.dispatch(ResourcePicker.Action.OPEN);

To reproduce the problem from a live app, install Discount Ninja on a development store (free) and follow these instructions:
https://www.loom.com/share/d263246df8ac40c78097e944adaaac1d

This is the line that is executed just before the bug happens:
appbridge issue

Expected behaviour

The resource picker should display the list of products / collections (not an empty list).
Opening the resource picker should never result in the iFrame being refreshed / reloaded.

Packages and versions

List the relevant packages you’re using, and their versions. For example:

  • @shopify/app-bridge @ 1.27.2

Platform

  • OS: 10.0.19041.450
  • Browser: I'm using FireFox 80.0.1 and Google Chrome 85.0.4183.83 on a Windows 10 machine. However, this bug was reproduced by many merchants on different browsers, both on Windows and on Mac.

Context

The code we use to create a resource picker and issue the command to open it looks as follows:
image

@limoniapps limoniapps added the bug Something isn't working label Sep 6, 2020
@limoniapps limoniapps changed the title Opening resource picker in Firefox results in empty picker and refresh Opening resource picker results in empty picker and refresh Sep 7, 2020
@limoniapps
Copy link
Author

Hi there, kindly asking for an update on this bug.
Many thanks in advance!

@henrytao-me
Copy link
Member

Hi @bartcoppens

I have tested ResourcePicker in Incognito using different app as well as your app, it works just fine. I saw your recorded video, it works fine after auth the 2nd time. Does it still happen after that? Do you have to do anything (ex: clear cookies) to reproduce it again?

@limoniapps
Copy link
Author

Hi @henrytao-me ,

Thanks for your reply.

We have multiple reports every week from customers who are running into this.
I have not been able to record an instance where this happens multiple consecutive times.

We usually recommend they use a different browser as this seems to happen most frequently in FireFox.
One customer told us this happens to them consecutive times on different browsers. That is to say, it failed on FireFox, they tried again on the same browser and on other browsers and it continued to fail.
While testing and recording the videos this happened to me on FireFox multiple times (but not all times) without clearing cookies in between. It also happened to me on Chrome.

What code in the ResourcePicker could potentially cause the entire iFrame to reload? How can we protect against this happening?

@iainmcampbell
Copy link

Hi Bart,

I’m able to reproduce this consistently with Discount Ninja, using Firefox 80. I don't clear cookies, just open a new tab. However, I can’t reproduce it in an isolated test case app.

We’ll look deeper into this. Firefox has been doing increasingly aggressive blocking around cookies and iframes, but I haven't seen it do this before.

One thing you may want to consider for the future is implementing our new session token auth system in your app. It's currently in public beta: https://shopify.dev/tutorials/authenticate-your-app-using-session-tokens. It's definitely not trivial to implement, but it completely replaces the Oauth flow for your embedded app with a new system that doesn't use cookies or redirects.

@limoniapps
Copy link
Author

@iainmcampbell Thanks for your feedback, and good to hear you can reproduce this issue.

Side-note: I have also noticed Firefox is more strict in its application of Content-Security-Policy.
Perhaps this could be related? Specifically, we're seeing an issue with the Content-Security-Policy (frame-src) disallowing an export of a file (on FireFox only). I have no indication the resource picker issue is related at this moment. FYI: here's a video that describes the Content-Security-Policy issue: https://www.loom.com/share/2dfbc3abbe9e4a41bb77e454649704ba

We are aware of the new session token auth system and we'll definitely implement it.
We have removed all cookies (we used one for auth as well) from our app a while ago in favor of a token-based approach.
Do you think there may be a link between auth and this resource picker issue somehow?

@iainmcampbell
Copy link

Yeah, Firefox is very strict with CSP and blocks all kinds of stuff from iframes now. Safari can be very problematic too, although usage numbers for it are a lot lower. Still investigating; I'm not an expert on CSP so I’ve pulled in a team with more knowledge.

If you can find the method call that triggers that frame-src CSP error in the library you're using, please open a new issue with that info. At first glance, it looks like the library is trying to navigate the iframe to a blob:// url, which isn’t permitted by Shopify Admin’s frame-src.

Do you think there may be a link between auth and this resource picker issue somehow?

I don't think so. just wanted to mention it as a good idea. but you're actually ahead of the curve, already using your own token-based system 👌

@limoniapps
Copy link
Author

I'll open a separate issue for the frame-src one.
Which github repository should I post that issue to?

@iainmcampbell
Copy link

this one is fine

@hannachen
Copy link

👋 Hi @bartcoppens, I'm continuing to investigate this issue. I was able to get to the same point as Iain, but unable to fully understand what's happening or reproduce in isolation as there appears to be a lot going on behind the scenes. I suspect that this might have something to do with auth. A GraphQL call was rejected due to CSRF between Shopify Admin and the GraphQL endpoint, even though the CSRF value itself is correct. Which makes me think that the session sent along the request is missing or incorrect. Would it be possible to shed some light on how your own token-based system works? I don't think it's the direct cause of the issue, but it would be helpful to understand what's going on. Although the app itself doesn't use cookies, some parts of Shopify Admin may still require it.

@limoniapps
Copy link
Author

limoniapps commented Oct 6, 2020

Hi @hannachen, Our token-based authentication system consists of a token that is retrieved from an identity server when the app is accessed. The token is then attached to all subsequent Ajax requests as a header. This is done as follows:

$.ajaxSetup({ headers: { 'X-LimoniApps-AccessToken': viewModel.User.AccessToken() } }); 

@hannachen
Copy link

Thanks for the insight @bartcoppens, that sounds just like how the new token system for apps inside Shopify Admin works. In your case, would it be correct to say that this is strictly for calls going between your app's front-end and back-end?

@limoniapps
Copy link
Author

limoniapps commented Oct 7, 2020 via email

@limoniapps
Copy link
Author

Hi @hannachen, have you been able to get to the bottom of this?

@hannachen
Copy link

Hi @bartcoppens, apologies for the delayed response. Unfortunately, we haven't had much luck last week 😞 Iain looked into this from the infrastructure side of things, but couldn't find the smoking gun there. I'm continuing with the investigation this week.

@iainmcampbell
Copy link

Quick update - we've isolated the issue and are working towards a solution. It's a problem with Shopify infrastructure, not the embedded app.

@hannachen
Copy link

hannachen commented Nov 20, 2020

Hi @bartcoppens, I just noticed a pattern with apps encountering this issue. This seems to happen when the auth URL is set as the App's URL in the partner's dashboard. For example: /auth/login that initializes an oauth flow, or if you're using shopify-koa-auth, the /shopify path. Is it possible to update your app's App URL in the partner's dashboard to point to your app's landing page, and then initialize an oauth flow only when required?

Update:

More specifically, when these 302 redirects for oauth happen within the iframe on app page load, it somehow invalidates your current session in the admin page for Firefox. The highlighted network call should be on window.top rather than a subdocument:
Screen Shot 2020-11-26 at 7 22 25 PM

Perhaps this doc can be helpful to you: https://shopify.dev/tools/embedded-app-sdk/oauth

@kris-tremblay
Copy link

Closing this as #35 continues it. If you are still experiencing this issue and believe this closed in error, please feel free to re-open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants