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

Improve upgrade docs #1525

Merged
merged 1 commit into from
Oct 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions docs/Troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#### Table of contents

[Generators](#generators)
* [The `shopify_app:install` generator hangs](#the-shopifyappinstall-generator-hangs)
* [The `shopify_app:install` generator hangs](#the-shopify_appinstall-generator-hangs)

[Rails](#rails)
* [Known issues with Rails `v6.1`](#known-issues-with-rails-v61)
Expand All @@ -18,6 +18,8 @@
* [My app can't make requests to the Shopify API](#my-app-cant-make-requests-to-the-shopify-api)
* [I'm stuck in a redirect loop after OAuth](#im-stuck-in-a-redirect-loop-after-oauth)

[Debugging Tips](#debugging-tips)

## Generators

### The shopify_app:install generator hangs
Expand Down Expand Up @@ -143,9 +145,43 @@ X-Shopify-API-Request-Failure-Unauthorized: true

Then, use the [Shopify App Bridge Redirect](https://shopify.dev/tools/app-bridge/actions/navigation/redirect) action to redirect your app frontend to the app login URL if this header is set.


### I'm stuck in a redirect loop after OAuth

In previous versions of `ShopifyApp::Authenticated` controller concern, App Bridge embedded apps were able to include the `Authenticated` controller concern in the `HomeController` and other embedded controllers. This is no longer supported due to browsers blocking 3rd party cookies to increase privacy. App Bridge 3 is needed to handle all embedded sessions.

For more details on how to handle embeded sessions, refer to [the session token documentation](https://shopify.dev/apps/auth/oauth/session-tokens).

### `redirect_uri is not whitelisted`

* Ensure you have set the `HOST` environment variable to match your host's URL, e.g. `http://localhost:3000` or `https://my-host-name.trycloudflare.com`.
* Update the app's URL and whitelisted URLs in App Setup on https://partners.shopify.com

### `This app can’t load due to an issue with browser cookies`

This can be caused by an infinite redirect due to a coding error
To investigate the cause, you can add a breakpoint or logging to the `rescue` clause of `ShopifyApp::CallbackController`.

One possible cause is that for XHR requests, the `Authenticated` concern should be used, rather than `RequireKnownShop`.
See below for further details.

## Controller Concerns
### Authenticated vs RequireKnownShop
The gem heavily relies on the `current_shopify_domain` helper to contextualize a request to a given Shopify shop. This helper is set in different and conflicting ways if the request is authenticated or not.

Because of these conflicting approaches the `Authenticated` (for use in authenticated requests) and `RequireKnownShop` (for use in unauthenticated requests) controller concerns must *never* be included within the same controller.

#### Authenticated Requests
For authenticated requests, use the [`Authenticated` controller concern](https://github.com/Shopify/shopify_app/blob/main/app/controllers/concerns/shopify_app/authenticated.rb). The `current_shopify_domain` is set from the JWT for these requests.

#### Unauthenticated Requests
For unauthenticated requests, use the [`RequireKnownShop` controller concern](https://github.com/Shopify/shopify_app/blob/main/app/controllers/concerns/shopify_app/require_known_shop.rb). The `current_shopify_domain` is set from the query string parameters that are passed.

## Debugging Tips

If you do run into issues with the gem there are two useful techniques to apply: Adding log statements, and using an interactive debugger, such as `pry`.

You can temporarily add log statements or debugger calls to the `shopify_app` or `shopify-api-ruby` gems:
* You can modify a gem using [`bundle open`](https://boringrails.com/tips/bundle-open-debug-gems)
* Alternatively, you can your modify your `Gemfile` to use local locally checked out gems with the the [`path` option](https://bundler.io/man/gemfile.5.html).

Note that if you make changes to a gem, you will need to restart the app for the changes to be applied.
54 changes: 24 additions & 30 deletions docs/Upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ This file documents important changes needed to upgrade your app's Shopify App v

#### Table of contents

[General Advice](#general-advice)

[Upgrading to `v20.2.0`](#upgrading-to-v2020)

[Upgrading to `v20.1.0`](#upgrading-to-v2010)
Expand All @@ -20,7 +22,20 @@ This file documents important changes needed to upgrade your app's Shopify App v

[Upgrading from `v8.6` to `v9.0.0`](#upgrading-from-v86-to-v900)

## General Advice

Although we strive to make upgrades as smooth as possible, some effort may be required to stay up to date with the latest changes to `shopify_app`.

We strongly recommend you avoid 'monkeypatching' any existing code from `ShopifyApp`, e.g. by inheriting from `ShopifyApp` and then overriding particular methods. This can result in difficult upgrades. If your app does so, you will need to carefully check the gem's internal changes when upgrading.

If you need to upgrade by more than one major version (e.g. from v18 to v20), we recommend doing one at a time. Deploy each into production to help to detect problems earlier.

We also recommend the use of a staging site which matches your production environment as closely as possible.

If you do run into issues, we recommend looking at our [debugging tips.](https://github.com/Shopify/shopify_app/blob/main/docs/Troubleshooting.md#debugging-tips)

## Upgrading to `v20.2.0`

All custom errors defined inline within the `ShopifyApp` gem have been moved to `lib/shopify_app/errors.rb`.

- If you rescue any errors defined in this gem, you will need to rename them to match their new namespacing.
Expand All @@ -36,8 +51,9 @@ Note that the following steps are *optional* and only apply to **embedded** appl

## Upgrading to `v19.0.0`

This update moves API authentication logic from this gem to the [`shopify_api`](https://github.com/Shopify/shopify-api-ruby)
gem.
*This change introduced a major change of strategy regarding sessions.* Due to security changes with browsers, support for cookie based sessions was dropped. JWT is now the only supported method for managing sessions.

As part of that change, this update moves API authentication logic from this gem to the [`shopify_api`](https://github.com/Shopify/shopify-api-ruby) gem.

### High-level process

Expand All @@ -53,13 +69,16 @@ gem.

### Specific cases

#### Shopify user id in session
#### Shopify user ID in session

Previously, we set the entire app user object in the `session` object.
As of v19, since we no longer save the app user to the session (but only the shopify user id), we now store it as `session[:shopify_user_id]`. Please make sure to update any references to that object.

#### Webhook Jobs

It is assumed that you have an ActiveJob implementation configured for `perform_later`, e.g. Sidekiq.
Copy link
Contributor Author

@andyw8 andyw8 Oct 5, 2022

Choose a reason for hiding this comment

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

(some apps may have been using a plain Ruby class with the perform method).

Ensure your jobs inherit from `ApplicationJob` or `ActiveJob::Base`.

Add a new `handle` method to existing webhook jobs to go through the updated `shopify_api` gem.

```ruby
Expand Down Expand Up @@ -95,40 +114,15 @@ Shopify API session, or `nil` if no such session is available.

#### Setting up `ShopifyAPI::Context`

The `shopify_app` initializer must configure the `ShopifyAPI::Context`. The Rails generator will
generate a block in the `shopify_app` initializer. To do so manually, ensure the following is
part of the `after_initialize` block in `shopify_app.rb`.

```ruby
Copy link
Contributor Author

@andyw8 andyw8 Oct 5, 2022

Choose a reason for hiding this comment

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

(For easier long-term maintenance of this document, I think it's better to refer to the template rather than duplicating its contents here.)

Rails.application.config.after_initialize do
if ShopifyApp.configuration.api_key.present? && ShopifyApp.configuration.secret.present?
ShopifyAPI::Context.setup(
api_key: ShopifyApp.configuration.api_key,
api_secret_key: ShopifyApp.configuration.secret,
old_api_secret_key: ShopifyApp.configuration.old_secret,
api_version: ShopifyApp.configuration.api_version,
host_name: URI(ENV.fetch('HOST', '')).host || '',
scope: ShopifyApp.configuration.scope,
is_private: !ENV.fetch('SHOPIFY_APP_PRIVATE_SHOP', '').empty?,
is_embedded: ShopifyApp.configuration.embedded_app,
session_storage: ShopifyApp::SessionRepository,
logger: Rails.logger,
private_shop: ENV.fetch('SHOPIFY_APP_PRIVATE_SHOP', nil),
user_agent_prefix: "ShopifyApp/#{ShopifyApp::VERSION}"
)

ShopifyApp::WebhooksManager.add_registrations
end
end
```
The `shopify_app` initializer must configure the `ShopifyAPI::Context`. The Rails generator will generate a block in the `shopify_app` initializer. To do so manually, you can refer to `after_initialize` block in the [template]((https://github.com/Shopify/shopify_app/blob/main/lib/generators/shopify_app/install/templates/shopify_app.rb.tt).

## Upgrading to `v18.1.2`

Version 18.1.2 replaces the deprecated EASDK redirect with an App Bridge 2 redirect when attempting to break out of an iframe. This happens when an app is installed, requires new access scopes, or re-authentication because the login session is expired.

## Upgrading to `v17.2.0`

### Different SameSite cookie attribute behaviour
### Different SameSite cookie attribute behavior

To support Rails `v6.1`, the [`SameSiteCookieMiddleware`](/lib/shopify_app/middleware/same_site_cookie_middleware.rb) was updated to configure cookies to `SameSite=None` if the app is embedded. Before this release, cookies were configured to `SameSite=None` only if this attribute had not previously been set before.

Expand Down