shopify_app 22.5.2 → 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.
- checksums.yaml +4 -4
- data/.github/dependabot.yaml +6 -0
- data/.github/workflows/build.yml +5 -5
- data/.github/workflows/close-waiting-for-response-issues.yml +1 -1
- data/.github/workflows/release.yml +2 -2
- data/.github/workflows/remove-labels-on-activity.yml +2 -3
- data/.github/workflows/rubocop.yml +2 -2
- data/CHANGELOG.md +22 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +181 -122
- data/README.md +105 -25
- data/Rakefile +13 -0
- data/app/controllers/shopify_app/callback_controller.rb +2 -40
- data/app/controllers/shopify_app/extension_verification_controller.rb +1 -1
- data/app/jobs/shopify_app/script_tags_manager_job.rb +16 -0
- data/docs/Releasing.md +113 -19
- data/docs/Upgrading.md +72 -0
- data/docs/shopify_app/content-security-policy.md +50 -3
- data/docs/shopify_app/controller-concerns.md +20 -0
- data/docs/shopify_app/script-tags.md +52 -0
- data/docs/shopify_app/sessions.md +149 -22
- data/lib/generators/shopify_app/add_app_uninstalled_job/templates/app_uninstalled_job.rb.tt +2 -2
- data/lib/generators/shopify_app/add_privacy_jobs/templates/customers_data_request_job.rb.tt +2 -2
- data/lib/generators/shopify_app/add_privacy_jobs/templates/customers_redact_job.rb.tt +2 -2
- data/lib/generators/shopify_app/add_privacy_jobs/templates/shop_redact_job.rb.tt +2 -2
- data/lib/generators/shopify_app/add_webhook/templates/webhook_job.rb.tt +2 -2
- data/lib/generators/shopify_app/install/install_generator.rb +1 -1
- data/lib/generators/shopify_app/shop_model/shop_model_generator.rb +18 -0
- data/lib/generators/shopify_app/shop_model/templates/db/migrate/add_shop_access_token_expiry_columns.erb +7 -0
- data/lib/generators/shopify_app/shop_model/templates/shop.rb +1 -1
- data/lib/generators/shopify_app/user_model/templates/user.rb +1 -1
- data/lib/shopify_app/auth/post_authenticate_tasks.rb +8 -0
- data/lib/shopify_app/auth/token_exchange.rb +7 -0
- data/lib/shopify_app/configuration.rb +5 -5
- data/lib/shopify_app/controller_concerns/login_protection.rb +12 -8
- data/lib/shopify_app/engine.rb +2 -5
- data/lib/shopify_app/errors.rb +2 -0
- data/lib/shopify_app/managers/script_tags_manager.rb +348 -0
- data/lib/shopify_app/session/shop_session_storage.rb +84 -2
- data/lib/shopify_app/session/shop_session_storage_with_scopes.rb +6 -0
- data/lib/shopify_app/session/user_session_storage.rb +21 -2
- data/lib/shopify_app/session/user_session_storage_with_scopes.rb +6 -0
- data/lib/shopify_app/utils.rb +1 -1
- data/lib/shopify_app/version.rb +1 -1
- data/lib/shopify_app.rb +12 -7
- data/package.json +1 -1
- data/shopify_app.gemspec +9 -10
- data/translation.yml +1 -0
- data/yarn.lock +7 -9
- metadata +63 -46
- data/lib/shopify_app/middleware/jwt_middleware.rb +0 -48
- data/lib/shopify_app/session/jwt.rb +0 -73
- /data/{lib/shopify_app/jobs → app/jobs/shopify_app}/webhooks_manager_job.rb +0 -0
metadata
CHANGED
|
@@ -1,28 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: shopify_app
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 23.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shopify
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
-
- !ruby/object:Gem::Dependency
|
|
13
|
-
name: activeresource
|
|
14
|
-
requirement: !ruby/object:Gem::Requirement
|
|
15
|
-
requirements:
|
|
16
|
-
- - ">="
|
|
17
|
-
- !ruby/object:Gem::Version
|
|
18
|
-
version: '0'
|
|
19
|
-
type: :runtime
|
|
20
|
-
prerelease: false
|
|
21
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
-
requirements:
|
|
23
|
-
- - ">="
|
|
24
|
-
- !ruby/object:Gem::Version
|
|
25
|
-
version: '0'
|
|
26
12
|
- !ruby/object:Gem::Dependency
|
|
27
13
|
name: addressable
|
|
28
14
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -41,16 +27,22 @@ dependencies:
|
|
|
41
27
|
name: rails
|
|
42
28
|
requirement: !ruby/object:Gem::Requirement
|
|
43
29
|
requirements:
|
|
44
|
-
- - "
|
|
30
|
+
- - ">="
|
|
45
31
|
- !ruby/object:Gem::Version
|
|
46
|
-
version:
|
|
32
|
+
version: '7.1'
|
|
33
|
+
- - "<"
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: '9'
|
|
47
36
|
type: :runtime
|
|
48
37
|
prerelease: false
|
|
49
38
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
39
|
requirements:
|
|
51
|
-
- - "
|
|
40
|
+
- - ">="
|
|
52
41
|
- !ruby/object:Gem::Version
|
|
53
|
-
version:
|
|
42
|
+
version: '7.1'
|
|
43
|
+
- - "<"
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '9'
|
|
54
46
|
- !ruby/object:Gem::Dependency
|
|
55
47
|
name: redirect_safely
|
|
56
48
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -69,52 +61,46 @@ dependencies:
|
|
|
69
61
|
name: shopify_api
|
|
70
62
|
requirement: !ruby/object:Gem::Requirement
|
|
71
63
|
requirements:
|
|
72
|
-
- - "
|
|
73
|
-
- !ruby/object:Gem::Version
|
|
74
|
-
version: 14.7.0
|
|
75
|
-
- - "<"
|
|
64
|
+
- - "~>"
|
|
76
65
|
- !ruby/object:Gem::Version
|
|
77
|
-
version: '
|
|
66
|
+
version: '16.0'
|
|
78
67
|
type: :runtime
|
|
79
68
|
prerelease: false
|
|
80
69
|
version_requirements: !ruby/object:Gem::Requirement
|
|
81
70
|
requirements:
|
|
82
|
-
- - "
|
|
83
|
-
- !ruby/object:Gem::Version
|
|
84
|
-
version: 14.7.0
|
|
85
|
-
- - "<"
|
|
71
|
+
- - "~>"
|
|
86
72
|
- !ruby/object:Gem::Version
|
|
87
|
-
version: '
|
|
73
|
+
version: '16.0'
|
|
88
74
|
- !ruby/object:Gem::Dependency
|
|
89
75
|
name: sprockets-rails
|
|
90
76
|
requirement: !ruby/object:Gem::Requirement
|
|
91
77
|
requirements:
|
|
92
78
|
- - ">="
|
|
93
79
|
- !ruby/object:Gem::Version
|
|
94
|
-
version:
|
|
80
|
+
version: '0'
|
|
95
81
|
type: :runtime
|
|
96
82
|
prerelease: false
|
|
97
83
|
version_requirements: !ruby/object:Gem::Requirement
|
|
98
84
|
requirements:
|
|
99
85
|
- - ">="
|
|
100
86
|
- !ruby/object:Gem::Version
|
|
101
|
-
version:
|
|
87
|
+
version: '0'
|
|
102
88
|
- !ruby/object:Gem::Dependency
|
|
103
|
-
name:
|
|
89
|
+
name: byebug
|
|
104
90
|
requirement: !ruby/object:Gem::Requirement
|
|
105
91
|
requirements:
|
|
106
92
|
- - ">="
|
|
107
93
|
- !ruby/object:Gem::Version
|
|
108
|
-
version:
|
|
109
|
-
type: :
|
|
94
|
+
version: '0'
|
|
95
|
+
type: :development
|
|
110
96
|
prerelease: false
|
|
111
97
|
version_requirements: !ruby/object:Gem::Requirement
|
|
112
98
|
requirements:
|
|
113
99
|
- - ">="
|
|
114
100
|
- !ruby/object:Gem::Version
|
|
115
|
-
version:
|
|
101
|
+
version: '0'
|
|
116
102
|
- !ruby/object:Gem::Dependency
|
|
117
|
-
name:
|
|
103
|
+
name: csv
|
|
118
104
|
requirement: !ruby/object:Gem::Requirement
|
|
119
105
|
requirements:
|
|
120
106
|
- - ">="
|
|
@@ -127,6 +113,20 @@ dependencies:
|
|
|
127
113
|
- - ">="
|
|
128
114
|
- !ruby/object:Gem::Version
|
|
129
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
|
|
130
130
|
- !ruby/object:Gem::Dependency
|
|
131
131
|
name: minitest
|
|
132
132
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -143,6 +143,20 @@ dependencies:
|
|
|
143
143
|
version: '0'
|
|
144
144
|
- !ruby/object:Gem::Dependency
|
|
145
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
|
|
146
160
|
requirement: !ruby/object:Gem::Requirement
|
|
147
161
|
requirements:
|
|
148
162
|
- - ">="
|
|
@@ -243,16 +257,16 @@ dependencies:
|
|
|
243
257
|
name: sqlite3
|
|
244
258
|
requirement: !ruby/object:Gem::Requirement
|
|
245
259
|
requirements:
|
|
246
|
-
- - "
|
|
260
|
+
- - ">="
|
|
247
261
|
- !ruby/object:Gem::Version
|
|
248
|
-
version: '
|
|
262
|
+
version: '0'
|
|
249
263
|
type: :development
|
|
250
264
|
prerelease: false
|
|
251
265
|
version_requirements: !ruby/object:Gem::Requirement
|
|
252
266
|
requirements:
|
|
253
|
-
- - "
|
|
267
|
+
- - ">="
|
|
254
268
|
- !ruby/object:Gem::Version
|
|
255
|
-
version: '
|
|
269
|
+
version: '0'
|
|
256
270
|
- !ruby/object:Gem::Dependency
|
|
257
271
|
name: webmock
|
|
258
272
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -278,6 +292,7 @@ files:
|
|
|
278
292
|
- ".github/ISSUE_TEMPLATE/config.yml"
|
|
279
293
|
- ".github/ISSUE_TEMPLATE/feature-request.md"
|
|
280
294
|
- ".github/PULL_REQUEST_TEMPLATE.md"
|
|
295
|
+
- ".github/dependabot.yaml"
|
|
281
296
|
- ".github/workflows/build.yml"
|
|
282
297
|
- ".github/workflows/cla.yml"
|
|
283
298
|
- ".github/workflows/close-waiting-for-response-issues.yml"
|
|
@@ -308,6 +323,8 @@ files:
|
|
|
308
323
|
- app/controllers/shopify_app/extension_verification_controller.rb
|
|
309
324
|
- app/controllers/shopify_app/sessions_controller.rb
|
|
310
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
|
|
311
328
|
- app/views/shopify_app/layouts/app_bridge.html.erb
|
|
312
329
|
- app/views/shopify_app/partials/_button_styles.html.erb
|
|
313
330
|
- app/views/shopify_app/partials/_card_styles.html.erb
|
|
@@ -351,6 +368,7 @@ files:
|
|
|
351
368
|
- docs/shopify_app/generators.md
|
|
352
369
|
- docs/shopify_app/handling-access-scopes-changes.md
|
|
353
370
|
- docs/shopify_app/logging.md
|
|
371
|
+
- docs/shopify_app/script-tags.md
|
|
354
372
|
- docs/shopify_app/sessions.md
|
|
355
373
|
- docs/shopify_app/testing.md
|
|
356
374
|
- docs/shopify_app/webhooks.md
|
|
@@ -398,6 +416,7 @@ files:
|
|
|
398
416
|
- lib/generators/shopify_app/routes/templates/routes.rb
|
|
399
417
|
- lib/generators/shopify_app/shop_model/shop_model_generator.rb
|
|
400
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
|
|
401
420
|
- lib/generators/shopify_app/shop_model/templates/db/migrate/create_shops.erb
|
|
402
421
|
- lib/generators/shopify_app/shop_model/templates/shop.rb
|
|
403
422
|
- lib/generators/shopify_app/shop_model/templates/shops.yml
|
|
@@ -432,14 +451,12 @@ files:
|
|
|
432
451
|
- lib/shopify_app/controller_concerns/with_shopify_id_token.rb
|
|
433
452
|
- lib/shopify_app/engine.rb
|
|
434
453
|
- lib/shopify_app/errors.rb
|
|
435
|
-
- lib/shopify_app/jobs/webhooks_manager_job.rb
|
|
436
454
|
- lib/shopify_app/logger.rb
|
|
455
|
+
- lib/shopify_app/managers/script_tags_manager.rb
|
|
437
456
|
- lib/shopify_app/managers/webhooks_manager.rb
|
|
438
|
-
- lib/shopify_app/middleware/jwt_middleware.rb
|
|
439
457
|
- lib/shopify_app/session/in_memory_session_store.rb
|
|
440
458
|
- lib/shopify_app/session/in_memory_shop_session_store.rb
|
|
441
459
|
- lib/shopify_app/session/in_memory_user_session_store.rb
|
|
442
|
-
- lib/shopify_app/session/jwt.rb
|
|
443
460
|
- lib/shopify_app/session/null_user_session_store.rb
|
|
444
461
|
- lib/shopify_app/session/session_repository.rb
|
|
445
462
|
- lib/shopify_app/session/session_storage.rb
|
|
@@ -469,14 +486,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
469
486
|
requirements:
|
|
470
487
|
- - ">="
|
|
471
488
|
- !ruby/object:Gem::Version
|
|
472
|
-
version: '3.
|
|
489
|
+
version: '3.2'
|
|
473
490
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
474
491
|
requirements:
|
|
475
492
|
- - ">="
|
|
476
493
|
- !ruby/object:Gem::Version
|
|
477
494
|
version: '0'
|
|
478
495
|
requirements: []
|
|
479
|
-
rubygems_version: 3.
|
|
496
|
+
rubygems_version: 3.7.2
|
|
480
497
|
specification_version: 4
|
|
481
498
|
summary: This gem is used to get quickly started with the Shopify API
|
|
482
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
|
|
File without changes
|