shopify_api 9.4.1 → 9.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +1 -1
- data/.github/workflows/build.yml +8 -5
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +12 -10
- data/dev.yml +11 -0
- data/lib/shopify_api/hmac_params.rb +23 -0
- data/lib/shopify_api/session.rb +2 -7
- data/lib/shopify_api/version.rb +1 -1
- data/lib/shopify_api.rb +1 -0
- data/service.yml +2 -5
- data/shopify_api.gemspec +2 -1
- data/test/fulfillment_order_test.rb +2 -2
- data/test/hmac_params_test.rb +25 -0
- data/test/meta_test.rb +2 -2
- data/test/session_test.rb +13 -9
- metadata +22 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 86c73a80fab5607e57486b42ce37c750797bfc5ac391012b0ca4b8ad2e8dee7e
|
4
|
+
data.tar.gz: 7b4df963e1f9163d23a51623aa845f32a0bf996abf5f447f22a7226f0b6f0b5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87c1fdb069d8f3946eb2136c99eede3f03eb86373ccd60a1e7e46188b7fd141fd418e92a665802949b6b196625aafd6e4065af815cc52f5ff5d437e25517b7d1
|
7
|
+
data.tar.gz: ca85757c71561e6956f1e7499142a45f44d511e9256fb112fc594302d12bdca3d0071d68534a2e8061e0949251aec1c00cd8c5c977a7cfc040f3419ab7a9a1bb
|
data/.github/CODEOWNERS
CHANGED
@@ -1 +1 @@
|
|
1
|
-
* @shopify/
|
1
|
+
* @shopify/core-build-learn
|
data/.github/workflows/build.yml
CHANGED
@@ -12,17 +12,20 @@ jobs:
|
|
12
12
|
strategy:
|
13
13
|
matrix:
|
14
14
|
version:
|
15
|
-
- 2.4
|
16
|
-
- 2.5
|
17
|
-
- 2.6
|
18
|
-
- 2.7
|
15
|
+
- "2.4"
|
16
|
+
- "2.5"
|
17
|
+
- "2.6"
|
18
|
+
- "2.7"
|
19
|
+
- "3.0"
|
19
20
|
gemfile:
|
20
21
|
- Gemfile_ar41
|
21
22
|
- Gemfile_ar50
|
22
23
|
- Gemfile_ar51
|
23
24
|
- Gemfile_ar_master
|
24
25
|
exclude:
|
25
|
-
- version: 2.7
|
26
|
+
- version: "2.7"
|
27
|
+
gemfile: Gemfile_ar41
|
28
|
+
- version: "3.0"
|
26
29
|
gemfile: Gemfile_ar41
|
27
30
|
steps:
|
28
31
|
- uses: actions/checkout@v2
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
shopify_api (9.
|
4
|
+
shopify_api (9.5)
|
5
5
|
activeresource (>= 4.1.0, < 6.0.0)
|
6
6
|
graphql-client
|
7
7
|
rack
|
8
|
+
webrick
|
8
9
|
|
9
10
|
GEM
|
10
11
|
remote: https://rubygems.org/
|
@@ -25,7 +26,7 @@ GEM
|
|
25
26
|
minitest (~> 5.1)
|
26
27
|
tzinfo (~> 1.1)
|
27
28
|
zeitwerk (~> 2.2, >= 2.2.2)
|
28
|
-
addressable (2.
|
29
|
+
addressable (2.8.0)
|
29
30
|
public_suffix (>= 2.0.2, < 5.0)
|
30
31
|
ast (2.4.1)
|
31
32
|
builder (3.2.4)
|
@@ -41,10 +42,10 @@ GEM
|
|
41
42
|
eventmachine (1.2.7)
|
42
43
|
ffi (1.12.2)
|
43
44
|
forwardable-extended (2.6.0)
|
44
|
-
graphql (1.12.
|
45
|
-
graphql-client (0.
|
45
|
+
graphql (1.12.16)
|
46
|
+
graphql-client (0.17.0)
|
46
47
|
activesupport (>= 3.0)
|
47
|
-
graphql (~> 1.
|
48
|
+
graphql (~> 1.10)
|
48
49
|
hashdiff (1.0.1)
|
49
50
|
http_parser.rb (0.6.0)
|
50
51
|
i18n (1.8.2)
|
@@ -78,7 +79,7 @@ GEM
|
|
78
79
|
rb-inotify (~> 0.9, >= 0.9.10)
|
79
80
|
mercenary (0.4.0)
|
80
81
|
method_source (1.0.0)
|
81
|
-
minitest (5.14.
|
82
|
+
minitest (5.14.4)
|
82
83
|
mocha (1.11.2)
|
83
84
|
parallel (1.19.2)
|
84
85
|
parser (2.7.2.0)
|
@@ -91,7 +92,7 @@ GEM
|
|
91
92
|
pry-byebug (3.9.0)
|
92
93
|
byebug (~> 11.0)
|
93
94
|
pry (~> 0.13.0)
|
94
|
-
public_suffix (4.0.
|
95
|
+
public_suffix (4.0.6)
|
95
96
|
rack (2.2.3)
|
96
97
|
rainbow (3.0.0)
|
97
98
|
rake (13.0.1)
|
@@ -99,7 +100,7 @@ GEM
|
|
99
100
|
rb-inotify (0.10.1)
|
100
101
|
ffi (~> 1.0)
|
101
102
|
regexp_parser (1.8.2)
|
102
|
-
rexml (3.2.
|
103
|
+
rexml (3.2.5)
|
103
104
|
rouge (3.19.0)
|
104
105
|
rubocop (0.93.1)
|
105
106
|
parallel (~> 1.10)
|
@@ -129,6 +130,7 @@ GEM
|
|
129
130
|
addressable (>= 2.3.6)
|
130
131
|
crack (>= 0.3.2)
|
131
132
|
hashdiff (>= 0.4.0, < 2.0.0)
|
133
|
+
webrick (1.7.0)
|
132
134
|
zeitwerk (2.3.0)
|
133
135
|
|
134
136
|
PLATFORMS
|
@@ -137,7 +139,7 @@ PLATFORMS
|
|
137
139
|
DEPENDENCIES
|
138
140
|
activeresource (~> 5.1)
|
139
141
|
jekyll
|
140
|
-
minitest (>=
|
142
|
+
minitest (>= 5.14)
|
141
143
|
mocha (>= 1.4.0)
|
142
144
|
pry
|
143
145
|
pry-byebug
|
@@ -148,4 +150,4 @@ DEPENDENCIES
|
|
148
150
|
webmock
|
149
151
|
|
150
152
|
BUNDLED WITH
|
151
|
-
2.
|
153
|
+
2.2.22
|
data/dev.yml
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'webrick/httputils'
|
3
|
+
|
4
|
+
module ShopifyAPI
|
5
|
+
module HmacParams
|
6
|
+
extend WEBrick::HTTPUtils
|
7
|
+
|
8
|
+
def self.encode(params)
|
9
|
+
params
|
10
|
+
.except(:signature, :hmac, :action, :controller)
|
11
|
+
.map { |k,v| sprintf("%s=%s", encode_key(k), encode_value(v)) }
|
12
|
+
.sort.join("&")
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.encode_key(key)
|
16
|
+
_escape(key.to_s, _make_regex('&=%'))
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.encode_value(value)
|
20
|
+
_escape(value.to_s, _make_regex('&%'))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/shopify_api/session.rb
CHANGED
@@ -71,7 +71,7 @@ module ShopifyAPI
|
|
71
71
|
return false unless (signature = params[:hmac])
|
72
72
|
|
73
73
|
calculated_signature = OpenSSL::HMAC.hexdigest(
|
74
|
-
OpenSSL::Digest.new('SHA256'), secret,
|
74
|
+
OpenSSL::Digest.new('SHA256'), secret, ShopifyAPI::HmacParams.encode(params)
|
75
75
|
)
|
76
76
|
|
77
77
|
Rack::Utils.secure_compare(calculated_signature, signature)
|
@@ -79,11 +79,6 @@ module ShopifyAPI
|
|
79
79
|
|
80
80
|
private
|
81
81
|
|
82
|
-
def encoded_params_for_signature(params)
|
83
|
-
params = params.except(:signature, :hmac, :action, :controller)
|
84
|
-
params.map { |k, v| "#{URI.escape(k.to_s, '&=%')}=#{URI.escape(v.to_s, '&%')}" }.sort.join('&')
|
85
|
-
end
|
86
|
-
|
87
82
|
def extract_current_session
|
88
83
|
site = ShopifyAPI::Base.site.to_s
|
89
84
|
token = ShopifyAPI::Base.headers['X-Shopify-Access-Token']
|
@@ -188,7 +183,7 @@ module ShopifyAPI
|
|
188
183
|
end
|
189
184
|
|
190
185
|
def parameterize(params)
|
191
|
-
URI.
|
186
|
+
URI.encode_www_form(params)
|
192
187
|
end
|
193
188
|
|
194
189
|
def access_token_request(code)
|
data/lib/shopify_api/version.rb
CHANGED
data/lib/shopify_api.rb
CHANGED
@@ -21,6 +21,7 @@ require 'shopify_api/metafields'
|
|
21
21
|
require 'shopify_api/countable'
|
22
22
|
require 'shopify_api/resources'
|
23
23
|
require 'shopify_api/session'
|
24
|
+
require 'shopify_api/hmac_params'
|
24
25
|
require 'shopify_api/api_access'
|
25
26
|
require 'shopify_api/message_enricher'
|
26
27
|
require 'shopify_api/connection'
|
data/service.yml
CHANGED
data/shopify_api.gemspec
CHANGED
@@ -35,10 +35,11 @@ Gem::Specification.new do |s|
|
|
35
35
|
s.add_runtime_dependency("activeresource", ">= 4.1.0", "< 6.0.0")
|
36
36
|
s.add_runtime_dependency("rack")
|
37
37
|
s.add_runtime_dependency("graphql-client")
|
38
|
+
s.add_runtime_dependency("webrick")
|
38
39
|
|
39
40
|
s.add_development_dependency("mocha", ">= 1.4.0")
|
40
41
|
s.add_development_dependency("webmock")
|
41
|
-
s.add_development_dependency("minitest", ">=
|
42
|
+
s.add_development_dependency("minitest", ">= 5.14")
|
42
43
|
s.add_development_dependency("rake")
|
43
44
|
s.add_development_dependency("timecop")
|
44
45
|
s.add_development_dependency("rubocop-shopify")
|
@@ -315,7 +315,7 @@ class FulFillmentOrderTest < Test::Unit::TestCase
|
|
315
315
|
fulfillment_order_line_items: [{ id: 1, quantity: 1 }],
|
316
316
|
message: "Fulfill this FO, please.",
|
317
317
|
}
|
318
|
-
response_fulfillment_orders = fulfillment_order.request_fulfillment(params)
|
318
|
+
response_fulfillment_orders = fulfillment_order.request_fulfillment(**params)
|
319
319
|
|
320
320
|
assert_equal('closed', fulfillment_order.status)
|
321
321
|
assert_equal(3, response_fulfillment_orders.size)
|
@@ -367,7 +367,7 @@ class FulFillmentOrderTest < Test::Unit::TestCase
|
|
367
367
|
fulfillment_order_line_items: [{ id: 1, quantity: 1 }],
|
368
368
|
message: "Fulfill this FO, please.",
|
369
369
|
}
|
370
|
-
response_fulfillment_orders = fulfillment_order.request_fulfillment(params)
|
370
|
+
response_fulfillment_orders = fulfillment_order.request_fulfillment(**params)
|
371
371
|
|
372
372
|
assert_equal('closed', fulfillment_order.status)
|
373
373
|
assert_equal(3, response_fulfillment_orders.size)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class HmacParamsTest < Test::Unit::TestCase
|
5
|
+
test "cgi param keys are prepared for hmac validation by encoding equals, ampersand, and percent characters" do
|
6
|
+
assert_equal(
|
7
|
+
"abcd%26%3D%251234",
|
8
|
+
ShopifyAPI::HmacParams.encode_key("abcd&=%1234")
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
test "cgi param values are prepared for hmac validation by encoding ampersand and percent characters" do
|
13
|
+
assert_equal(
|
14
|
+
"abcd%26=%251234",
|
15
|
+
ShopifyAPI::HmacParams.encode_value("abcd&=%1234")
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
test "cgi params are encoded properly for hmac validation" do
|
20
|
+
assert_equal(
|
21
|
+
"abcd%26%3D%251234=abcd%26=%251234",
|
22
|
+
ShopifyAPI::HmacParams.encode({"abcd&=%1234" => "abcd&=%1234"})
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
data/test/meta_test.rb
CHANGED
@@ -40,8 +40,8 @@ class ApiVersionTest < Test::Unit::TestCase
|
|
40
40
|
"display_name": "unstable",
|
41
41
|
"supported": false,
|
42
42
|
},
|
43
|
-
].
|
43
|
+
].as_json
|
44
44
|
|
45
|
-
assert_equal versions, ShopifyAPI::Meta.admin_versions.
|
45
|
+
assert_equal versions, ShopifyAPI::Meta.admin_versions.as_json
|
46
46
|
end
|
47
47
|
end
|
data/test/session_test.rb
CHANGED
@@ -94,7 +94,7 @@ class SessionTest < Test::Unit::TestCase
|
|
94
94
|
end
|
95
95
|
|
96
96
|
test "ignore everything but the subdomain in the shop" do
|
97
|
-
|
97
|
+
assert_equal_uri(
|
98
98
|
"https://testshop.myshopify.com",
|
99
99
|
ShopifyAPI::Session.new(
|
100
100
|
domain: "http://user:pass@testshop.notshopify.net/path",
|
@@ -105,7 +105,7 @@ class SessionTest < Test::Unit::TestCase
|
|
105
105
|
end
|
106
106
|
|
107
107
|
test "append the myshopify domain if not given" do
|
108
|
-
|
108
|
+
assert_equal_uri(
|
109
109
|
"https://testshop.myshopify.com",
|
110
110
|
ShopifyAPI::Session.new(domain: "testshop", token: "any-token", api_version: any_api_version).site
|
111
111
|
)
|
@@ -283,7 +283,7 @@ class SessionTest < Test::Unit::TestCase
|
|
283
283
|
)
|
284
284
|
scope = ["write_products"]
|
285
285
|
permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com")
|
286
|
-
|
286
|
+
assert_equal_uri(
|
287
287
|
"https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
|
288
288
|
"scope=write_products&redirect_uri=http://my_redirect_uri.com",
|
289
289
|
permission_url
|
@@ -299,7 +299,7 @@ class SessionTest < Test::Unit::TestCase
|
|
299
299
|
)
|
300
300
|
scope = ["write_products", "write_customers"]
|
301
301
|
permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com")
|
302
|
-
|
302
|
+
assert_equal_uri(
|
303
303
|
"https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
|
304
304
|
"scope=write_products,write_customers&redirect_uri=http://my_redirect_uri.com",
|
305
305
|
permission_url
|
@@ -315,7 +315,7 @@ class SessionTest < Test::Unit::TestCase
|
|
315
315
|
)
|
316
316
|
scope = []
|
317
317
|
permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com")
|
318
|
-
|
318
|
+
assert_equal_uri(
|
319
319
|
"https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
|
320
320
|
"scope=&redirect_uri=http://my_redirect_uri.com",
|
321
321
|
permission_url
|
@@ -331,9 +331,9 @@ class SessionTest < Test::Unit::TestCase
|
|
331
331
|
)
|
332
332
|
scope = []
|
333
333
|
permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com", state: "My nonce")
|
334
|
-
|
334
|
+
assert_equal_uri(
|
335
335
|
"https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
|
336
|
-
"scope=&redirect_uri=http://my_redirect_uri.com&state=My
|
336
|
+
"scope=&redirect_uri=http://my_redirect_uri.com&state=My+nonce",
|
337
337
|
permission_url
|
338
338
|
)
|
339
339
|
end
|
@@ -347,7 +347,7 @@ class SessionTest < Test::Unit::TestCase
|
|
347
347
|
)
|
348
348
|
scope = []
|
349
349
|
permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com", grant_options: "per-user")
|
350
|
-
|
350
|
+
assert_equal_uri(
|
351
351
|
"https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
|
352
352
|
"scope=&redirect_uri=http://my_redirect_uri.com&grant_options[]=per-user",
|
353
353
|
permission_url
|
@@ -380,7 +380,7 @@ class SessionTest < Test::Unit::TestCase
|
|
380
380
|
token: "any-token",
|
381
381
|
api_version: any_api_version
|
382
382
|
)
|
383
|
-
|
383
|
+
assert_equal_uri("https://testshop.myshopify.com", session.site)
|
384
384
|
end
|
385
385
|
|
386
386
|
test "return_token_if_signature_is_valid" do
|
@@ -618,6 +618,10 @@ class SessionTest < Test::Unit::TestCase
|
|
618
618
|
|
619
619
|
private
|
620
620
|
|
621
|
+
def assert_equal_uri(expected, actual)
|
622
|
+
assert_equal(Addressable::URI.parse(expected), Addressable::URI.parse(actual))
|
623
|
+
end
|
624
|
+
|
621
625
|
def make_sorted_params(params)
|
622
626
|
params.with_indifferent_access.except(
|
623
627
|
:signature, :hmac, :action, :controller
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shopify_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 9.
|
4
|
+
version: '9.5'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activeresource
|
@@ -58,6 +58,20 @@ dependencies:
|
|
58
58
|
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: webrick
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :runtime
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
61
75
|
- !ruby/object:Gem::Dependency
|
62
76
|
name: mocha
|
63
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,14 +106,14 @@ dependencies:
|
|
92
106
|
requirements:
|
93
107
|
- - ">="
|
94
108
|
- !ruby/object:Gem::Version
|
95
|
-
version: '
|
109
|
+
version: '5.14'
|
96
110
|
type: :development
|
97
111
|
prerelease: false
|
98
112
|
version_requirements: !ruby/object:Gem::Requirement
|
99
113
|
requirements:
|
100
114
|
- - ">="
|
101
115
|
- !ruby/object:Gem::Version
|
102
|
-
version: '
|
116
|
+
version: '5.14'
|
103
117
|
- !ruby/object:Gem::Dependency
|
104
118
|
name: rake
|
105
119
|
requirement: !ruby/object:Gem::Requirement
|
@@ -204,6 +218,7 @@ files:
|
|
204
218
|
- RELEASING
|
205
219
|
- Rakefile
|
206
220
|
- SECURITY.md
|
221
|
+
- dev.yml
|
207
222
|
- docker-compose.yml
|
208
223
|
- docs/_config.yml
|
209
224
|
- docs/_includes/footer.html
|
@@ -225,6 +240,7 @@ files:
|
|
225
240
|
- lib/shopify_api/graphql/http_client.rb
|
226
241
|
- lib/shopify_api/graphql/railtie.rb
|
227
242
|
- lib/shopify_api/graphql/task.rake
|
243
|
+
- lib/shopify_api/hmac_params.rb
|
228
244
|
- lib/shopify_api/limits.rb
|
229
245
|
- lib/shopify_api/message_enricher.rb
|
230
246
|
- lib/shopify_api/meta.rb
|
@@ -487,6 +503,7 @@ files:
|
|
487
503
|
- test/gift_card_test.rb
|
488
504
|
- test/graphql/http_client_test.rb
|
489
505
|
- test/graphql_test.rb
|
506
|
+
- test/hmac_params_test.rb
|
490
507
|
- test/image_test.rb
|
491
508
|
- test/inventory_level_test.rb
|
492
509
|
- test/lib/webmock_extensions/last_request.rb
|
@@ -547,7 +564,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
547
564
|
- !ruby/object:Gem::Version
|
548
565
|
version: '0'
|
549
566
|
requirements: []
|
550
|
-
rubygems_version: 3.
|
567
|
+
rubygems_version: 3.2.20
|
551
568
|
signing_key:
|
552
569
|
specification_version: 4
|
553
570
|
summary: ShopifyAPI is a lightweight gem for accessing the Shopify admin REST web
|