Skip to content
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

Redirect embedded apps to the provided return_to if it's a fully-formed URL #1746

Merged
merged 6 commits into from
Nov 13, 2023

Conversation

laynekoftinowmikan
Copy link
Contributor

@laynekoftinowmikan laynekoftinowmikan commented Nov 9, 2023

What this PR does

Fixes https://github.com/Shopify/shop-server/issues/65307.

We have a flow in Shop where we're able to install the Shop channel through an internal admin tool called Shop Internal. This is generally used for testing in Spin and production. In previous versions of this gem, the installation flow brought us back to Shop Internal at the end. However, now the gem assumes that embedded app installations should always get redirected to Shopify Admin. This fixes that issue by redirecting to the provided return_to for embedded apps if it's a fully-formed URL (ie. not just a path within Shopify Admin).

Reviewer's guide to testing

I tested both our internal installation flow and our regular installation flow and both are working. The internal installation flow brings us back to Shop Server, and the regular one brings us to the Admin.

Internal flow

  1. spin up shop-server
  2. In Spin, run code --add $(bundle show shopify_app) to import the shopify_app gem code
  3. Copy/paste the code changes in this PR into the gem (don't seem to be able to use git here, let me know if there's a better way to test this)
  4. In the Shopify Admin, uninstall the Shop channel
  5. In Spin, dev c and Merchant::ShopRecord.destroy_all
  6. In Shop Internal, go to the broker and select "Install the channel"
  7. Confirm you're returned to the Shop Internal GraphiQL at the end of the flow

Regular flow

  1. In the Shopify Admin, uninstall the Shop channel
  2. In Spin, dev c and Merchant::ShopRecord.destroy_all
  3. Go directly to the login screen, eg. https://shop-server.shop-server-260k.layne-koftinowmikan.us.spin.dev/merchant/login
  4. Confirm you're brought to the Shop channel in Shopify Admin at the end of the flow

Things to focus on

That this won't have any adverse effects for other apps.

Checklist

Before submitting the PR, please consider if any of the following are needed:

  • Update CHANGELOG.md if the changes would impact users
  • Update README.md, if appropriate.
  • Update any relevant pages in /docs, if necessary
  • For security fixes, the Disclosure Policy must be followed.

@@ -78,6 +78,11 @@ def redirect_to_app
end
end

def fully_formed_url?(return_to)
uri = Addressable::URI.parse(return_to)
uri.present? && uri.scheme.present? && uri.host.present?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Outlined here what the scheme and host refer to: https://github.com/sporkmonger/addressable#example-usage

@laynekoftinowmikan laynekoftinowmikan marked this pull request as ready for review November 9, 2023 17:47
@laynekoftinowmikan laynekoftinowmikan requested a review from a team as a code owner November 9, 2023 17:47
uri = Addressable::URI.parse(return_to)
uri.present? && uri.scheme.present? && uri.host.present?
end

def decoded_host
@decoded_host ||= ShopifyAPI::Auth.embedded_app_url(params[:host])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other thing this this embedded_app_url does is append the Context's API key to the path. I'm doing some research of the context of what this is needed for. It sounds like your app is fine without it but I'm curious if others would

app/controllers/shopify_app/callback_controller.rb Outdated Show resolved Hide resolved
@@ -69,7 +69,7 @@ def update_rails_cookie(api_session, cookie)
end

def redirect_to_app
if ShopifyAPI::Context.embedded?
if ShopifyAPI::Context.embedded? && !fully_formed_url?(session[:return_to])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I see what this is doing now because I have the context, it isn't super clear as to the intent of the feature. Maybe we add another return_to local override that says return_to = return_url if full_formed_url?. Something similar to line 74's return_to override.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, I've refactored a bit so it's hopefully more clear. Let me know what you think

Copy link

@rondanino rondanino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. How do we build and use it in shop-server?

@laynekoftinowmikan
Copy link
Contributor Author

@rondanino that was going to my next question, I figure that changes get batched into new releases and once that release goes out we'll bump the gem in Shop Server

@nelsonwittwer what's the release process generally like for minor changes like this?

@nelsonwittwer nelsonwittwer merged commit f9910fb into main Nov 13, 2023
@nelsonwittwer nelsonwittwer deleted the laynekm/callback_controller branch November 13, 2023 14:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants