shopify_app 13.0.0 → 18.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/ISSUE_TEMPLATE/bug-report.md +63 -0
  4. data/.github/ISSUE_TEMPLATE/config.yml +1 -0
  5. data/.github/ISSUE_TEMPLATE/feature-request.md +33 -0
  6. data/.github/PULL_REQUEST_TEMPLATE.md +22 -0
  7. data/.github/workflows/build.yml +41 -0
  8. data/.github/workflows/release.yml +24 -0
  9. data/.github/workflows/rubocop.yml +22 -0
  10. data/.gitignore +0 -2
  11. data/.rubocop.yml +14 -6
  12. data/CHANGELOG.md +158 -0
  13. data/CONTRIBUTING.md +76 -0
  14. data/Gemfile +5 -0
  15. data/Gemfile.lock +268 -0
  16. data/README.md +73 -534
  17. data/Rakefile +1 -0
  18. data/SECURITY.md +59 -0
  19. data/app/assets/images/storage_access.svg +1 -2
  20. data/app/assets/javascripts/shopify_app/post_redirect.js +9 -0
  21. data/app/assets/javascripts/shopify_app/storage_access.js +2 -1
  22. data/app/assets/javascripts/shopify_app/top_level_interaction.js +1 -1
  23. data/app/controllers/concerns/shopify_app/authenticated.rb +1 -0
  24. data/app/controllers/concerns/shopify_app/ensure_authenticated_links.rb +26 -0
  25. data/app/controllers/concerns/shopify_app/require_known_shop.rb +39 -0
  26. data/app/controllers/concerns/shopify_app/shop_access_scopes_verification.rb +32 -0
  27. data/app/controllers/shopify_app/authenticated_controller.rb +1 -0
  28. data/app/controllers/shopify_app/callback_controller.rb +104 -18
  29. data/app/controllers/shopify_app/extension_verification_controller.rb +2 -7
  30. data/app/controllers/shopify_app/sessions_controller.rb +26 -10
  31. data/app/controllers/shopify_app/webhooks_controller.rb +6 -5
  32. data/app/views/shopify_app/partials/_button_styles.html.erb +41 -36
  33. data/app/views/shopify_app/partials/_card_styles.html.erb +3 -3
  34. data/app/views/shopify_app/partials/_empty_state_styles.html.erb +28 -59
  35. data/app/views/shopify_app/partials/_form_styles.html.erb +56 -0
  36. data/app/views/shopify_app/partials/_layout_styles.html.erb +16 -1
  37. data/app/views/shopify_app/partials/_typography_styles.html.erb +6 -6
  38. data/app/views/shopify_app/sessions/enable_cookies.html.erb +2 -7
  39. data/app/views/shopify_app/sessions/new.html.erb +38 -110
  40. data/app/views/shopify_app/sessions/request_storage_access.html.erb +1 -1
  41. data/app/views/shopify_app/sessions/top_level_interaction.html.erb +21 -22
  42. data/app/views/shopify_app/shared/post_redirect_to_auth_shopify.html.erb +13 -0
  43. data/config/locales/de.yml +11 -11
  44. data/config/locales/fi.yml +1 -1
  45. data/config/locales/nl.yml +8 -8
  46. data/config/locales/th.yml +4 -4
  47. data/config/locales/vi.yml +22 -0
  48. data/config/locales/zh-CN.yml +1 -1
  49. data/config/routes.rb +1 -0
  50. data/docs/Quickstart.md +15 -87
  51. data/docs/Releasing.md +18 -14
  52. data/docs/Troubleshooting.md +147 -4
  53. data/docs/Upgrading.md +126 -0
  54. data/docs/shopify_app/authentication.md +124 -0
  55. data/docs/shopify_app/engine.md +82 -0
  56. data/docs/shopify_app/generators.md +127 -0
  57. data/docs/shopify_app/handling-access-scopes-changes.md +14 -0
  58. data/docs/shopify_app/script-tags.md +28 -0
  59. data/docs/shopify_app/session-repository.md +88 -0
  60. data/docs/shopify_app/testing.md +38 -0
  61. data/docs/shopify_app/webhooks.md +72 -0
  62. data/karma.conf.js +1 -1
  63. data/lib/generators/shopify_app/add_after_authenticate_job/add_after_authenticate_job_generator.rb +5 -3
  64. data/lib/generators/shopify_app/add_after_authenticate_job/templates/after_authenticate_job.rb +1 -0
  65. data/lib/generators/shopify_app/add_marketing_activity_extension/add_marketing_activity_extension_generator.rb +2 -1
  66. data/lib/generators/shopify_app/add_marketing_activity_extension/templates/marketing_activities_controller.rb +4 -4
  67. data/lib/generators/shopify_app/add_webhook/add_webhook_generator.rb +5 -4
  68. data/lib/generators/shopify_app/add_webhook/templates/{webhook_job.rb → webhook_job.rb.tt} +5 -0
  69. data/lib/generators/shopify_app/app_proxy_controller/app_proxy_controller_generator.rb +4 -3
  70. data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_controller.rb +3 -3
  71. data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_route.rb +10 -9
  72. data/lib/generators/shopify_app/authenticated_controller/authenticated_controller_generator.rb +1 -1
  73. data/lib/generators/shopify_app/controllers/controllers_generator.rb +2 -1
  74. data/lib/generators/shopify_app/home_controller/home_controller_generator.rb +31 -3
  75. data/lib/generators/shopify_app/home_controller/templates/home_controller.rb +10 -0
  76. data/lib/generators/shopify_app/home_controller/templates/index.html.erb +66 -16
  77. data/lib/generators/shopify_app/home_controller/templates/unauthenticated_home_controller.rb +12 -0
  78. data/lib/generators/shopify_app/install/install_generator.rb +46 -11
  79. data/lib/generators/shopify_app/install/templates/embedded_app.html.erb +3 -2
  80. data/lib/generators/shopify_app/install/templates/flash_messages.js +0 -2
  81. data/lib/generators/shopify_app/install/templates/omniauth.rb +3 -1
  82. data/lib/generators/shopify_app/install/templates/shopify_app.js +1 -1
  83. data/lib/generators/shopify_app/install/templates/shopify_app.rb.tt +25 -0
  84. data/lib/generators/shopify_app/install/templates/shopify_provider.rb.tt +8 -0
  85. data/lib/generators/shopify_app/install/templates/user_agent.rb +2 -1
  86. data/lib/generators/shopify_app/products_controller/products_controller_generator.rb +19 -0
  87. data/lib/generators/shopify_app/products_controller/templates/products_controller.rb +8 -0
  88. data/lib/generators/shopify_app/routes/routes_generator.rb +1 -0
  89. data/lib/generators/shopify_app/routes/templates/routes.rb +10 -9
  90. data/lib/generators/shopify_app/shop_model/shop_model_generator.rb +39 -7
  91. data/lib/generators/shopify_app/shop_model/templates/db/migrate/add_shop_access_scopes_column.erb +5 -0
  92. data/lib/generators/shopify_app/shop_model/templates/shop.rb +2 -1
  93. data/lib/generators/shopify_app/shopify_app_generator.rb +4 -3
  94. data/lib/generators/shopify_app/user_model/templates/db/migrate/add_user_access_scopes_column.erb +5 -0
  95. data/lib/generators/shopify_app/user_model/templates/user.rb +2 -1
  96. data/lib/generators/shopify_app/user_model/user_model_generator.rb +39 -7
  97. data/lib/generators/shopify_app/views/views_generator.rb +2 -1
  98. data/lib/shopify_app/access_scopes/noop_strategy.rb +13 -0
  99. data/lib/shopify_app/access_scopes/shop_strategy.rb +24 -0
  100. data/lib/shopify_app/access_scopes/user_strategy.rb +41 -0
  101. data/lib/shopify_app/configuration.rb +40 -8
  102. data/lib/shopify_app/controller_concerns/app_proxy_verification.rb +3 -3
  103. data/lib/shopify_app/controller_concerns/csrf_protection.rb +15 -0
  104. data/lib/shopify_app/controller_concerns/embedded_app.rb +3 -2
  105. data/lib/shopify_app/controller_concerns/localization.rb +1 -0
  106. data/lib/shopify_app/controller_concerns/login_protection.rb +81 -16
  107. data/lib/shopify_app/controller_concerns/payload_verification.rb +24 -0
  108. data/lib/shopify_app/controller_concerns/webhook_verification.rb +3 -18
  109. data/lib/shopify_app/engine.rb +27 -0
  110. data/lib/shopify_app/jobs/scripttags_manager_job.rb +1 -1
  111. data/lib/shopify_app/jobs/webhooks_manager_job.rb +1 -1
  112. data/lib/shopify_app/managers/scripttags_manager.rb +4 -3
  113. data/lib/shopify_app/managers/webhooks_manager.rb +4 -3
  114. data/lib/shopify_app/middleware/jwt_middleware.rb +42 -0
  115. data/lib/shopify_app/middleware/same_site_cookie_middleware.rb +3 -2
  116. data/lib/shopify_app/omniauth/omniauth_configuration.rb +64 -0
  117. data/lib/shopify_app/session/in_memory_session_store.rb +7 -3
  118. data/lib/shopify_app/session/in_memory_shop_session_store.rb +12 -0
  119. data/lib/shopify_app/session/in_memory_user_session_store.rb +12 -0
  120. data/lib/shopify_app/session/jwt.rb +63 -0
  121. data/lib/shopify_app/session/null_user_session_store.rb +22 -0
  122. data/lib/shopify_app/session/session_repository.rb +13 -16
  123. data/lib/shopify_app/session/session_storage.rb +1 -0
  124. data/lib/shopify_app/session/shop_session_storage.rb +21 -9
  125. data/lib/shopify_app/session/shop_session_storage_with_scopes.rb +58 -0
  126. data/lib/shopify_app/session/user_session_storage.rb +19 -8
  127. data/lib/shopify_app/session/user_session_storage_with_scopes.rb +58 -0
  128. data/lib/shopify_app/test_helpers/all.rb +2 -0
  129. data/lib/shopify_app/test_helpers/webhook_verification_helper.rb +17 -0
  130. data/lib/shopify_app/utils.rb +18 -5
  131. data/lib/shopify_app/version.rb +2 -1
  132. data/lib/shopify_app.rb +23 -5
  133. data/package.json +7 -8
  134. data/service.yml +1 -4
  135. data/shopify_app.gemspec +15 -9
  136. data/translation.yml +1 -1
  137. data/yarn.lock +2140 -2188
  138. metadata +107 -19
  139. data/.github/ISSUE_TEMPLATE.md +0 -14
  140. data/.travis.yml +0 -27
  141. data/docs/install-on-dev-shop.png +0 -0
  142. data/docs/test-your-app.png +0 -0
  143. data/lib/generators/shopify_app/install/templates/shopify_app.rb +0 -15
  144. data/lib/generators/shopify_app/install/templates/shopify_provider.rb +0 -20
  145. data/package-lock.json +0 -7245
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/Gemfile.lock ADDED
@@ -0,0 +1,268 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ shopify_app (18.0.2)
5
+ browser_sniffer (~> 1.2.2)
6
+ jwt (>= 2.2.3)
7
+ omniauth-rails_csrf_protection
8
+ omniauth-shopify-oauth2 (~> 2.3)
9
+ rails (> 5.2.1, < 6.2)
10
+ redirect_safely (~> 1.0)
11
+ shopify_api (~> 9.4)
12
+
13
+ GEM
14
+ remote: https://rubygems.org/
15
+ specs:
16
+ actioncable (6.1.3.1)
17
+ actionpack (= 6.1.3.1)
18
+ activesupport (= 6.1.3.1)
19
+ nio4r (~> 2.0)
20
+ websocket-driver (>= 0.6.1)
21
+ actionmailbox (6.1.3.1)
22
+ actionpack (= 6.1.3.1)
23
+ activejob (= 6.1.3.1)
24
+ activerecord (= 6.1.3.1)
25
+ activestorage (= 6.1.3.1)
26
+ activesupport (= 6.1.3.1)
27
+ mail (>= 2.7.1)
28
+ actionmailer (6.1.3.1)
29
+ actionpack (= 6.1.3.1)
30
+ actionview (= 6.1.3.1)
31
+ activejob (= 6.1.3.1)
32
+ activesupport (= 6.1.3.1)
33
+ mail (~> 2.5, >= 2.5.4)
34
+ rails-dom-testing (~> 2.0)
35
+ actionpack (6.1.3.1)
36
+ actionview (= 6.1.3.1)
37
+ activesupport (= 6.1.3.1)
38
+ rack (~> 2.0, >= 2.0.9)
39
+ rack-test (>= 0.6.3)
40
+ rails-dom-testing (~> 2.0)
41
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
42
+ actiontext (6.1.3.1)
43
+ actionpack (= 6.1.3.1)
44
+ activerecord (= 6.1.3.1)
45
+ activestorage (= 6.1.3.1)
46
+ activesupport (= 6.1.3.1)
47
+ nokogiri (>= 1.8.5)
48
+ actionview (6.1.3.1)
49
+ activesupport (= 6.1.3.1)
50
+ builder (~> 3.1)
51
+ erubi (~> 1.4)
52
+ rails-dom-testing (~> 2.0)
53
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
54
+ activejob (6.1.3.1)
55
+ activesupport (= 6.1.3.1)
56
+ globalid (>= 0.3.6)
57
+ activemodel (6.1.3.1)
58
+ activesupport (= 6.1.3.1)
59
+ activemodel-serializers-xml (1.0.2)
60
+ activemodel (> 5.x)
61
+ activesupport (> 5.x)
62
+ builder (~> 3.1)
63
+ activerecord (6.1.3.1)
64
+ activemodel (= 6.1.3.1)
65
+ activesupport (= 6.1.3.1)
66
+ activeresource (5.1.1)
67
+ activemodel (>= 5.0, < 7)
68
+ activemodel-serializers-xml (~> 1.0)
69
+ activesupport (>= 5.0, < 7)
70
+ activestorage (6.1.3.1)
71
+ actionpack (= 6.1.3.1)
72
+ activejob (= 6.1.3.1)
73
+ activerecord (= 6.1.3.1)
74
+ activesupport (= 6.1.3.1)
75
+ marcel (~> 1.0.0)
76
+ mini_mime (~> 1.0.2)
77
+ activesupport (6.1.3.1)
78
+ concurrent-ruby (~> 1.0, >= 1.0.2)
79
+ i18n (>= 1.6, < 2)
80
+ minitest (>= 5.1)
81
+ tzinfo (~> 2.0)
82
+ zeitwerk (~> 2.3)
83
+ addressable (2.7.0)
84
+ public_suffix (>= 2.0.2, < 5.0)
85
+ ast (2.4.1)
86
+ binding_of_caller (0.8.0)
87
+ debug_inspector (>= 0.0.1)
88
+ browser_sniffer (1.2.2)
89
+ builder (3.2.4)
90
+ byebug (11.1.3)
91
+ coderay (1.1.3)
92
+ concurrent-ruby (1.1.8)
93
+ crack (0.4.4)
94
+ crass (1.0.6)
95
+ debug_inspector (0.0.3)
96
+ erubi (1.10.0)
97
+ faraday (1.4.1)
98
+ faraday-excon (~> 1.1)
99
+ faraday-net_http (~> 1.0)
100
+ faraday-net_http_persistent (~> 1.1)
101
+ multipart-post (>= 1.2, < 3)
102
+ ruby2_keywords (>= 0.0.4)
103
+ faraday-excon (1.1.0)
104
+ faraday-net_http (1.0.1)
105
+ faraday-net_http_persistent (1.1.0)
106
+ globalid (0.4.2)
107
+ activesupport (>= 4.2.0)
108
+ graphql (1.12.8)
109
+ graphql-client (0.16.0)
110
+ activesupport (>= 3.0)
111
+ graphql (~> 1.8)
112
+ hashdiff (1.0.1)
113
+ hashie (4.1.0)
114
+ i18n (1.8.9)
115
+ concurrent-ruby (~> 1.0)
116
+ jwt (2.2.3)
117
+ loofah (2.9.0)
118
+ crass (~> 1.0.2)
119
+ nokogiri (>= 1.5.9)
120
+ mail (2.7.1)
121
+ mini_mime (>= 0.1.1)
122
+ marcel (1.0.1)
123
+ method_source (0.9.2)
124
+ mini_mime (1.0.3)
125
+ mini_portile2 (2.5.0)
126
+ minitest (5.14.4)
127
+ mocha (1.11.2)
128
+ multi_json (1.15.0)
129
+ multi_xml (0.6.0)
130
+ multipart-post (2.1.1)
131
+ nio4r (2.5.7)
132
+ nokogiri (1.11.2)
133
+ mini_portile2 (~> 2.5.0)
134
+ racc (~> 1.4)
135
+ oauth2 (1.4.7)
136
+ faraday (>= 0.8, < 2.0)
137
+ jwt (>= 1.0, < 3.0)
138
+ multi_json (~> 1.3)
139
+ multi_xml (~> 0.5)
140
+ rack (>= 1.2, < 3)
141
+ omniauth (2.0.4)
142
+ hashie (>= 3.4.6)
143
+ rack (>= 1.6.2, < 3)
144
+ rack-protection
145
+ omniauth-oauth2 (1.7.1)
146
+ oauth2 (~> 1.4)
147
+ omniauth (>= 1.9, < 3)
148
+ omniauth-rails_csrf_protection (1.0.0)
149
+ actionpack (>= 4.2)
150
+ omniauth (~> 2.0)
151
+ omniauth-shopify-oauth2 (2.3.2)
152
+ activesupport
153
+ omniauth-oauth2 (~> 1.5)
154
+ parallel (1.20.1)
155
+ parser (2.7.2.0)
156
+ ast (~> 2.4.1)
157
+ pry (0.12.2)
158
+ coderay (~> 1.1.0)
159
+ method_source (~> 0.9.0)
160
+ pry-nav (0.3.0)
161
+ pry (>= 0.9.10, < 0.13.0)
162
+ pry-stack_explorer (0.4.9.3)
163
+ binding_of_caller (>= 0.7)
164
+ pry (>= 0.9.11)
165
+ public_suffix (4.0.6)
166
+ racc (1.5.2)
167
+ rack (2.2.3)
168
+ rack-protection (2.1.0)
169
+ rack
170
+ rack-test (1.1.0)
171
+ rack (>= 1.0, < 3)
172
+ rails (6.1.3.1)
173
+ actioncable (= 6.1.3.1)
174
+ actionmailbox (= 6.1.3.1)
175
+ actionmailer (= 6.1.3.1)
176
+ actionpack (= 6.1.3.1)
177
+ actiontext (= 6.1.3.1)
178
+ actionview (= 6.1.3.1)
179
+ activejob (= 6.1.3.1)
180
+ activemodel (= 6.1.3.1)
181
+ activerecord (= 6.1.3.1)
182
+ activestorage (= 6.1.3.1)
183
+ activesupport (= 6.1.3.1)
184
+ bundler (>= 1.15.0)
185
+ railties (= 6.1.3.1)
186
+ sprockets-rails (>= 2.0.0)
187
+ rails-controller-testing (1.0.5)
188
+ actionpack (>= 5.0.1.rc1)
189
+ actionview (>= 5.0.1.rc1)
190
+ activesupport (>= 5.0.1.rc1)
191
+ rails-dom-testing (2.0.3)
192
+ activesupport (>= 4.2.0)
193
+ nokogiri (>= 1.6)
194
+ rails-html-sanitizer (1.3.0)
195
+ loofah (~> 2.3)
196
+ railties (6.1.3.1)
197
+ actionpack (= 6.1.3.1)
198
+ activesupport (= 6.1.3.1)
199
+ method_source
200
+ rake (>= 0.8.7)
201
+ thor (~> 1.0)
202
+ rainbow (3.0.0)
203
+ rake (13.0.3)
204
+ rb-readline (0.5.5)
205
+ redirect_safely (1.0.0)
206
+ activemodel
207
+ regexp_parser (2.0.0)
208
+ rexml (3.2.4)
209
+ rubocop (1.5.2)
210
+ parallel (~> 1.10)
211
+ parser (>= 2.7.1.5)
212
+ rainbow (>= 2.2.2, < 4.0)
213
+ regexp_parser (>= 1.8, < 3.0)
214
+ rexml
215
+ rubocop-ast (>= 1.2.0, < 2.0)
216
+ ruby-progressbar (~> 1.7)
217
+ unicode-display_width (>= 1.4.0, < 2.0)
218
+ rubocop-ast (1.3.0)
219
+ parser (>= 2.7.1.5)
220
+ rubocop-shopify (1.0.7)
221
+ rubocop (~> 1.4)
222
+ ruby-progressbar (1.10.1)
223
+ ruby2_keywords (0.0.4)
224
+ shopify_api (9.4.1)
225
+ activeresource (>= 4.1.0, < 6.0.0)
226
+ graphql-client
227
+ rack
228
+ sprockets (4.0.2)
229
+ concurrent-ruby (~> 1.0)
230
+ rack (> 1, < 3)
231
+ sprockets-rails (3.2.2)
232
+ actionpack (>= 4.0)
233
+ activesupport (>= 4.0)
234
+ sprockets (>= 3.0.0)
235
+ sqlite3 (1.4.2)
236
+ thor (1.1.0)
237
+ tzinfo (2.0.4)
238
+ concurrent-ruby (~> 1.0)
239
+ unicode-display_width (1.7.0)
240
+ webmock (3.9.1)
241
+ addressable (>= 2.3.6)
242
+ crack (>= 0.3.2)
243
+ hashdiff (>= 0.4.0, < 2.0.0)
244
+ websocket-driver (0.7.3)
245
+ websocket-extensions (>= 0.1.0)
246
+ websocket-extensions (0.1.5)
247
+ zeitwerk (2.4.2)
248
+
249
+ PLATFORMS
250
+ ruby
251
+
252
+ DEPENDENCIES
253
+ byebug
254
+ minitest
255
+ mocha
256
+ pry
257
+ pry-nav
258
+ pry-stack_explorer
259
+ rails-controller-testing
260
+ rake
261
+ rb-readline
262
+ rubocop-shopify
263
+ shopify_app!
264
+ sqlite3 (~> 1.4)
265
+ webmock
266
+
267
+ BUNDLED WITH
268
+ 2.1.4
data/README.md CHANGED
@@ -1,592 +1,131 @@
1
- Shopify App
2
- ===========
3
- [![Version][gem]][gem_url] [![Build Status](https://travis-ci.org/Shopify/shopify_app.png)](https://travis-ci.org/Shopify/shopify_app)
1
+ # Shopify App
2
+
3
+ **Shopify is doubling our engineering staff in 2021! [Join our team and work on libraries like this one.](https://smrtr.io/5GGrK)**
4
+
5
+ [![Version][gem]][gem_url] [![Build Status](https://github.com/Shopify/shopify_app/workflows/CI/badge.svg)](https://github.com/Shopify/shopify_app/actions?query=workflow%3ACI) ![Supported Rails version][supported_rails_version]
4
6
 
5
7
  [gem]: https://img.shields.io/gem/v/shopify_app.svg
6
8
  [gem_url]: https://rubygems.org/gems/shopify_app
9
+ [supported_rails_version]: https://img.shields.io/badge/rails-%3C6.2.0-orange
7
10
 
11
+ This gem builds Rails applications that can be embedded in the Shopify Admin.
8
12
 
9
- Shopify Application Rails engine and generator
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.
13
+ [Introduction](#introduction) |
14
+ [Requirements](#requirements) |
15
+ [Usage](#usage) |
16
+ [Documentation](#documentation) |
17
+ [Contributing](/CONTRIBUTING.md) |
18
+ [License](/LICENSE)
12
19
 
13
- Table of Contents
14
- -----------------
15
- - [Introduction](#introduction)
16
- - [Become a Shopify App Developer](#become-a-shopify-app-developer)
17
- - [Installation](#installation)
18
- - [Generators](#generators)
19
- - [Mounting the Engine](#mounting-the-engine)
20
- - [Authentication](#authentication)
21
- - [WebhooksManager](#webhooksmanager)
22
- - [ScripttagsManager](#scripttagsmanager)
23
- - [RotateShopifyTokenJob](#rotateshopifytokenjob)
24
- - [App Tunneling](#app-tunneling)
25
- - [AppProxyVerification](#appproxyverification)
26
- - [Troubleshooting](#troubleshooting)
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)
29
- - [Questions or problems?](#questions-or-problems-)
30
- - [Rails 6 Compatibility](#rails-6-compatibility)
31
- - [Upgrading from 8.6 to 9.0.0](#upgrading-from-86-to-900)
20
+ ## Introduction
32
21
 
33
- Introduction
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).
22
+ This gem includes a Rails engine, generators, modules, and mixins that help create Rails applications that work with Shopify APIs. The [Shopify App Rails engine](/docs/shopify_app/engine.md) provides all the code required to implement OAuth with Shopify. The [default Shopify App generator](/docs/shopify_app/generators.md#-environment-rails-generate-shopify_app) builds an app that can be embedded in the Shopify Admin and secures it with [session tokens](https://shopify.dev/concepts/apps/building-embedded-apps-using-session-tokens).
36
23
 
37
- *Note: It's recommended to use this on a new Rails project, so that the generator won't overwrite/delete your files.*
24
+ <!-- This section is linked to in `templates/shopify_app.rb.tt`. Be careful renaming this heading. -->
25
+ ## Requirements
38
26
 
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:
27
+ > **Rails compatibility**
28
+ > * Use Shopify App `<= v7.2.8` if you need to work with Rails 4.
40
29
 
41
- [https://www.youtube.com/watch?v=yGxeoAHlQOg](https://www.youtube.com/watch?v=yGxeoAHlQOg)
30
+ To become a Shopify app developer, you will need a [Shopify Partners](https://www.shopify.com/partners) account. Explore the [Shopify dev docs](https://shopify.dev/concepts/shopify-introduction) to learn more about [building Shopify apps](https://shopify.dev/concepts/apps).
42
31
 
43
- Become a Shopify App Developer
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.
32
+ This gem requires that you have the following credentials:
46
33
 
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.
34
+ - **Shopify API key:** The API key app credential specified in your [Shopify Partners dashboard](https://partners.shopify.com/organizations).
35
+ - **Shopify API secret:** The API secret key app credential specified in your [Shopify Partners dashboard](https://partners.shopify.com/organizations).
48
36
 
49
- To create an application for development set your new app's `App URL` to the URL provided by [your tunnel](#app-tunneling), ensuring that you use `https://`. If you are not planning to embed your app inside the Shopify admin or receive webhooks, set your redirect URL to `http://localhost:3000/` and the `Whitelisted redirection URL(s)` to contain `<App URL>/auth/shopify/callback`.
37
+ ## Usage
50
38
 
51
- Installation
52
- ------------
53
- To get started add `shopify_app` to your Gemfile and run `bundle install`:
39
+ 1. To get started, create a new Rails app:
54
40
 
55
41
  ``` sh
56
- # Create a new rails app
57
42
  $ rails new my_shopify_app
58
- $ cd my_shopify_app
59
-
60
- # Add the gem shopify_app to your Gemfile
61
- $ echo "gem 'shopify_app'" >> Gemfile
62
- $ bundle install
63
- ```
64
-
65
- 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.
66
-
67
-
68
- #### Rails Compatibility
69
-
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.
71
-
72
-
73
- Generators
74
- ----------
75
-
76
- ### Default Generator
77
-
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:
79
-
80
- ```sh
81
- $ rails generate shopify_app
82
- ```
83
-
84
- After running the generator, you will need to run `rails db:migrate` to add new tables to your database. You can start your app with `bundle exec rails server` and install your app by visiting `http://localhost` in your web browser.
85
-
86
- ### API Keys
87
-
88
- The default and install generators have been updated to source Shopify API key and secret from an Environment (`.env`) variables file, which you will need to create with the following format:
89
-
90
- ```
91
- SHOPIFY_API_KEY=your api key
92
- SHOPIFY_API_SECRET=your api secret
93
43
  ```
94
44
 
95
- 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
-
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.**
98
-
99
- ### Install Generator
45
+ 2. Add the Shopify App gem to `my_shopify_app`'s Gemfile.
100
46
 
101
47
  ```sh
102
- $ rails generate shopify_app:install
103
-
104
- # or optionally with arguments:
105
-
106
- $ rails generate shopify_app:install
48
+ $ bundle add shopify_app
107
49
  ```
108
50
 
109
- Other options include:
110
- * `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
112
- (e.g. `--scope read_products, write_orders, write_products` or `--scope "read_products, write_orders, write_products"`)
113
- For more information, refer the [docs](http://docs.shopify.com/api/tutorials/oauth).
114
- * `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
-
116
- You can update any of these settings later on easily, the arguments are simply for convenience.
117
-
118
- The generator adds ShopifyApp and the required initializers to the host Rails application.
51
+ 3. Create a `.env` file in the root of `my_shopify_app` to specify your Shopify API credentials:
119
52
 
120
- After running the `install` generator, you can start your app with `bundle exec rails server` and install your app by visiting localhost.
121
-
122
-
123
- ### Home Controller Generator
124
-
125
- ```sh
126
- $ rails generate shopify_app:home_controller
127
53
  ```
128
-
129
- This generator creates an example home controller and view which fetches and displays products using the Shopify API
130
-
131
-
132
- ### App Proxy Controller Generator
133
-
134
- ```sh
135
- $ rails generate shopify_app:app_proxy_controller
54
+ SHOPIFY_API_KEY=<Your Shopify API key>
55
+ SHOPIFY_API_SECRET=<Your Shopify API secret>
136
56
  ```
137
57
 
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
58
+ > In a development environment, you can use a gem like `dotenv-rails` to manage environment variables.
139
59
 
140
- ### Marketing Extension Generator
60
+ 4. Run the default Shopify App generator to create an app that can be embedded in the Shopify Admin:
141
61
 
142
62
  ```sh
143
- $ rails generate shopify_app:add_marketing_activity_extension
144
- ```
145
-
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.
147
-
148
- ### Controllers, Routes and Views
149
-
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.
151
-
152
- Mounting the Engine
153
- -------------------
154
-
155
- Mounting the Engine will provide the basic routes to authenticating a shop with your application. By default it will provide:
156
-
157
- | Verb | Route | Action |
158
- |--------|-------------------------------|------------------------------|
159
- |GET |'/login' |Login |
160
- |POST |'/login' |Login |
161
- |GET |'/auth/shopify/callback' |Authenticate Callback |
162
- |GET |'/logout' |Logout |
163
- |POST |'/webhooks/:type' |Webhook Callback |
164
-
165
- ### Nested Routes
166
-
167
- The engine may also be mounted at a nested route, for example:
168
-
169
- ```ruby
170
- mount ShopifyApp::Engine, at: '/nested'
171
- ```
172
-
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.:
174
-
175
- ```ruby
176
- ShopifyApp.configure do |config|
177
- config.root_url = '/nested'
178
- end
179
- ```
180
-
181
- then update the omniauth initializer to include a custom `callback_path` e.g.:
182
-
183
- ```ruby
184
- provider :shopify,
185
- ShopifyApp.configuration.api_key,
186
- ShopifyApp.configuration.secret,
187
- scope: ShopifyApp.configuration.scope,
188
- callback_path: '/nested/auth/shopify/callback'
189
- ```
190
-
191
- You may also need to change your `config/routes.rb` to render a view for `/nested`, since this is what will be rendered in the Shopify Admin of any shops that have installed your app. The engine itself doesn't have a view for this, so you'll need something like this:
192
-
193
- ```ruby
194
- # config/routes.rb
195
- Rails.application.routes.draw do
196
- root :to => 'something_else#index'
197
- get "/nested", to: "home#index"
198
- mount ShopifyApp::Engine, at: '/nested'
199
- end
200
- ```
201
-
202
- Finally, note that if you do this, to add your app to a store, you must navigate to `/nested` in order to render the `Enter your shop domain to log in or install this app.` UI.
203
-
204
- ### Custom login URL
205
-
206
- While you can customize the login view by creating a `/app/views/shopify_app/sessions/new.html.erb` file, you may also want to customize the URL entirely. You can modify your `shopify_app.rb` initializer to provide a custom `login_url` e.g.:
207
-
208
- ```ruby
209
- ShopifyApp.configure do |config|
210
- config.login_url = 'https://my.domain.com/nested/login'
211
- end
212
- ```
213
-
214
- Authentication
215
- --------------
216
-
217
- ### Callback
218
-
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:
220
- * Logging into the shop and resetting the session
221
- * [Installing Webhooks](https://github.com/Shopify/shopify_app#webhooksmanager)
222
- * [Setting Scripttags](https://github.com/Shopify/shopify_app#scripttagsmanager)
223
- * [Performing the AfterAuthenticate Job](https://github.com/Shopify/shopify_app#afterauthenticatejob)
224
- * Redirecting to the return address
225
-
226
- **Note that starting with version 8.4.0, we have extracted the callback logic in its own controller. If you are upgrading from a version older than 8.4.0 the callback action and related helper methods were defined in `ShopifyApp::SessionsController` ==> you will have to extend `ShopifyApp::CallbackController` instead and port your logic to the new controller.**
227
-
228
- ### ShopifyApp::SessionRepository
229
-
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.
231
-
232
- #### 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.
234
- ```sh
235
- $ rails generate shopify_app:shop_model
236
- ```
237
- This will generate a shop model which will be the storage for the tokens necessary for authentication.
238
-
239
- #### 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.
241
- ```sh
242
- $ rails generate shopify_app:shop_model
243
- $ rails generate shopify_app:user_model
244
- ```
245
- This will generate a shop model and user model which will be the storage for the tokens necessary for authentication.
246
-
247
- The current Shopify user will be stored in the rails session at `session[:shopify_user]`
248
-
249
- Read more about Online vs. Offline access [here](https://help.shopify.com/api/getting-started/authentication/oauth).
250
-
251
- #### Migrating from shop-based to user-based token strategy
252
- 1. Run the `user_model` generator as mentioned above.
253
- 2. Ensure that both your `Shop` model and `User` model includes the necessary concerns `ShopifyApp::ShopSessionStorage` and `ShopifyApp::UserSessionStorage`.
254
- 3. Make changes to 2 initializer files as shown below:
255
- ```ruby
256
- # In the `omniauth.rb` initializer:
257
- provider :shopify,
258
- ...
259
- setup: lambda { |env|
260
- ...
261
- # Add this line
262
- strategy.options[:per_user_permissions] = strategy.session[:user_tokens]
263
- ...
264
- }
265
-
266
- # In the `shopify_app.rb` initializer:
267
- config.shop_session_repository = {YOUR_SHOP_MODEL_CLASS}
268
- config.user_session_repository = {YOUR_USER_MODEL_CLASS}
269
- ```
270
-
271
- ### Authenticated
272
-
273
- The engine provides a `ShopifyApp::Authenticated` concern which should be included in any controller that is intended to be behind Shopify OAuth. It adds `before_action`s to ensure that the user is authenticated and will redirect to the Shopify login page if not. It is best practice to include this concern in a base controller inheriting from your `ApplicationController`, from which all controllers that require Shopify authentication inherit.
274
-
275
- For backwards compatibility, the engine still provides a controller called `ShopifyApp::AuthenticatedController` which includes the `ShopifyApp::Authenticated` concern. Note that it inherits directly from `ActionController::Base`, so you will not be able to share functionality between it and your application's `ApplicationController`.
276
-
277
- ### AfterAuthenticate Job
278
-
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:
280
-
281
- ```ruby
282
- ShopifyApp.configure do |config|
283
- config.after_authenticate_job = { job: "Shopify::AfterAuthenticateJob" }
284
- end
285
- ```
286
-
287
- The job can be configured as either a class or a class name string.
288
-
289
- If you need the job to run synchronously add the `inline` flag:
290
-
291
- ```ruby
292
- ShopifyApp.configure do |config|
293
- config.after_authenticate_job = { job: Shopify::AfterAuthenticateJob, inline: true }
294
- end
295
- ```
296
-
297
- We've also provided a generator which creates a skeleton job and updates the initializer for you:
298
-
299
- ```
300
- bin/rails g shopify_app:add_after_authenticate_job
301
- ```
302
-
303
- If you want to perform that action only once, e.g. send a welcome email to the user when they install the app, you should make sure that this action is idempotent, meaning that it won't have an impact if run multiple times.
304
-
305
- API Versioning
306
- --------------
307
-
308
- Shopify's API is versioned, and you can [read about that process in the Shopify Developers documentation page](https://shopify.dev/concepts/about-apis/versioning).
309
-
310
- Since shopify_app gem version 1.11.0, the included shopify_api gem has also been updated to allow you to easily set and switch what version of the Shopify API you want your app or service to use, as well as surface warnings to Rails apps about [deprecated endpoints, GraphQL fields and more](https://shopify.dev/concepts/about-apis/versioning#deprecation-practices).
311
-
312
- See the [shopify_api gem README](https://github.com/Shopify/shopify_api/) for more details.
313
-
314
- WebhooksManager
315
- ---------------
316
-
317
- ShopifyApp can manage your app's webhooks for you if you set which webhooks you require in the initializer:
318
-
319
- ```ruby
320
- ShopifyApp.configure do |config|
321
- config.webhooks = [
322
- {topic: 'carts/update', address: 'https://example-app.com/webhooks/carts_update'}
323
- ]
324
- end
325
- ```
326
-
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.
328
-
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).
330
-
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`):
332
-
333
- ```ruby
334
- ShopifyApp.configure do |config|
335
- config.webhook_jobs_namespace = 'shopify/webhooks'
336
- end
337
- ```
338
-
339
- If you are only interested in particular fields, you can optionally filter the data sent by Shopify by specifying the `fields` parameter in `config/webhooks`. Note that you will still receive a webhook request from Shopify every time the resource is updated, but only the specified fields will be sent.
340
-
341
- ```ruby
342
- ShopifyApp.configure do |config|
343
- config.webhooks = [
344
- {topic: 'products/update', address: 'https://example-app.com/webhooks/products_update', fields: ['title', 'vendor']}
345
- ]
346
- end
347
- ```
348
-
349
- If you'd rather implement your own controller then you'll want to use the WebhookVerification module to verify your webhooks, example:
350
-
351
- ```ruby
352
- class CustomWebhooksController < ApplicationController
353
- include ShopifyApp::WebhookVerification
354
-
355
- def carts_update
356
- params.permit!
357
- SomeJob.perform_later(shop_domain: shop_domain, webhook: webhook_params.to_h)
358
- head :no_content
359
- end
360
-
361
- private
362
-
363
- def webhook_params
364
- params.except(:controller, :action, :type)
365
- end
366
- end
367
- ```
368
-
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.
370
-
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.
372
-
373
- 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
-
375
- ```
376
- rails g shopify_app:add_webhook -t carts/update -a https://example.com/webhooks/carts_update
377
- ```
378
-
379
- where `-t` is the topic and `-a` is the address the webhook should be sent to.
380
-
381
- ScripttagsManager
382
- -----------------
383
-
384
- As with webhooks, ShopifyApp can manage your app's scripttags for you by setting which scripttags you require in the initializer:
385
-
386
- ```ruby
387
- ShopifyApp.configure do |config|
388
- config.scripttags = [
389
- {event:'onload', src: 'https://my-shopifyapp.herokuapp.com/fancy.js'},
390
- {event:'onload', src: ->(domain) { dynamic_tag_url(domain) } }
391
- ]
392
- end
393
- ```
394
-
395
- You also need to have write_script_tags permission in the config scope in order to add script tags automatically:
396
-
397
- ```ruby
398
- config.scope = '... , write_script_tags'
399
- ```
400
-
401
- Scripttags are created in the same way as the Webhooks, with a background job which will create the required scripttags.
402
-
403
- If `src` responds to `call` its return value will be used as the scripttag's source. It will be called on scripttag creation and deletion.
404
-
405
- RotateShopifyTokenJob
406
- ---------------------
407
-
408
- If your Shopify secret key is leaked, you can use the RotateShopifyTokenJob to perform [API Credential Rotation](https://help.shopify.com/en/api/getting-started/authentication/oauth/api-credential-rotation).
409
-
410
- Before running the job, you'll need to generate a new secret key from your Shopify Partner dashboard, and update the `/config/initializers/shopify_app.rb` to hold your new and old secret keys:
411
-
412
- ```ruby
413
- config.secret = Rails.application.secrets.shopify_secret
414
- config.old_secret = Rails.application.secrets.old_shopify_secret
63
+ $ rails generate shopify_app
415
64
  ```
416
65
 
417
- We've provided a generator which creates the job and an example rake task:
66
+ 5. Run a migration to create the necessary tables in your database:
418
67
 
419
68
  ```sh
420
- bin/rails g shopify_app:rotate_shopify_token_job
69
+ $ rails db:migrate
421
70
  ```
422
71
 
423
- The generated rake task will be found at `lib/tasks/shopify/rotate_shopify_token.rake` and is provided strictly for example purposes. It might not work with your application out of the box without some configuration.
424
-
425
- ⚠️ Note: if you are updating `shopify_app` from a version prior to 8.4.2 (and do not wish to run the default/install generator again), you will need to add [the following line](https://github.com/Shopify/shopify_app/blob/4f7e6cca2a472d8f7af44b938bd0fcafe4d8e88a/lib/generators/shopify_app/install/templates/shopify_provider.rb#L18) to `config/intializers/omniauth.rb`:
426
-
427
- ```ruby
428
- strategy.options[:old_client_secret] = ShopifyApp.configuration.old_secret
429
- ```
430
-
431
- App Tunneling
432
- -------------
433
-
434
- Your local app needs to be accessible from the public Internet in order to install it on a Shopify store, to use the [App Proxy Controller](#app-proxy-controller-generator) or receive Webhooks.
435
-
436
- Use a tunneling service like [ngrok](https://ngrok.com/), [Forward](https://forwardhq.com/), [Beeceptor](https://beeceptor.com/), [Mockbin](http://mockbin.org/), or [Hookbin](https://hookbin.com/) to make your development environment accessible to the internet.
437
-
438
- For example with [ngrok](https://ngrok.com/), run this command to set up a tunnel proxy to Rails' default port:
72
+ 6. Run the app:
439
73
 
440
74
  ```sh
441
- ngrok http 3000
75
+ $ rails server
442
76
  ```
443
77
 
444
- AppProxyVerification
445
- --------------------
78
+ See [*Quickstart*](/docs/Quickstart.md) to learn how to install your app on a shop.
446
79
 
447
- The engine provides a mixin for verifying incoming HTTP requests sent via an App Proxy. Any controller that `include`s `ShopifyApp::AppProxyVerification` will verify that each request has a valid `signature` query parameter that is calculated using the other query parameters and the app's shared secret.
80
+ This app implements [OAuth 2.0](https://shopify.dev/tutorials/authenticate-with-oauth) with Shopify to authenticate requests made to Shopify APIs. By default, this app is configured to use [session tokens](https://shopify.dev/concepts/apps/building-embedded-apps-using-session-tokens) to authenticate merchants when embedded in the Shopify Admin.
448
81
 
449
- ### Recommended Usage
82
+ See [*Generators*](/docs/shopify_app/generators.md) for a complete list of generators available to Shopify App.
450
83
 
451
- The App Proxy Controller Generator automatically adds the mixin to the generated app_proxy_controller.rb
452
- Additional controllers for resources within the App_Proxy namespace, will need to include the mixin like so:
453
-
454
- ```ruby
455
- # app/controllers/app_proxy/reviews_controller.rb
456
- class ReviewsController < ApplicationController
457
- include ShopifyApp::AppProxyVerification
458
- # ...
459
- end
460
- ```
461
-
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`.
463
- ![Creating an App Proxy](/images/app-proxy-screenshot.png)
464
-
465
- App Bridge
466
- ---
467
-
468
- A basic example of using [App Bridge][app-bridge] is included in the install generator. An app instance is automatically initialized in [shopify_app.js](https://github.com/Shopify/shopify_app/blob/master/lib/generators/shopify_app/install/templates/shopify_app.js) and [flash_messages.js](https://github.com/Shopify/shopify_app/blob/master/lib/generators/shopify_app/install/templates/flash_messages.js) converts Rails [flash messages](https://api.rubyonrails.org/classes/ActionDispatch/Flash.html) to App Bridge Toast actions automatically. By default, this library is included via [unpkg in the embedded_app layout](https://github.com/Shopify/shopify_app/blob/master/lib/generators/shopify_app/install/templates/embedded_app.html.erb#L27). For more advanced uses it is recommended to [install App Bridge via npm or yarn](https://help.shopify.com/en/api/embedded-apps/app-bridge/getting-started#set-up-shopify-app-bridge-in-your-app).
469
-
470
- Troubleshooting
471
- ---------------
472
-
473
- see [TROUBLESHOOTING.md](https://github.com/Shopify/shopify_app/blob/master/docs/Troubleshooting.md)
474
-
475
- Testing an embedded app outside the Shopify admin
476
- -------------------------------------------------
477
-
478
- By default, loading your embedded app will redirect to the Shopify admin, with the app view loaded in an `iframe`. If you need to load your app outside of the Shopify admin (e.g., for performance testing), you can change `forceRedirect: true` to `false` in `ShopifyApp.init` block in the `embedded_app` view. To keep the redirect on in production but off in your `development` and `test` environments, you can use:
479
-
480
- ```javascript
481
- forceRedirect: <%= Rails.env.development? || Rails.env.test? ? 'false' : 'true' %>
482
- ```
84
+ ## Documentation
483
85
 
484
- Migrating to 13.0.0
485
- -------------------
86
+ You can find documentation on gem usage, concepts, mixins, installation, and more in [`/docs`](/docs).
486
87
 
487
- Version 13.0.0 adds the ability to use both user and shop sessions, concurrently. This however involved a large
488
- change to how session stores work. Here are the steps to migrate to 13.x
88
+ * Start with the [*Generators*](/docs/shopify_app/generators.md) document to learn more about the generators this gem offers.
89
+ * Check out the [*Changelog*](/CHANGELOG.md) for notes on the latest gem releases.
90
+ * See [*Troubleshooting*](/docs/Troubleshooting.md) for tips on common issues.
91
+ * If you are looking to upgrade your Shopify App version to a new major release, see [*Upgrading*](/docs/Upgrading.md) for important notes on breaking changes.
489
92
 
490
- ### Changes to `config/initializers/shopify_app.rb`
491
- - *REMOVE* `config.per_user_tokens = [true|false]` this is no longer needed
492
- - *CHANGE* `config.session_repository = 'Shop'` To `config.shop_session_repository = 'Shop'`
493
- - *ADD (optional)* User Session Storage `config.user_session_repository = 'User'`
93
+ ### Overview
494
94
 
495
- ### Shop Model Changes (normally `app/models/shop.rb`)
496
- - *CHANGE* `include ShopifyApp::SessionStorage` to `include ShopifyApp::ShopSessionStorage`
95
+ [Quickstart](/docs/Quickstart.md)
497
96
 
498
- ### Changes to `ShopifyApp::LoginProtection`
499
- `ShopifyApp::LoginProtection`
97
+ [Troubleshooting](/docs/Troubleshooting.md)
500
98
 
501
- if you are using `ShopifyApp::LoginProtection#shop_session` in your code, it will need to be
502
- changed to `ShopifyApp::LoginProtection#activate_shopify_session`
99
+ [Upgrading](/docs/Upgrading.md)
503
100
 
504
- ### Notes
505
- You do not need a user model, a shop session is fine for most applications.
101
+ [Shopify App](/docs/shopify_app)
102
+ * [Authentication](/docs/shopify_app/authentication.md)
103
+ * [Engine](/docs/shopify_app/engine.md)
104
+ * [Generators](/docs/shopify_app/generators.md)
105
+ * [ScriptTags](/docs/shopify_app/script-tags.md)
106
+ * [Session repository](/docs/shopify_app/session-repository.md)
107
+ * [Handling changes in access scopes](/docs/shopify_app/handling-access-scopes-changes.md)
108
+ * [Testing](/docs/shopify_app/testing.md)
109
+ * [Webhooks](/docs/shopify_app/webhooks.md)
506
110
 
507
- Questions or problems?
508
- ----------------------
111
+ ### Engine
509
112
 
510
- - [Ask questions!](https://ecommerce.shopify.com/c/shopify-apis-and-technology)
511
- - [Read the docs!](https://help.shopify.com/api/guides)
512
- - And don't forget to check the [Changelog](https://github.com/Shopify/shopify_app/blob/master/CHANGELOG.md) too!
113
+ Mounting the Shopify App Rails Engine provides the following routes. These routes are configured to help install your application on shops and implement OAuth.
513
114
 
514
- Upgrading to 11.7.0
515
- ---------------------------
115
+ | Verb | Route | Action |
116
+ | ---: | :--- | :--- |
117
+ | `GET` | `/login` | Login |
118
+ | `POST` | `/login` | Login |
119
+ | `GET` | `/auth/shopify/callback` | OAuth redirect URI |
120
+ | `GET` | `/logout` | Logout |
121
+ | `POST` | `/webhooks/:type` | Webhook callback |
516
122
 
517
- ### Session storage method signature breaking change
518
- If you override `def self.store(auth_session)` method in your session storage model (e.g. Shop), the method signature has changed to `def self.store(auth_session, *args)` in order to support user-based token storage. Please update your method signature to include the second argument.
123
+ These routes are configurable. See the more detailed [*Engine*](/docs/shopify_app/engine.md) documentation to learn how you can customize the login URL or mount the Shopify App Rails engine at nested routes.
519
124
 
520
- Rails 6 Compatibility
521
- ---------------------
522
-
523
- ### Disable Webpacker
524
- If you are using sprockets in rails 6 or want to generate a shopify_app without webpacker run the install task by running
525
-
526
- ```
527
- SHOPIFY_APP_DISABLE_WEBPACKER=1 rails generate shopify_app
528
- ```
529
-
530
- and then in your ShopifyApp configuration block, add
531
-
532
- ```
533
- ShopifyApp.configure do |config|
534
- config.disable_webpacker = true
535
- end
536
- ```
537
-
538
- Upgrading from 8.6 to 9.0.0
539
- ---------------------------
540
-
541
- ### Configuration change
542
-
543
- Add an api version configuration in `config/initializers/shopify_app.rb`
544
- 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
- ```ruby
546
- config.api_version = '2019-04'
547
- ```
548
-
549
- ### Session storage change
550
-
551
- You will need to add an `api_version` method to you session storage object. The default implementation for this is.
552
- ```ruby
553
- def api_version
554
- ShopifyApp.configuration.api_version
555
- end
556
- ```
557
-
558
- ### Generated file change
559
-
560
- `embedded_app.html.erb` the usage of `shop_session.url` needs to be changed to `shop_session.domain`
561
- ```erb
562
- <script type="text/javascript">
563
- ShopifyApp.init({
564
- apiKey: "<%= ShopifyApp.configuration.api_key %>",
565
-
566
- shopOrigin: "<%= "https://#{ @shop_session.url }" if @shop_session %>",
567
-
568
- debug: false,
569
- forceRedirect: true
570
- });
571
- </script>
572
- ```
573
- is changed to
574
- ```erb
575
- <script type="text/javascript">
576
- ShopifyApp.init({
577
- apiKey: "<%= ShopifyApp.configuration.api_key %>",
578
-
579
- shopOrigin: "<%= "https://#{ @shop_session.domain }" if @shop_session %>",
580
-
581
- debug: false,
582
- forceRedirect: true
583
- });
584
- </script>
585
- ```
125
+ To learn more about how this gem authenticates with Shopify, see [*Authentication*](/docs/shopify_app/authentication.md).
586
126
 
587
- ### ShopifyAPI changes
127
+ ### API Versioning
588
128
 
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.
129
+ [Shopify's API is versioned](https://shopify.dev/concepts/about-apis/versioning). With Shopify App `v1.11.0`, the included Shopify API gem allows developers to specify and update the Shopify API version they want their app or service to use. The Shopify API gem also surfaces warnings to Rails apps about [deprecated endpoints, GraphQL fields and more](https://shopify.dev/concepts/about-apis/versioning#deprecation-practices).
590
130
 
591
- [dashboard]:https://partners.shopify.com
592
- [app-bridge]:https://help.shopify.com/en/api/embedded-apps/app-bridge
131
+ See the [Shopify API gem README](https://github.com/Shopify/shopify_api/) for more information.