shopify_app 13.0.0 → 14.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.github/PULL_REQUEST_TEMPLATE.md +6 -0
  3. data/.github/workflows/rubocop.yml +28 -0
  4. data/.rubocop.yml +13 -6
  5. data/.travis.yml +3 -3
  6. data/CHANGELOG.md +51 -0
  7. data/Gemfile +5 -0
  8. data/README.md +79 -41
  9. data/Rakefile +1 -0
  10. data/SECURITY.md +59 -0
  11. data/app/controllers/concerns/shopify_app/authenticated.rb +1 -0
  12. data/app/controllers/concerns/shopify_app/require_known_shop.rb +39 -0
  13. data/app/controllers/shopify_app/authenticated_controller.rb +1 -0
  14. data/app/controllers/shopify_app/callback_controller.rb +41 -10
  15. data/app/controllers/shopify_app/extension_verification_controller.rb +2 -7
  16. data/app/controllers/shopify_app/sessions_controller.rb +9 -6
  17. data/app/controllers/shopify_app/webhooks_controller.rb +6 -5
  18. data/config/locales/fi.yml +1 -1
  19. data/config/locales/nl.yml +7 -7
  20. data/config/routes.rb +1 -0
  21. data/docs/Quickstart.md +7 -17
  22. data/docs/Releasing.md +1 -0
  23. data/lib/generators/shopify_app/add_after_authenticate_job/add_after_authenticate_job_generator.rb +5 -3
  24. data/lib/generators/shopify_app/add_after_authenticate_job/templates/after_authenticate_job.rb +1 -0
  25. data/lib/generators/shopify_app/add_marketing_activity_extension/add_marketing_activity_extension_generator.rb +2 -1
  26. data/lib/generators/shopify_app/add_marketing_activity_extension/templates/marketing_activities_controller.rb +4 -4
  27. data/lib/generators/shopify_app/add_webhook/add_webhook_generator.rb +5 -4
  28. data/lib/generators/shopify_app/add_webhook/templates/{webhook_job.rb → webhook_job.rb.tt} +5 -0
  29. data/lib/generators/shopify_app/app_proxy_controller/app_proxy_controller_generator.rb +4 -3
  30. data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_controller.rb +3 -3
  31. data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_route.rb +10 -9
  32. data/lib/generators/shopify_app/authenticated_controller/authenticated_controller_generator.rb +1 -1
  33. data/lib/generators/shopify_app/controllers/controllers_generator.rb +1 -0
  34. data/lib/generators/shopify_app/home_controller/home_controller_generator.rb +22 -3
  35. data/lib/generators/shopify_app/home_controller/templates/index.html.erb +67 -17
  36. data/lib/generators/shopify_app/home_controller/templates/unauthenticated_home_controller.rb +10 -0
  37. data/lib/generators/shopify_app/install/install_generator.rb +10 -9
  38. data/lib/generators/shopify_app/install/templates/embedded_app.html.erb +1 -1
  39. data/lib/generators/shopify_app/install/templates/flash_messages.js +0 -2
  40. data/lib/generators/shopify_app/install/templates/omniauth.rb +2 -1
  41. data/lib/generators/shopify_app/install/templates/{shopify_app.rb → shopify_app.rb.tt} +2 -1
  42. data/lib/generators/shopify_app/install/templates/user_agent.rb +2 -1
  43. data/lib/generators/shopify_app/products_controller/products_controller_generator.rb +19 -0
  44. data/lib/generators/shopify_app/products_controller/templates/products_controller.rb +8 -0
  45. data/lib/generators/shopify_app/routes/routes_generator.rb +1 -0
  46. data/lib/generators/shopify_app/routes/templates/routes.rb +10 -9
  47. data/lib/generators/shopify_app/shop_model/shop_model_generator.rb +12 -7
  48. data/lib/generators/shopify_app/shop_model/templates/shop.rb +1 -0
  49. data/lib/generators/shopify_app/shopify_app_generator.rb +4 -3
  50. data/lib/generators/shopify_app/user_model/templates/user.rb +1 -0
  51. data/lib/generators/shopify_app/user_model/user_model_generator.rb +12 -7
  52. data/lib/generators/shopify_app/views/views_generator.rb +1 -0
  53. data/lib/shopify_app/configuration.rb +15 -8
  54. data/lib/shopify_app/controller_concerns/app_proxy_verification.rb +3 -3
  55. data/lib/shopify_app/controller_concerns/csrf_protection.rb +15 -0
  56. data/lib/shopify_app/controller_concerns/embedded_app.rb +3 -2
  57. data/lib/shopify_app/controller_concerns/localization.rb +1 -0
  58. data/lib/shopify_app/controller_concerns/login_protection.rb +60 -15
  59. data/lib/shopify_app/controller_concerns/payload_verification.rb +24 -0
  60. data/lib/shopify_app/controller_concerns/webhook_verification.rb +3 -18
  61. data/lib/shopify_app/engine.rb +5 -0
  62. data/lib/shopify_app/jobs/scripttags_manager_job.rb +1 -1
  63. data/lib/shopify_app/jobs/webhooks_manager_job.rb +1 -1
  64. data/lib/shopify_app/managers/scripttags_manager.rb +4 -3
  65. data/lib/shopify_app/managers/webhooks_manager.rb +4 -3
  66. data/lib/shopify_app/middleware/jwt_middleware.rb +42 -0
  67. data/lib/shopify_app/middleware/same_site_cookie_middleware.rb +2 -1
  68. data/lib/shopify_app/session/in_memory_session_store.rb +7 -3
  69. data/lib/shopify_app/session/in_memory_shop_session_store.rb +10 -0
  70. data/lib/shopify_app/session/in_memory_user_session_store.rb +10 -0
  71. data/lib/shopify_app/session/jwt.rb +61 -0
  72. data/lib/shopify_app/session/null_user_session_store.rb +22 -0
  73. data/lib/shopify_app/session/session_repository.rb +13 -16
  74. data/lib/shopify_app/session/session_storage.rb +1 -0
  75. data/lib/shopify_app/session/shop_session_storage.rb +21 -9
  76. data/lib/shopify_app/session/user_session_storage.rb +19 -8
  77. data/lib/shopify_app/test_helpers/all.rb +2 -0
  78. data/lib/shopify_app/test_helpers/webhook_verification_helper.rb +17 -0
  79. data/lib/shopify_app/utils.rb +6 -5
  80. data/lib/shopify_app/version.rb +2 -1
  81. data/lib/shopify_app.rb +12 -5
  82. data/package-lock.json +10 -78
  83. data/package.json +1 -1
  84. data/shopify_app.gemspec +12 -7
  85. data/yarn.lock +12 -12
  86. metadata +53 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d4e2d37f9112725500d1a9f36fe76b743e8981920eea4838024cafd6a71cb5eb
4
- data.tar.gz: 3c52a0ee9a7f40433ad01b82bda3a0c6d30dd9bb45c319f1d457a0bd13c30fc0
3
+ metadata.gz: eb6669e0b864299f689103042e4c59cb4ddc7e53481b559275b64accc6e390b9
4
+ data.tar.gz: 9e3481e24e1e44ef799ac573025e532814acff362d0c9ea3f44b3e4000a68037
5
5
  SHA512:
6
- metadata.gz: 19a445a22b25b01f860a84128551234313bc44e7acd1583ec90bc96f59d65a8fac208feb1d5a6899453935dd19458196c5253605d85e3ac346be2fa405a50b4c
7
- data.tar.gz: 526354098526753ade6d30a346ffa75b2280707638b66dba61c89b34a771e72dd4c23cfae8bda319de58a7a373e7c05d233a13a4f2f8325c7754cda1ed58d835
6
+ metadata.gz: 13f7898748c764d9093d8479ce61a3b1f2d5e9d3ebf7b04a952af7587ef243f9c785c3573c45a915a909a6b9d6cb15ea0d63ab34ed424c45401419f331aa141d
7
+ data.tar.gz: ba8649d90387c3c5c8050ad69923a9e56509955016c5d8bfd955e8870bf0d55f6ed3956dc1643e2f11aa655730e82504e7c28a472a7fcc542a4977b76169ebf4
@@ -0,0 +1,6 @@
1
+ Before submitting the PR, please consider if any of the following are needed:
2
+
3
+ - [ ] Update `CHANGELOG.md` if the changes would impact users
4
+ - [ ] Update `README.md`, if appropriate.
5
+ - [ ] Update any relevant pages in `docs/`, if necessary
6
+ - [ ] For security fixes, the [Disclosure Policy](https://github.com/Shopify/shopify_app/blob/master/SECURITY.md#disclosure-policy) must be followed.
@@ -0,0 +1,28 @@
1
+ name: RuboCop
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: ubuntu-latest
8
+
9
+ steps:
10
+ - uses: actions/checkout@v2
11
+ - name: Set up Ruby 2.7
12
+ uses: ruby/setup-ruby@v1
13
+ with:
14
+ ruby-version: 2.7
15
+ - name: Cache gems
16
+ uses: actions/cache@v1
17
+ with:
18
+ path: vendor/bundle
19
+ key: ${{ runner.os }}-rubocop-${{ hashFiles('**/Gemfile.lock') }}
20
+ restore-keys: |
21
+ ${{ runner.os }}-rubocop-
22
+ - name: Install gems
23
+ run: |
24
+ bundle config path vendor/bundle
25
+ bundle config set without 'default development test'
26
+ bundle install --jobs 4 --retry 3
27
+ - name: Run RuboCop
28
+ run: bundle exec rubocop --parallel
data/.rubocop.yml CHANGED
@@ -1,10 +1,17 @@
1
- inherit_from:
2
- - https://shopify.github.io/ruby-style-guide/rubocop.yml
1
+ inherit_gem:
2
+ rubocop-shopify: rubocop.yml
3
3
 
4
- LineLength:
4
+ AllCops:
5
+ TargetRubyVersion: 2.7
5
6
  Exclude:
6
- - test/**/*
7
+ - 'test/tmp/**/*'
8
+ - 'vendor/bundle/**/*'
7
9
 
8
- Metrics/ClassLength:
10
+ Style/MethodCallWithArgsParentheses:
9
11
  Exclude:
10
- - test/**/*
12
+ - '**/Gemfile'
13
+
14
+ Style/ClassAndModuleChildren:
15
+ Exclude:
16
+ - 'test/**/*'
17
+
data/.travis.yml CHANGED
@@ -13,9 +13,9 @@ cache:
13
13
  yarn: true
14
14
 
15
15
  rvm:
16
- - 2.4.3
17
- - 2.5.0
18
- - 2.6.2
16
+ - 2.5
17
+ - 2.6
18
+ - 2.7
19
19
 
20
20
  install:
21
21
  - bundle install
data/CHANGELOG.md CHANGED
@@ -1,3 +1,54 @@
1
+ 14.0.0
2
+ ------
3
+ * Ruby 2.4 is no longer supported by this gem
4
+ * Bump gemspec ruby dependency to 2.5
5
+ * (Beta) Add `--with-session-token` flag to the Shopify App generator to create an app that is compatible with App Bridge Authentication
6
+
7
+ 13.5.0
8
+ ------
9
+ * Add `signal_access_token_required` helper method for apps to indicate access token has expired and that a new one is required
10
+
11
+ 13.4.1
12
+ ------
13
+ * Fix the version checks for the dependency on `shopify_api` to allow all of v9.X
14
+
15
+ 13.4.0
16
+ ------
17
+ * Skip CSRF protection if a valid signed JWT token is present as we trust Shopify to be the only source that can sign it securely. [#994](https://github.com/Shopify/shopify_app/pull/994)
18
+
19
+ 13.3.0
20
+ ------
21
+ * Added Payload Verification module [#992](https://github.com/Shopify/shopify_app/pull/992)
22
+ * Add concern to check for valid shop domains in the unauthenticated controller
23
+
24
+ 13.2.0
25
+ ------
26
+ * Get current shop domain from JWT header
27
+ * Validate that the omniauth data matches the JWT data
28
+ * Persist the token information to the session store
29
+
30
+ 13.1.1
31
+ ------
32
+ * Update browser_sniffer to 1.2.2
33
+
34
+ 13.1.0
35
+ ------
36
+ * Adds the shop URL as a parameter when redirecting after the callback
37
+ * Bump minimum Ruby version to 2.4
38
+ * Bug fixes
39
+
40
+ 13.0.1
41
+ ------
42
+ * Small addition to WebhookJob to return if the shop is nil #952
43
+ * Added Rubocop to the Repo #948
44
+ * Added a WebhookVerification test helper #950
45
+ * Fix for deprecation warning while loading session storage at startup
46
+ * Changes that will allow future JWT authentication
47
+
48
+ 13.0.1
49
+ ------
50
+ * fix for deprecation warning while loading session storage at startup
51
+
1
52
  13.0.0
2
53
  ------
3
54
  + #887 Added concurrent user and shop session support (online/offline)
data/Gemfile CHANGED
@@ -1,6 +1,11 @@
1
+ # frozen_string_literal: true
1
2
  source "https://rubygems.org"
2
3
 
3
4
  # Specify your gem's dependencies in shopify_app.gemspec
4
5
  gemspec
5
6
 
6
7
  gem 'rails-controller-testing', group: :test
8
+
9
+ group :rubocop do
10
+ gem 'rubocop-shopify', require: false
11
+ end
data/README.md CHANGED
@@ -8,7 +8,7 @@ Shopify App
8
8
 
9
9
  Shopify Application Rails engine and generator
10
10
 
11
- #### NOTE : Versions 8.0.0 through 8.2.3 contained a CSRF vulnerability that was addressed in version 8.2.4. Please update to version 8.2.4 if you're using an old version.
11
+ #### NOTE: Versions 8.0.0 through 8.2.3 contained a CSRF vulnerability that was addressed in version 8.2.4. Please update to version 8.2.4 if you're using an old version.
12
12
 
13
13
  Table of Contents
14
14
  -----------------
@@ -25,16 +25,16 @@ Table of Contents
25
25
  - [AppProxyVerification](#appproxyverification)
26
26
  - [Troubleshooting](#troubleshooting)
27
27
  - [Testing an embedded app outside the Shopify admin](#testing-an-embedded-app-outside-the-shopify-admin)
28
- - [Migration to 13.0.0](#migrating-to-13)
28
+ - [Migration to 13.0.0](#migrating-to-1300)
29
29
  - [Questions or problems?](#questions-or-problems-)
30
30
  - [Rails 6 Compatibility](#rails-6-compatibility)
31
31
  - [Upgrading from 8.6 to 9.0.0](#upgrading-from-86-to-900)
32
32
 
33
33
  Introduction
34
34
  -----------
35
- Get started with the [Shopify Admin API](https://help.shopify.com/en/api/getting-started) faster; This gem includes a Rails Engine and generators for writing Rails applications using the Shopify API. The Engine provides a SessionsController and all the required code for authenticating with a shop via Oauth (other authentication methods are not supported).
35
+ Get started with the [Shopify Admin API](https://help.shopify.com/en/api/getting-started) faster; This gem includes a Rails Engine and generators for writing Rails applications using the Shopify API. The Engine provides a SessionsController and all the required code for authenticating with a shop via OAuth (other authentication methods are not supported).
36
36
 
37
- *Note: It's recommended to use this on a new Rails project, so that the generator won't overwrite/delete your files.*
37
+ *Note: It's recommended to use this on a new Rails project so that the generator won't overwrite/delete your files.*
38
38
 
39
39
  Learn how to create and deploy a new Shopify App to Heroku with our [quickstart guide](https://github.com/Shopify/shopify_app/blob/master/docs/Quickstart.md), or dive in in less than 5 minutes with this quickstart video:
40
40
 
@@ -42,7 +42,7 @@ Learn how to create and deploy a new Shopify App to Heroku with our [quickstart
42
42
 
43
43
  Become a Shopify App Developer
44
44
  --------------------------------
45
- To become a Shopify App Developer you'll need a [Shopify Partner account.](http://shopify.com/partners) If you don't have a Shopify Partner account, head to http://shopify.com/partners to create one before you start.
45
+ To become a Shopify App Developer, you'll need a [Shopify Partner account.](http://shopify.com/partners) If you don't have a Shopify Partner account, head to http://shopify.com/partners to create one before you start.
46
46
 
47
47
  Once you have a Partner account, [create a new application in the Partner Dashboard](https://help.shopify.com/en/api/tools/partner-dashboard/your-apps) to get an API key and other API credentials.
48
48
 
@@ -50,7 +50,7 @@ To create an application for development set your new app's `App URL` to the URL
50
50
 
51
51
  Installation
52
52
  ------------
53
- To get started add `shopify_app` to your Gemfile and run `bundle install`:
53
+ To get started, add `shopify_app` to your Gemfile and run `bundle install`:
54
54
 
55
55
  ``` sh
56
56
  # Create a new rails app
@@ -58,8 +58,7 @@ $ rails new my_shopify_app
58
58
  $ cd my_shopify_app
59
59
 
60
60
  # Add the gem shopify_app to your Gemfile
61
- $ echo "gem 'shopify_app'" >> Gemfile
62
- $ bundle install
61
+ $ bundle add shopify_app
63
62
  ```
64
63
 
65
64
  Now we are ready to run any of the [generators](#generators) included with `shopify_app`. The following section explains the generators and what you can do with them.
@@ -67,7 +66,7 @@ Now we are ready to run any of the [generators](#generators) included with `shop
67
66
 
68
67
  #### Rails Compatibility
69
68
 
70
- The lastest version of shopify_app is compatible with Rails `>= 5`. Use version `<= v7.2.8` if you need to work with Rails 4.
69
+ The latest version of shopify_app is compatible with Rails `>= 5`. Use version `<= v7.2.8` if you need to work with Rails 4.
71
70
 
72
71
 
73
72
  Generators
@@ -75,7 +74,7 @@ Generators
75
74
 
76
75
  ### Default Generator
77
76
 
78
- The default generator will run the `install`, `shop`, and `home_controller` generators. This is the recommended way to start a new app from scratch:
77
+ The default generator will run the `install`, `shop`, `authenticated_controller`, and `home_controller` generators. This is the recommended way to start a new app from scratch:
79
78
 
80
79
  ```sh
81
80
  $ rails generate shopify_app
@@ -94,26 +93,22 @@ SHOPIFY_API_SECRET=your api secret
94
93
 
95
94
  These values can be found on the "App Setup" page in the [Shopify Partners Dashboard][dashboard]. If you are checking your code into a code repository, ensure your `.gitignore` prevents your `.env` file from being checked into any publicly accessible code.
96
95
 
97
- **You will need to load the ENV variables into your enviroment, you can do this with the [dot-env](https://github.com/bkeepers/dotenv) gem or any other method you wish to.**
96
+ **You will need to load the ENV variables into your environment, you can do this with the [dot-env](https://github.com/bkeepers/dotenv) gem or any other method you wish to.**
98
97
 
99
98
  ### Install Generator
100
99
 
101
100
  ```sh
102
- $ rails generate shopify_app:install
103
-
104
- # or optionally with arguments:
105
-
106
101
  $ rails generate shopify_app:install
107
102
  ```
108
103
 
109
- Other options include:
104
+ Options include:
110
105
  * `application_name` - the name of your app, it can be supplied with or without double-quotes if a whitespace is present. (e.g. `--application_name Example App` or `--application_name "Example App"`)
111
- * `scope` - the Oauth access scope required for your app, eg **read_products, write_orders**. *Multiple options* need to be delimited by a comma-space, and can be supplied with or without double-quotes
106
+ * `scope` - the OAuth access scope required for your app, e.g. **read_products, write_orders**. *Multiple options* need to be delimited by a comma-space and can be supplied with or without double-quotes
112
107
  (e.g. `--scope read_products, write_orders, write_products` or `--scope "read_products, write_orders, write_products"`)
113
108
  For more information, refer the [docs](http://docs.shopify.com/api/tutorials/oauth).
114
109
  * `embedded` - the default is to generate an [embedded app](http://docs.shopify.com/embedded-app-sdk), if you want a legacy non-embedded app then set this to false, `--embedded false`
115
110
 
116
- You can update any of these settings later on easily, the arguments are simply for convenience.
111
+ You can update any of these settings later on easily; the arguments are simply for convenience.
117
112
 
118
113
  The generator adds ShopifyApp and the required initializers to the host Rails application.
119
114
 
@@ -126,8 +121,18 @@ After running the `install` generator, you can start your app with `bundle exec
126
121
  $ rails generate shopify_app:home_controller
127
122
  ```
128
123
 
129
- This generator creates an example home controller and view which fetches and displays products using the Shopify API
124
+ This generator creates an example home controller and view which fetches and displays products using the Shopify API.
130
125
 
126
+ Options include:
127
+ * __[beta]__ `with-session-token`: This flag generates an unauthenticated home_controller and a protected sample products_controller. It also creates a home view that leverages a session token to fetch products from your products_controller. Use this flag if you plan to build a single-page application or to secure your app using JWT session tokens (e.g. `--with-session-token` or `--with-session-token true`).
128
+
129
+ ### Products Controller Generator
130
+
131
+ ```sh
132
+ $ rails generate shopify_app:products_controller
133
+ ```
134
+
135
+ This generator creates an example products API controller to fetch products using the Shopify API.
131
136
 
132
137
  ### App Proxy Controller Generator
133
138
 
@@ -135,7 +140,7 @@ This generator creates an example home controller and view which fetches and dis
135
140
  $ rails generate shopify_app:app_proxy_controller
136
141
  ```
137
142
 
138
- This optional generator, not included with the default generator, creates the app proxy controller to handle proxy requests to the app from your shop storefront, modifies 'config/routes.rb' with a namespace route, and an example view which displays current shop information using the LiquidAPI
143
+ This optional generator, not included with the default generator, creates the app proxy controller to handle proxy requests to the app from your shop storefront, modifies 'config/routes.rb' with a namespace route, and an example view which displays current shop information using the LiquidAPI.
139
144
 
140
145
  ### Marketing Extension Generator
141
146
 
@@ -143,11 +148,11 @@ This optional generator, not included with the default generator, creates the ap
143
148
  $ rails generate shopify_app:add_marketing_activity_extension
144
149
  ```
145
150
 
146
- This will create a controller with the endpoints required to build a [marketing activities extension](https://help.shopify.com/en/api/embedded-apps/app-extensions/shopify-admin/marketing-activities). The extension will be generated with a base url at `/marketing_activities`, which should also be configured in partners.
151
+ This will create a controller with the endpoints required to build a [marketing activities extension](https://help.shopify.com/en/api/embedded-apps/app-extensions/shopify-admin/marketing-activities). The extension will be generated with a base URL at `/marketing_activities`, which should also be configured in partners.
147
152
 
148
153
  ### Controllers, Routes and Views
149
154
 
150
- The last group of generators are for your convenience if you want to start overriding code included as part of the Rails engine. For example by default the engine provides a simple SessionController, if you run the `rails generate shopify_app:controllers` generator then this code gets copied out into your app so you can start adding to it. Routes and views follow the exact same pattern.
155
+ The last group of generators are for your convenience if you want to start overriding code included as part of the Rails engine. For example, by default the engine provides a simple SessionController, if you run the `rails generate shopify_app:controllers` generator then this code gets copied out into your app so you can start adding to it. Routes and views follow the exact same pattern.
151
156
 
152
157
  Mounting the Engine
153
158
  -------------------
@@ -170,7 +175,7 @@ The engine may also be mounted at a nested route, for example:
170
175
  mount ShopifyApp::Engine, at: '/nested'
171
176
  ```
172
177
 
173
- This will create the Shopify engine routes under the specified subpath. You'll also need to make some updates to your `shopify_app.rb` and `omniauth.rb` initializers. First update the shopify_app initializer to include a custom `root_url` e.g.:
178
+ This will create the Shopify engine routes under the specified subpath. You'll also need to make some updates to your `shopify_app.rb` and `omniauth.rb` initializers. First, update the shopify_app initializer to include a custom `root_url` e.g.:
174
179
 
175
180
  ```ruby
176
181
  ShopifyApp.configure do |config|
@@ -216,7 +221,7 @@ Authentication
216
221
 
217
222
  ### Callback
218
223
 
219
- Upon completing the authentication flow Shopify calls the app at the `callback_path` mentioned before. If the app needs to do some extra work it can define and configure the route to a custom callback controller, inheriting from `ShopifyApp::CallbackController` and hook into or override any of the defined helper methods. The default callback controller already provides the following behaviour:
224
+ Upon completing the authentication flow, Shopify calls the app at the `callback_path` mentioned before. If the app needs to do some extra work, it can define and configure the route to a custom callback controller, inheriting from `ShopifyApp::CallbackController` and hook into or override any of the defined helper methods. The default callback controller already provides the following behaviour:
220
225
  * Logging into the shop and resetting the session
221
226
  * [Installing Webhooks](https://github.com/Shopify/shopify_app#webhooksmanager)
222
227
  * [Setting Scripttags](https://github.com/Shopify/shopify_app#scripttagsmanager)
@@ -227,22 +232,22 @@ Upon completing the authentication flow Shopify calls the app at the `callback_p
227
232
 
228
233
  ### ShopifyApp::SessionRepository
229
234
 
230
- `ShopifyApp::SessionRepository` allows you as a developer to define how your sessions are stored and retrieved for shops. The `SessionRepository` is configured in the `config/initializers/shopify_app.rb` file and can be set to any object that implements `self.store(auth_session, *args)` which stores the session and returns a unique identifier and `self.retrieve(id)` which returns a `ShopifyAPI::Session` for the passed id. These methods are already implemented as part of the `ShopifyApp::SessionStorage` concern, but can be overridden for custom implementation.
235
+ `ShopifyApp::SessionRepository` allows you as a developer to define how your sessions are stored and retrieved for shops. The `SessionRepository` is configured in the `config/initializers/shopify_app.rb` file and can be set to any object that implements `self.store(auth_session, *args)` which stores the session and returns a unique identifier and `self.retrieve(id)` which returns a `ShopifyAPI::Session` for the passed id. These methods are already implemented as part of the `ShopifyApp::SessionStorage` concern but can be overridden for custom implementation.
231
236
 
232
237
  #### Shop-based token storage
233
- Storing tokens on the store model means that any user login associated to the store will have equal access levels to whatever the original user granted the app.
238
+ Storing tokens on the store model means that any user login associated with the store will have equal access levels to whatever the original user granted the app.
234
239
  ```sh
235
240
  $ rails generate shopify_app:shop_model
236
241
  ```
237
242
  This will generate a shop model which will be the storage for the tokens necessary for authentication.
238
243
 
239
244
  #### User-based token storage
240
- A more granular control over level of access per user on an app might be necessary, to which the shop-based token strategy is not sufficient. Shopify supports a user-based token storage strategy where a unique token to each user can be managed. Shop tokens must still be maintained if you are running background jobs so that you can make use of them when necessary.
245
+ A more granular control over the level of access per user on an app might be necessary, to which the shop-based token strategy is not sufficient. Shopify supports a user-based token storage strategy where a unique token to each user can be managed. Shop tokens must still be maintained if you are running background jobs so that you can make use of them when necessary.
241
246
  ```sh
242
247
  $ rails generate shopify_app:shop_model
243
248
  $ rails generate shopify_app:user_model
244
249
  ```
245
- This will generate a shop model and user model which will be the storage for the tokens necessary for authentication.
250
+ This will generate a shop model and user model, which will be the storage for the tokens necessary for authentication.
246
251
 
247
252
  The current Shopify user will be stored in the rails session at `session[:shopify_user]`
248
253
 
@@ -276,7 +281,7 @@ For backwards compatibility, the engine still provides a controller called `Shop
276
281
 
277
282
  ### AfterAuthenticate Job
278
283
 
279
- If your app needs to perform specific actions after the user is authenticated successfully (i.e. every time a new session is created), ShopifyApp can queue or run a job of your choosing (note that we already provide support for automatically creating Webhooks and Scripttags). To configure the after authenticate job update your initializer as follows:
284
+ If your app needs to perform specific actions after the user is authenticated successfully (i.e. every time a new session is created), ShopifyApp can queue or run a job of your choosing (note that we already provide support for automatically creating Webhooks and Scripttags). To configure the after authenticate job, update your initializer as follows:
280
285
 
281
286
  ```ruby
282
287
  ShopifyApp.configure do |config|
@@ -324,11 +329,11 @@ ShopifyApp.configure do |config|
324
329
  end
325
330
  ```
326
331
 
327
- When the oauth callback is completed successfully ShopifyApp will queue a background job which will ensure all the specified webhooks exist for that shop. Because this runs on every oauth callback it means your app will always have the webhooks it needs even if the user uninstalls and re-installs the app.
332
+ When the OAuth callback is completed successfully, ShopifyApp will queue a background job which will ensure all the specified webhooks exist for that shop. Because this runs on every OAuth callback, it means your app will always have the webhooks it needs even if the user uninstalls and re-installs the app.
328
333
 
329
- ShopifyApp also provides a WebhooksController that receives webhooks and queues a job based on the received topic. For example if you register the webhook from above then all you need to do is create a job called `CartsUpdateJob`. The job will be queued with 2 params: `shop_domain` and `webhook` (which is the webhook body).
334
+ ShopifyApp also provides a WebhooksController that receives webhooks and queues a job based on the received topic. For example, if you register the webhook from above, then all you need to do is create a job called `CartsUpdateJob`. The job will be queued with 2 params: `shop_domain` and `webhook` (which is the webhook body).
330
335
 
331
- If you would like to namespace your jobs you may set `webhook_jobs_namespace` in the config. For example if your app handles webhooks from other ecommerce applications as well, and you want Shopify cart update webhooks to be processed by a job living in `jobs/shopify/webhooks/carts_update_job.rb` rather than `jobs/carts_update_job.rb`):
336
+ If you would like to namespace your jobs, you may set `webhook_jobs_namespace` in the config. For example, if your app handles webhooks from other ecommerce applications as well, and you want Shopify cart update webhooks to be processed by a job living in `jobs/shopify/webhooks/carts_update_job.rb` rather than `jobs/carts_update_job.rb`):
332
337
 
333
338
  ```ruby
334
339
  ShopifyApp.configure do |config|
@@ -366,9 +371,9 @@ class CustomWebhooksController < ApplicationController
366
371
  end
367
372
  ```
368
373
 
369
- The module skips the `verify_authenticity_token` before_action and adds an action to verify that the webhook came from Shopify. You can now add a post route to your application pointing to the controller and action to accept the webhook data from Shopify.
374
+ The module skips the `verify_authenticity_token` before_action and adds an action to verify that the webhook came from Shopify. You can now add a post route to your application, pointing to the controller and action to accept the webhook data from Shopify.
370
375
 
371
- The WebhooksManager uses ActiveJob, if ActiveJob is not configured then by default Rails will run the jobs inline. However it is highly recommended to configure a proper background processing queue like sidekiq or resque in production.
376
+ The WebhooksManager uses ActiveJob. If ActiveJob is not configured then by default Rails will run the jobs inline. However, it is highly recommended to configure a proper background processing queue like Sidekiq or Resque in production.
372
377
 
373
378
  ShopifyApp can create webhooks for you using the `add_webhook` generator. This will add the new webhook to your config and create the required job class for you.
374
379
 
@@ -376,7 +381,7 @@ ShopifyApp can create webhooks for you using the `add_webhook` generator. This w
376
381
  rails g shopify_app:add_webhook -t carts/update -a https://example.com/webhooks/carts_update
377
382
  ```
378
383
 
379
- where `-t` is the topic and `-a` is the address the webhook should be sent to.
384
+ Where `-t` is the topic and `-a` is the address the webhook should be sent to.
380
385
 
381
386
  ScripttagsManager
382
387
  -----------------
@@ -459,7 +464,7 @@ class ReviewsController < ApplicationController
459
464
  end
460
465
  ```
461
466
 
462
- Create your app proxy url in the [Shopify Partners' Dashboard][dashboard], making sure to point it to `https://your_app_website.com/app_proxy`.
467
+ Create your app proxy URL in the [Shopify Partners' Dashboard][dashboard], making sure to point it to `https://your_app_website.com/app_proxy`.
463
468
  ![Creating an App Proxy](/images/app-proxy-screenshot.png)
464
469
 
465
470
  App Bridge
@@ -472,6 +477,31 @@ Troubleshooting
472
477
 
473
478
  see [TROUBLESHOOTING.md](https://github.com/Shopify/shopify_app/blob/master/docs/Troubleshooting.md)
474
479
 
480
+ Using Test Helpers inside your Application
481
+ -----------------------------------------
482
+
483
+ A test helper that will allow you to test `ShopifyApp::WebhookVerification` in the controller from your app, to use this test, you need to `require` it directly inside your app `test/controllers/webhook_verification_test.rb`.
484
+
485
+ ```ruby
486
+ require 'test_helper'
487
+ require 'action_controller'
488
+ require 'action_controller/base'
489
+ require 'shopify_app/test_helpers/webhook_verification_helper'
490
+ ```
491
+
492
+ Or you can require in your `test/test_helper.rb`.
493
+
494
+ ```ruby
495
+ ENV['RAILS_ENV'] ||= 'test'
496
+ require_relative '../config/environment'
497
+ require 'rails/test_help'
498
+ require 'byebug'
499
+ require 'shopify_app/test_helpers/all'
500
+ ```
501
+
502
+ With `lib/shopify_app/test_helpers/all'` more tests can be added and will only need to be required in once in your library.
503
+
504
+
475
505
  Testing an embedded app outside the Shopify admin
476
506
  -------------------------------------------------
477
507
 
@@ -495,14 +525,22 @@ change to how session stores work. Here are the steps to migrate to 13.x
495
525
  ### Shop Model Changes (normally `app/models/shop.rb`)
496
526
  - *CHANGE* `include ShopifyApp::SessionStorage` to `include ShopifyApp::ShopSessionStorage`
497
527
 
528
+ ### Changes to the @shop_session instance variable (normally in `app/controllers/*.rb`)
529
+ - *CHANGE* if you are using shop sessions, `@shop_session` will need to be changed to `@current_shopify_session`.
530
+
531
+ ### Changes to Rails `session`
532
+ - *CHANGE* `session[:shopify]` is no longer set. Use `session[:user_id]` if your app uses user based tokens, or `session[:shop_id]` if your app uses shop based tokens.
533
+
498
534
  ### Changes to `ShopifyApp::LoginProtection`
499
535
  `ShopifyApp::LoginProtection`
500
536
 
501
- if you are using `ShopifyApp::LoginProtection#shop_session` in your code, it will need to be
537
+ - CHANGE if you are using `ShopifyApp::LoginProtection#shopify_session` in your code, it will need to be
502
538
  changed to `ShopifyApp::LoginProtection#activate_shopify_session`
539
+ - CHANGE if you are using `ShopifyApp::LoginProtection#clear_shop_session` in your code, it will need to be
540
+ changed to `ShopifyApp::LoginProtection#clear_shopify_session`
503
541
 
504
542
  ### Notes
505
- You do not need a user model, a shop session is fine for most applications.
543
+ You do not need a user model; a shop session is fine for most applications.
506
544
 
507
545
  Questions or problems?
508
546
  ----------------------
@@ -540,7 +578,7 @@ Upgrading from 8.6 to 9.0.0
540
578
 
541
579
  ### Configuration change
542
580
 
543
- Add an api version configuration in `config/initializers/shopify_app.rb`
581
+ Add an API version configuration in `config/initializers/shopify_app.rb`
544
582
  Set this to the version you want to run against by default. See [Shopify API docs](https://help.shopify.com/en/api/versioning) for versions available.
545
583
  ```ruby
546
584
  config.api_version = '2019-04'
@@ -548,7 +586,7 @@ config.api_version = '2019-04'
548
586
 
549
587
  ### Session storage change
550
588
 
551
- You will need to add an `api_version` method to you session storage object. The default implementation for this is.
589
+ You will need to add an `api_version` method to your session storage object. The default implementation for this is.
552
590
  ```ruby
553
591
  def api_version
554
592
  ShopifyApp.configuration.api_version
@@ -586,7 +624,7 @@ is changed to
586
624
 
587
625
  ### ShopifyAPI changes
588
626
 
589
- You will need to also follow the ShopifyAPI [upgrade guide](https://github.com/Shopify/shopify_api/blob/master/README.md#-breaking-change-notice-for-version-700-) to ensure your app is ready to work with api versioning.
627
+ You will need to also follow the ShopifyAPI [upgrade guide](https://github.com/Shopify/shopify_api/blob/master/README.md#-breaking-change-notice-for-version-700-) to ensure your app is ready to work with API versioning.
590
628
 
591
629
  [dashboard]:https://partners.shopify.com
592
630
  [app-bridge]:https://help.shopify.com/en/api/embedded-apps/app-bridge