shopify_app 22.5.1 → 23.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yaml +6 -0
  3. data/.github/workflows/build.yml +5 -5
  4. data/.github/workflows/close-waiting-for-response-issues.yml +1 -1
  5. data/.github/workflows/release.yml +2 -2
  6. data/.github/workflows/remove-labels-on-activity.yml +2 -3
  7. data/.github/workflows/rubocop.yml +2 -2
  8. data/CHANGELOG.md +29 -0
  9. data/Gemfile +1 -1
  10. data/Gemfile.lock +182 -123
  11. data/README.md +105 -25
  12. data/Rakefile +13 -0
  13. data/app/controllers/shopify_app/callback_controller.rb +2 -40
  14. data/app/controllers/shopify_app/extension_verification_controller.rb +1 -1
  15. data/app/jobs/shopify_app/script_tags_manager_job.rb +16 -0
  16. data/app/views/shopify_app/sessions/new.html.erb +1 -1
  17. data/docs/Releasing.md +113 -19
  18. data/docs/Upgrading.md +72 -0
  19. data/docs/shopify_app/content-security-policy.md +50 -3
  20. data/docs/shopify_app/controller-concerns.md +20 -0
  21. data/docs/shopify_app/generators.md +1 -1
  22. data/docs/shopify_app/script-tags.md +52 -0
  23. data/docs/shopify_app/sessions.md +149 -22
  24. data/lib/generators/shopify_app/add_app_uninstalled_job/templates/app_uninstalled_job.rb.tt +2 -2
  25. data/lib/generators/shopify_app/add_privacy_jobs/templates/customers_data_request_job.rb.tt +2 -2
  26. data/lib/generators/shopify_app/add_privacy_jobs/templates/customers_redact_job.rb.tt +2 -2
  27. data/lib/generators/shopify_app/add_privacy_jobs/templates/shop_redact_job.rb.tt +2 -2
  28. data/lib/generators/shopify_app/add_webhook/templates/webhook_job.rb.tt +2 -2
  29. data/lib/generators/shopify_app/install/install_generator.rb +1 -1
  30. data/lib/generators/shopify_app/install/templates/shopify_app.rb.tt +1 -2
  31. data/lib/generators/shopify_app/shop_model/shop_model_generator.rb +18 -0
  32. data/lib/generators/shopify_app/shop_model/templates/db/migrate/add_shop_access_token_expiry_columns.erb +7 -0
  33. data/lib/generators/shopify_app/shop_model/templates/shop.rb +1 -1
  34. data/lib/generators/shopify_app/user_model/templates/user.rb +1 -1
  35. data/lib/shopify_app/auth/post_authenticate_tasks.rb +8 -0
  36. data/lib/shopify_app/auth/token_exchange.rb +7 -0
  37. data/lib/shopify_app/configuration.rb +5 -26
  38. data/lib/shopify_app/controller_concerns/login_protection.rb +12 -8
  39. data/lib/shopify_app/engine.rb +2 -5
  40. data/lib/shopify_app/errors.rb +2 -0
  41. data/lib/shopify_app/managers/script_tags_manager.rb +348 -0
  42. data/lib/shopify_app/session/shop_session_storage.rb +84 -2
  43. data/lib/shopify_app/session/shop_session_storage_with_scopes.rb +6 -0
  44. data/lib/shopify_app/session/user_session_storage.rb +21 -2
  45. data/lib/shopify_app/session/user_session_storage_with_scopes.rb +6 -0
  46. data/lib/shopify_app/utils.rb +2 -1
  47. data/lib/shopify_app/version.rb +1 -1
  48. data/lib/shopify_app.rb +12 -7
  49. data/package.json +8 -3
  50. data/shopify_app.gemspec +9 -10
  51. data/translation.yml +1 -0
  52. data/yarn.lock +228 -176
  53. metadata +63 -52
  54. data/lib/shopify_app/middleware/jwt_middleware.rb +0 -48
  55. data/lib/shopify_app/session/jwt.rb +0 -73
  56. /data/{lib/shopify_app/jobs → app/jobs/shopify_app}/webhooks_manager_job.rb +0 -0
metadata CHANGED
@@ -1,29 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shopify_app
3
3
  version: !ruby/object:Gem::Version
4
- version: 22.5.1
4
+ version: 23.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-12-11 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: activeresource
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
12
  - !ruby/object:Gem::Dependency
28
13
  name: addressable
29
14
  requirement: !ruby/object:Gem::Requirement
@@ -42,16 +27,22 @@ dependencies:
42
27
  name: rails
43
28
  requirement: !ruby/object:Gem::Requirement
44
29
  requirements:
45
- - - ">"
30
+ - - ">="
46
31
  - !ruby/object:Gem::Version
47
- version: 5.2.1
32
+ version: '7.1'
33
+ - - "<"
34
+ - !ruby/object:Gem::Version
35
+ version: '9'
48
36
  type: :runtime
49
37
  prerelease: false
50
38
  version_requirements: !ruby/object:Gem::Requirement
51
39
  requirements:
52
- - - ">"
40
+ - - ">="
53
41
  - !ruby/object:Gem::Version
54
- version: 5.2.1
42
+ version: '7.1'
43
+ - - "<"
44
+ - !ruby/object:Gem::Version
45
+ version: '9'
55
46
  - !ruby/object:Gem::Dependency
56
47
  name: redirect_safely
57
48
  requirement: !ruby/object:Gem::Requirement
@@ -70,52 +61,46 @@ dependencies:
70
61
  name: shopify_api
71
62
  requirement: !ruby/object:Gem::Requirement
72
63
  requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: 14.7.0
76
- - - "<"
64
+ - - "~>"
77
65
  - !ruby/object:Gem::Version
78
- version: '15.0'
66
+ version: '16.0'
79
67
  type: :runtime
80
68
  prerelease: false
81
69
  version_requirements: !ruby/object:Gem::Requirement
82
70
  requirements:
83
- - - ">="
84
- - !ruby/object:Gem::Version
85
- version: 14.7.0
86
- - - "<"
71
+ - - "~>"
87
72
  - !ruby/object:Gem::Version
88
- version: '15.0'
73
+ version: '16.0'
89
74
  - !ruby/object:Gem::Dependency
90
75
  name: sprockets-rails
91
76
  requirement: !ruby/object:Gem::Requirement
92
77
  requirements:
93
78
  - - ">="
94
79
  - !ruby/object:Gem::Version
95
- version: 2.0.0
80
+ version: '0'
96
81
  type: :runtime
97
82
  prerelease: false
98
83
  version_requirements: !ruby/object:Gem::Requirement
99
84
  requirements:
100
85
  - - ">="
101
86
  - !ruby/object:Gem::Version
102
- version: 2.0.0
87
+ version: '0'
103
88
  - !ruby/object:Gem::Dependency
104
- name: jwt
89
+ name: byebug
105
90
  requirement: !ruby/object:Gem::Requirement
106
91
  requirements:
107
92
  - - ">="
108
93
  - !ruby/object:Gem::Version
109
- version: 2.2.3
110
- type: :runtime
94
+ version: '0'
95
+ type: :development
111
96
  prerelease: false
112
97
  version_requirements: !ruby/object:Gem::Requirement
113
98
  requirements:
114
99
  - - ">="
115
100
  - !ruby/object:Gem::Version
116
- version: 2.2.3
101
+ version: '0'
117
102
  - !ruby/object:Gem::Dependency
118
- name: byebug
103
+ name: csv
119
104
  requirement: !ruby/object:Gem::Requirement
120
105
  requirements:
121
106
  - - ">="
@@ -128,6 +113,20 @@ dependencies:
128
113
  - - ">="
129
114
  - !ruby/object:Gem::Version
130
115
  version: '0'
116
+ - !ruby/object:Gem::Dependency
117
+ name: jwt
118
+ requirement: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: 2.2.3
123
+ type: :development
124
+ prerelease: false
125
+ version_requirements: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: 2.2.3
131
130
  - !ruby/object:Gem::Dependency
132
131
  name: minitest
133
132
  requirement: !ruby/object:Gem::Requirement
@@ -144,6 +143,20 @@ dependencies:
144
143
  version: '0'
145
144
  - !ruby/object:Gem::Dependency
146
145
  name: mocha
146
+ requirement: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: 2.1.0
151
+ type: :development
152
+ prerelease: false
153
+ version_requirements: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ version: 2.1.0
158
+ - !ruby/object:Gem::Dependency
159
+ name: mutex_m
147
160
  requirement: !ruby/object:Gem::Requirement
148
161
  requirements:
149
162
  - - ">="
@@ -244,16 +257,16 @@ dependencies:
244
257
  name: sqlite3
245
258
  requirement: !ruby/object:Gem::Requirement
246
259
  requirements:
247
- - - "~>"
260
+ - - ">="
248
261
  - !ruby/object:Gem::Version
249
- version: '1.4'
262
+ version: '0'
250
263
  type: :development
251
264
  prerelease: false
252
265
  version_requirements: !ruby/object:Gem::Requirement
253
266
  requirements:
254
- - - "~>"
267
+ - - ">="
255
268
  - !ruby/object:Gem::Version
256
- version: '1.4'
269
+ version: '0'
257
270
  - !ruby/object:Gem::Dependency
258
271
  name: webmock
259
272
  requirement: !ruby/object:Gem::Requirement
@@ -268,8 +281,6 @@ dependencies:
268
281
  - - ">="
269
282
  - !ruby/object:Gem::Version
270
283
  version: '0'
271
- description:
272
- email:
273
284
  executables: []
274
285
  extensions: []
275
286
  extra_rdoc_files: []
@@ -281,6 +292,7 @@ files:
281
292
  - ".github/ISSUE_TEMPLATE/config.yml"
282
293
  - ".github/ISSUE_TEMPLATE/feature-request.md"
283
294
  - ".github/PULL_REQUEST_TEMPLATE.md"
295
+ - ".github/dependabot.yaml"
284
296
  - ".github/workflows/build.yml"
285
297
  - ".github/workflows/cla.yml"
286
298
  - ".github/workflows/close-waiting-for-response-issues.yml"
@@ -311,6 +323,8 @@ files:
311
323
  - app/controllers/shopify_app/extension_verification_controller.rb
312
324
  - app/controllers/shopify_app/sessions_controller.rb
313
325
  - app/controllers/shopify_app/webhooks_controller.rb
326
+ - app/jobs/shopify_app/script_tags_manager_job.rb
327
+ - app/jobs/shopify_app/webhooks_manager_job.rb
314
328
  - app/views/shopify_app/layouts/app_bridge.html.erb
315
329
  - app/views/shopify_app/partials/_button_styles.html.erb
316
330
  - app/views/shopify_app/partials/_card_styles.html.erb
@@ -354,6 +368,7 @@ files:
354
368
  - docs/shopify_app/generators.md
355
369
  - docs/shopify_app/handling-access-scopes-changes.md
356
370
  - docs/shopify_app/logging.md
371
+ - docs/shopify_app/script-tags.md
357
372
  - docs/shopify_app/sessions.md
358
373
  - docs/shopify_app/testing.md
359
374
  - docs/shopify_app/webhooks.md
@@ -401,6 +416,7 @@ files:
401
416
  - lib/generators/shopify_app/routes/templates/routes.rb
402
417
  - lib/generators/shopify_app/shop_model/shop_model_generator.rb
403
418
  - lib/generators/shopify_app/shop_model/templates/db/migrate/add_shop_access_scopes_column.erb
419
+ - lib/generators/shopify_app/shop_model/templates/db/migrate/add_shop_access_token_expiry_columns.erb
404
420
  - lib/generators/shopify_app/shop_model/templates/db/migrate/create_shops.erb
405
421
  - lib/generators/shopify_app/shop_model/templates/shop.rb
406
422
  - lib/generators/shopify_app/shop_model/templates/shops.yml
@@ -435,14 +451,12 @@ files:
435
451
  - lib/shopify_app/controller_concerns/with_shopify_id_token.rb
436
452
  - lib/shopify_app/engine.rb
437
453
  - lib/shopify_app/errors.rb
438
- - lib/shopify_app/jobs/webhooks_manager_job.rb
439
454
  - lib/shopify_app/logger.rb
455
+ - lib/shopify_app/managers/script_tags_manager.rb
440
456
  - lib/shopify_app/managers/webhooks_manager.rb
441
- - lib/shopify_app/middleware/jwt_middleware.rb
442
457
  - lib/shopify_app/session/in_memory_session_store.rb
443
458
  - lib/shopify_app/session/in_memory_shop_session_store.rb
444
459
  - lib/shopify_app/session/in_memory_user_session_store.rb
445
- - lib/shopify_app/session/jwt.rb
446
460
  - lib/shopify_app/session/null_user_session_store.rb
447
461
  - lib/shopify_app/session/session_repository.rb
448
462
  - lib/shopify_app/session/session_storage.rb
@@ -462,11 +476,9 @@ files:
462
476
  - translation.yml
463
477
  - webpack.config.js
464
478
  - yarn.lock
465
- homepage:
466
479
  licenses: []
467
480
  metadata:
468
481
  allowed_push_host: https://rubygems.org
469
- post_install_message:
470
482
  rdoc_options: []
471
483
  require_paths:
472
484
  - lib
@@ -474,15 +486,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
474
486
  requirements:
475
487
  - - ">="
476
488
  - !ruby/object:Gem::Version
477
- version: '3.0'
489
+ version: '3.2'
478
490
  required_rubygems_version: !ruby/object:Gem::Requirement
479
491
  requirements:
480
492
  - - ">="
481
493
  - !ruby/object:Gem::Version
482
494
  version: '0'
483
495
  requirements: []
484
- rubygems_version: 3.5.23
485
- signing_key:
496
+ rubygems_version: 3.7.2
486
497
  specification_version: 4
487
498
  summary: This gem is used to get quickly started with the Shopify API
488
499
  test_files: []
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ShopifyApp
4
- class JWTMiddleware
5
- TOKEN_REGEX = /^Bearer (.+)$/
6
- ID_TOKEN_QUERY_PARAM = "id_token"
7
-
8
- def initialize(app)
9
- @app = app
10
- end
11
-
12
- def call(env)
13
- return call_next(env) unless ShopifyApp.configuration.embedded_app?
14
-
15
- token = token_from_authorization_header(env) || token_from_query_string(env)
16
- return call_next(env) unless token
17
-
18
- set_env_variables(token, env)
19
- call_next(env)
20
- end
21
-
22
- private
23
-
24
- def call_next(env)
25
- @app.call(env)
26
- end
27
-
28
- def token_from_authorization_header(env)
29
- env["HTTP_AUTHORIZATION"]&.match(TOKEN_REGEX)&.[](1)
30
- end
31
-
32
- def token_from_query_string(env)
33
- Rack::Utils.parse_nested_query(env["QUERY_STRING"])[ID_TOKEN_QUERY_PARAM]
34
- end
35
-
36
- def set_env_variables(token, env)
37
- jwt = ShopifyAPI::Auth::JwtPayload.new(token)
38
-
39
- env["jwt.token"] = token
40
- env["jwt.shopify_domain"] = jwt.shopify_domain
41
- env["jwt.shopify_user_id"] = jwt.shopify_user_id
42
- env["jwt.expire_at"] = jwt.expire_at
43
- rescue ShopifyAPI::Errors::InvalidJwtTokenError
44
- # ShopifyApp::JWT did not raise any exceptions, ensuring behaviour does not change
45
- nil
46
- end
47
- end
48
- end
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ShopifyApp
4
- class JWT
5
- WARN_EXCEPTIONS = [
6
- ::JWT::DecodeError,
7
- ::JWT::ExpiredSignature,
8
- ::JWT::ImmatureSignature,
9
- ::JWT::VerificationError,
10
- ::ShopifyApp::InvalidAudienceError,
11
- ::ShopifyApp::InvalidDestinationError,
12
- ::ShopifyApp::MismatchedHostsError,
13
- ]
14
-
15
- def initialize(token)
16
- warn_deprecation
17
- @token = token
18
- set_payload
19
- end
20
-
21
- def shopify_domain
22
- @payload && ShopifyApp::Utils.sanitize_shop_domain(@payload["dest"])
23
- end
24
-
25
- def shopify_user_id
26
- @payload["sub"].to_i if @payload && @payload["sub"]
27
- end
28
-
29
- def expire_at
30
- @payload["exp"].to_i if @payload && @payload["exp"]
31
- end
32
-
33
- private
34
-
35
- def set_payload
36
- payload, _ = parse_token_data(ShopifyApp.configuration&.secret, ShopifyApp.configuration&.old_secret)
37
- @payload = validate_payload(payload)
38
- rescue *WARN_EXCEPTIONS
39
- nil
40
- end
41
-
42
- def parse_token_data(secret, old_secret)
43
- ::JWT.decode(@token, secret, true, { algorithm: "HS256" })
44
- rescue ::JWT::VerificationError
45
- raise unless old_secret
46
-
47
- ::JWT.decode(@token, old_secret, true, { algorithm: "HS256" })
48
- end
49
-
50
- def validate_payload(payload)
51
- dest_host = ShopifyApp::Utils.sanitize_shop_domain(payload["dest"])
52
- iss_host = ShopifyApp::Utils.sanitize_shop_domain(payload["iss"])
53
- api_key = ShopifyApp.configuration.api_key
54
-
55
- raise ::ShopifyApp::InvalidAudienceError,
56
- "'aud' claim does not match api_key" unless payload["aud"] == api_key
57
- raise ::ShopifyApp::InvalidDestinationError, "'dest' claim host not a valid shopify host" unless dest_host
58
-
59
- raise ::ShopifyApp::MismatchedHostsError,
60
- "'dest' claim host does not match 'iss' claim host" unless dest_host == iss_host
61
-
62
- payload
63
- end
64
-
65
- def warn_deprecation
66
- message = <<~EOS
67
- "ShopifyApp::JWT will be deprecated, use ShopifyAPI::Auth::JwtPayload to parse JWT token instead."
68
- EOS
69
-
70
- ShopifyApp::Logger.deprecated(message, "23.0.0")
71
- end
72
- end
73
- end