shopify_api 12.2.1 → 12.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +10 -10
- data/README.md +9 -10
- data/docs/getting_started.md +1 -1
- data/docs/usage/oauth.md +3 -4
- data/lib/shopify_api/auth/oauth.rb +1 -4
- data/lib/shopify_api/clients/http_client.rb +3 -3
- data/lib/shopify_api/context.rb +38 -8
- data/lib/shopify_api/errors/feature_deprecated_error.rb +9 -0
- data/lib/shopify_api/errors/http_response_error.rb +7 -3
- data/lib/shopify_api/errors/log_level_not_found_error.rb +9 -0
- data/lib/shopify_api/logger.rb +82 -0
- data/lib/shopify_api/utils/session_utils.rb +38 -21
- data/lib/shopify_api/version.rb +1 -1
- data/shopify_api.gemspec +2 -2
- metadata +24 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60567c4e9da3da8eb19c903b704297d4cb194a3f63d0644e3273357554e86321
|
4
|
+
data.tar.gz: 19ec21a447be21e2f88ca5e4d3bb2978c587857f63976264bcaf998f7dddce47
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a09451f3182e19d125d662dad337b737377622079e23c03de6949999812bfdbee83fb319bc6ada35d202343a535536b7dc0622fe9d28a66a04465dca0074187a
|
7
|
+
data.tar.gz: 5c1ad7e58afebc440aa712f881c60823c070603b171d1eb80fcb2b3c703b2f0730c1a942d5e3a237cca1adef1d997d087bad716244baca716fd131e4ce8c935b
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,12 @@
|
|
3
3
|
Note: For changes to the API, see https://shopify.dev/changelog?filter=api
|
4
4
|
|
5
5
|
## Unreleased
|
6
|
+
## Version 12.3.0
|
7
|
+
|
8
|
+
- [#1040](https://github.com/Shopify/shopify-api-ruby/pull/1040) `ShopifyAPI::Clients::HttpResponse` as argument for `ShopifyAPI::Errors::HttpResponseError`
|
9
|
+
- [#1055](https://github.com/Shopify/shopify-api-ruby/pull/1055) Makes session_storage optional. Configuring the API with session_storage is now deprecated. Session persistence is handled by the [shopify_app gem](https://github.com/Shopify/shopify_app) if using Rails.
|
10
|
+
- [#1063](https://github.com/Shopify/shopify-api-ruby/pull/1063) Fix ActiveSupport inflector dependency
|
11
|
+
- [#1069](https://github.com/Shopify/shopify-api-ruby/pull/1069) Adds a custom Logger to help write uniform logs across the api and the [shopify_app gem](https://github.com/Shopify/shopify_app)
|
6
12
|
|
7
13
|
## Version 12.2.1
|
8
14
|
- [#1045](https://github.com/Shopify/shopify-api-ruby/pull/1045) Fixes bug with host/host_name requirement.
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
shopify_api (12.
|
4
|
+
shopify_api (12.3.0)
|
5
|
+
activesupport
|
5
6
|
concurrent-ruby
|
6
7
|
hash_diff
|
7
8
|
httparty
|
@@ -10,12 +11,12 @@ PATH
|
|
10
11
|
openssl
|
11
12
|
securerandom
|
12
13
|
sorbet-runtime
|
13
|
-
zeitwerk (~> 2.5)
|
14
|
+
zeitwerk (~> 2.5, < 2.6.5)
|
14
15
|
|
15
16
|
GEM
|
16
17
|
remote: https://rubygems.org/
|
17
18
|
specs:
|
18
|
-
activesupport (7.0.
|
19
|
+
activesupport (7.0.4)
|
19
20
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
20
21
|
i18n (>= 1.6, < 2)
|
21
22
|
minitest (>= 5.1)
|
@@ -25,7 +26,7 @@ GEM
|
|
25
26
|
ast (2.4.2)
|
26
27
|
byebug (11.1.3)
|
27
28
|
coderay (1.1.3)
|
28
|
-
concurrent-ruby (1.1.
|
29
|
+
concurrent-ruby (1.1.10)
|
29
30
|
crack (0.4.5)
|
30
31
|
rexml
|
31
32
|
diff-lcs (1.5.0)
|
@@ -35,7 +36,7 @@ GEM
|
|
35
36
|
httparty (0.20.0)
|
36
37
|
mime-types (~> 3.0)
|
37
38
|
multi_xml (>= 0.5.2)
|
38
|
-
i18n (1.
|
39
|
+
i18n (1.12.0)
|
39
40
|
concurrent-ruby (~> 1.0)
|
40
41
|
json (2.6.2)
|
41
42
|
jwt (2.5.0)
|
@@ -48,7 +49,7 @@ GEM
|
|
48
49
|
mocha (1.13.0)
|
49
50
|
multi_xml (0.6.0)
|
50
51
|
netrc (0.11.0)
|
51
|
-
oj (3.13.
|
52
|
+
oj (3.13.23)
|
52
53
|
openssl (3.0.1)
|
53
54
|
parallel (1.22.1)
|
54
55
|
parser (3.1.2.1)
|
@@ -91,7 +92,7 @@ GEM
|
|
91
92
|
sorbet-runtime
|
92
93
|
syntax_tree (>= 3.4)
|
93
94
|
ruby-progressbar (1.11.0)
|
94
|
-
securerandom (0.2.
|
95
|
+
securerandom (0.2.1)
|
95
96
|
sorbet (0.5.10438)
|
96
97
|
sorbet-static (= 0.5.10438)
|
97
98
|
sorbet-runtime (0.5.10438)
|
@@ -117,7 +118,7 @@ GEM
|
|
117
118
|
thor (>= 1.2.0)
|
118
119
|
yard-sorbet
|
119
120
|
thor (1.2.1)
|
120
|
-
tzinfo (2.0.
|
121
|
+
tzinfo (2.0.5)
|
121
122
|
concurrent-ruby (~> 1.0)
|
122
123
|
unicode-display_width (2.3.0)
|
123
124
|
unparser (0.6.5)
|
@@ -133,14 +134,13 @@ GEM
|
|
133
134
|
yard-sorbet (0.7.0)
|
134
135
|
sorbet-runtime (>= 0.5)
|
135
136
|
yard (>= 0.9)
|
136
|
-
zeitwerk (2.6.
|
137
|
+
zeitwerk (2.6.4)
|
137
138
|
|
138
139
|
PLATFORMS
|
139
140
|
arm64-darwin-21
|
140
141
|
x86_64-linux
|
141
142
|
|
142
143
|
DEPENDENCIES
|
143
|
-
activesupport
|
144
144
|
fakefs
|
145
145
|
minitest
|
146
146
|
mocha
|
data/README.md
CHANGED
@@ -23,7 +23,6 @@ To follow these usage guides, you will need to:
|
|
23
23
|
|
24
24
|
- have a working knowledge of ruby and a web framework such as Rails or Sinatra
|
25
25
|
- have a Shopify Partner account and development store
|
26
|
-
- _OR_ have a test store where you can create a private app
|
27
26
|
- have an app already set up in your test store or partner account
|
28
27
|
- add the URL and the appropriate redirect for your OAuth callback route to your app settings
|
29
28
|
|
@@ -55,8 +54,8 @@ ShopifyAPI::Context.setup(
|
|
55
54
|
scope: "read_orders,read_products,etc",
|
56
55
|
session_storage: ShopifyAPI::Auth::FileSessionStorage.new, # See more details below
|
57
56
|
is_embedded: true, # Set to true if you are building an embedded app
|
58
|
-
is_private: false, # Set to true if you are building a private app
|
59
57
|
api_version: "2022-01" # The version of the API you would like to use
|
58
|
+
is_private: false, # Set to true if you have an existing private app
|
60
59
|
)
|
61
60
|
```
|
62
61
|
|
@@ -68,7 +67,7 @@ Session information would is typically stored in cookies on the browser. However
|
|
68
67
|
|
69
68
|
### Performing OAuth
|
70
69
|
|
71
|
-
|
70
|
+
You need to go through OAuth as described [here](https://shopify.dev/apps/auth/oauth) to create sessions for shops using your app.
|
72
71
|
The Shopify API gem tries to make this easy by providing functions to begin and complete the OAuth process. See the [Oauth doc](docs/usage/oauth.md) for instructions on how to use these.
|
73
72
|
|
74
73
|
### Register Webhooks and a Webhook Handler
|
@@ -83,7 +82,7 @@ Once your app can perform OAuth, it can now make authenticated Shopify API calls
|
|
83
82
|
|
84
83
|
### Breaking change notice for version 10.0.0
|
85
84
|
|
86
|
-
We've rewritten this library for v10, so that it provides all essential features for a Shopify app without
|
85
|
+
We've rewritten this library for v10, so that it provides all essential features for a Shopify app without depending on the [Active Resource](https://github.com/rails/activeresource) or [graphql-client](https://github.com/github/graphql-client) libraries.
|
87
86
|
|
88
87
|
Here are the main features it provides:
|
89
88
|
|
@@ -107,12 +106,12 @@ With this, a lot changed in how apps access the library. Here are the updates yo
|
|
107
106
|
|
108
107
|
Please see below a (non-exhaustive) list of common replacements to guide you in your updates, using the `Order` resource as an example.
|
109
108
|
|
110
|
-
| Before
|
111
|
-
| ---
|
112
|
-
| `Order.find(:all, params: {param1: value1})`
|
113
|
-
| `Order.find(<id>)`
|
114
|
-
| `order = Order.new(<id>)`<br/>`order.post(:close)` | `order = Order.new
|
115
|
-
| `order = Order.new(<id>)`<br/>`order.delete`
|
109
|
+
| Before | After |
|
110
|
+
| --- | --- |
|
111
|
+
| `Order.find(:all, params: {param1: value1})` | `Order.all(param1: value1)` |
|
112
|
+
| `Order.find(<id>)` | `Order.find(id: <id>)` |
|
113
|
+
| `order = Order.new(<id>)`<br/>`order.post(:close)` | `order = Order.new`<br/>`order.close` |
|
114
|
+
| `order = Order.new(<id>)`<br/>`order.delete` | `Order.delete(id: <id>)` |
|
116
115
|
|
117
116
|
## Breaking changes for older versions
|
118
117
|
|
data/docs/getting_started.md
CHANGED
@@ -5,7 +5,7 @@ This page will outline everything you need to know and the steps you need to fol
|
|
5
5
|
## Requirements
|
6
6
|
|
7
7
|
- A working knowledge of ruby and a web framework such as Rails or Sinatra
|
8
|
-
- A
|
8
|
+
- A custom app already set up in your test store or partner account
|
9
9
|
- We recommend `ngrok` to tunnel traffic to your localhost for testing
|
10
10
|
|
11
11
|
## Installation
|
data/docs/usage/oauth.md
CHANGED
@@ -3,8 +3,7 @@
|
|
3
3
|
Once the library is set up for your project, you'll be able to use it to start adding functionality to your app. The first thing your app will need to do is to obtain an access token to the Admin API by performing the OAuth process.
|
4
4
|
|
5
5
|
To do this, you can follow the steps below.
|
6
|
-
|
7
|
-
**Note:** You do not need to go through the OAuth process if you are creating a private app. In this case you can simply set your `<key+password>` as the `api_secret_key` in `ShopifyAPI::Context.setup`. For more information on authenticating a Shopify app please see the [Types of Authentication](https://shopify.dev/apps/auth#types-of-authentication) page.
|
6
|
+
For more information on authenticating a Shopify app please see the [Types of Authentication](https://shopify.dev/apps/auth#types-of-authentication) page.
|
8
7
|
|
9
8
|
## Add a route to start OAuth
|
10
9
|
|
@@ -53,7 +52,7 @@ def callback
|
|
53
52
|
cookies: cookies.to_h,
|
54
53
|
auth_query: ShopifyAPI::Auth::Oauth::AuthQuery.new(request.parameters.symbolize_keys.except(:controller, :action))
|
55
54
|
)
|
56
|
-
|
55
|
+
|
57
56
|
cookies[auth_result[:cookie].name] = {
|
58
57
|
expires: auth_result[:cookie].expires,
|
59
58
|
secure: true,
|
@@ -66,7 +65,7 @@ def callback
|
|
66
65
|
head 307
|
67
66
|
response.set_header("Location", "<some-redirect-url>")
|
68
67
|
rescue => e
|
69
|
-
puts(e.message)
|
68
|
+
puts(e.message)
|
70
69
|
head 500
|
71
70
|
end
|
72
71
|
end
|
@@ -93,10 +93,7 @@ module ShopifyAPI
|
|
93
93
|
)
|
94
94
|
end
|
95
95
|
|
96
|
-
|
97
|
-
raise Errors::SessionStorageError,
|
98
|
-
"Session could not be saved. Please check your session storage implementation."
|
99
|
-
end
|
96
|
+
Context.session_storage&.store_session(session)
|
100
97
|
|
101
98
|
{ session: session, cookie: cookie }
|
102
99
|
end
|
@@ -69,13 +69,13 @@ module ShopifyAPI
|
|
69
69
|
error_message = error_messages.join("\n")
|
70
70
|
|
71
71
|
unless [429, 500].include?(response.code)
|
72
|
-
raise ShopifyAPI::Errors::HttpResponseError.new(
|
72
|
+
raise ShopifyAPI::Errors::HttpResponseError.new(response: response), error_message
|
73
73
|
end
|
74
74
|
|
75
75
|
if tries == request.tries
|
76
|
-
raise ShopifyAPI::Errors::HttpResponseError.new(
|
76
|
+
raise ShopifyAPI::Errors::HttpResponseError.new(response: response), error_message if request.tries == 1
|
77
77
|
|
78
|
-
raise ShopifyAPI::Errors::MaxHttpRetriesExceededError.new(
|
78
|
+
raise ShopifyAPI::Errors::MaxHttpRetriesExceededError.new(response: response),
|
79
79
|
"Exceeded maximum retry count of #{request.tries}. Last message: #{error_message}"
|
80
80
|
end
|
81
81
|
|
data/lib/shopify_api/context.rb
CHANGED
@@ -9,13 +9,14 @@ module ShopifyAPI
|
|
9
9
|
@api_secret_key = T.let("", String)
|
10
10
|
@api_version = T.let(LATEST_SUPPORTED_ADMIN_VERSION, String)
|
11
11
|
@scope = T.let(Auth::AuthScopes.new, Auth::AuthScopes)
|
12
|
-
@session_storage = T.let(ShopifyAPI::Auth::FileSessionStorage.new, ShopifyAPI::Auth::SessionStorage)
|
13
12
|
@is_private = T.let(false, T::Boolean)
|
14
13
|
@private_shop = T.let(nil, T.nilable(String))
|
15
14
|
@is_embedded = T.let(true, T::Boolean)
|
16
|
-
@logger = T.let(Logger.new($stdout), Logger)
|
15
|
+
@logger = T.let(::Logger.new($stdout), ::Logger)
|
16
|
+
@log_level = T.let(:info, Symbol)
|
17
17
|
@notified_missing_resources_folder = T.let({}, T::Hash[String, T::Boolean])
|
18
18
|
@active_session = T.let(Concurrent::ThreadLocalVar.new { nil }, Concurrent::ThreadLocalVar)
|
19
|
+
@session_storage = T.let(nil, T.nilable(ShopifyAPI::Auth::SessionStorage))
|
19
20
|
@user_agent_prefix = T.let(nil, T.nilable(String))
|
20
21
|
@old_api_secret_key = T.let(nil, T.nilable(String))
|
21
22
|
|
@@ -32,8 +33,9 @@ module ShopifyAPI
|
|
32
33
|
scope: T.any(T::Array[String], String),
|
33
34
|
is_private: T::Boolean,
|
34
35
|
is_embedded: T::Boolean,
|
35
|
-
|
36
|
-
logger: Logger,
|
36
|
+
log_level: T.any(String, Symbol),
|
37
|
+
logger: ::Logger,
|
38
|
+
session_storage: T.nilable(ShopifyAPI::Auth::SessionStorage),
|
37
39
|
host_name: T.nilable(String),
|
38
40
|
host: T.nilable(String),
|
39
41
|
private_shop: T.nilable(String),
|
@@ -48,8 +50,9 @@ module ShopifyAPI
|
|
48
50
|
scope:,
|
49
51
|
is_private:,
|
50
52
|
is_embedded:,
|
51
|
-
|
52
|
-
logger: Logger.new($stdout),
|
53
|
+
log_level: :info,
|
54
|
+
logger: ::Logger.new($stdout),
|
55
|
+
session_storage: nil,
|
53
56
|
host_name: nil,
|
54
57
|
host: ENV["HOST"] || "https://#{host_name}",
|
55
58
|
private_shop: nil,
|
@@ -73,6 +76,18 @@ module ShopifyAPI
|
|
73
76
|
@private_shop = private_shop
|
74
77
|
@user_agent_prefix = user_agent_prefix
|
75
78
|
@old_api_secret_key = old_api_secret_key
|
79
|
+
@log_level = if valid_log_level?(log_level)
|
80
|
+
log_level.to_sym
|
81
|
+
else
|
82
|
+
:info
|
83
|
+
end
|
84
|
+
|
85
|
+
if @session_storage
|
86
|
+
::ShopifyAPI::Logger.deprecated("The use of SessionStorage in the API library has been deprecated. " \
|
87
|
+
"The ShopifyAPI will no longer have responsibility for session persistence. " \
|
88
|
+
"Upgrading to `shopify_app` 21.3 will allow you to remove session_storage" \
|
89
|
+
" from the API library Context configuration.", "13.0.0")
|
90
|
+
end
|
76
91
|
|
77
92
|
load_rest_resources(api_version: api_version)
|
78
93
|
end
|
@@ -111,12 +126,15 @@ module ShopifyAPI
|
|
111
126
|
sig { returns(Auth::AuthScopes) }
|
112
127
|
attr_reader :scope
|
113
128
|
|
114
|
-
sig { returns(ShopifyAPI::Auth::SessionStorage) }
|
129
|
+
sig { returns(T.nilable(ShopifyAPI::Auth::SessionStorage)) }
|
115
130
|
attr_reader :session_storage
|
116
131
|
|
117
|
-
sig { returns(Logger) }
|
132
|
+
sig { returns(::Logger) }
|
118
133
|
attr_reader :logger
|
119
134
|
|
135
|
+
sig { returns(Symbol) }
|
136
|
+
attr_reader :log_level
|
137
|
+
|
120
138
|
sig { returns(T::Boolean) }
|
121
139
|
def private?
|
122
140
|
@is_private
|
@@ -161,6 +179,18 @@ module ShopifyAPI
|
|
161
179
|
def host_name
|
162
180
|
T.must(URI(T.must(host)).host)
|
163
181
|
end
|
182
|
+
|
183
|
+
private
|
184
|
+
|
185
|
+
sig { params(log_level: T.any(Symbol, String)).returns(T::Boolean) }
|
186
|
+
def valid_log_level?(log_level)
|
187
|
+
return true if ::ShopifyAPI::Logger.levels.include?(log_level.to_sym)
|
188
|
+
|
189
|
+
ShopifyAPI::Logger.warn("#{log_level} is not a valid log_level. "\
|
190
|
+
"Valid options are #{::ShopifyAPI::Logger.levels.join(", ")}")
|
191
|
+
|
192
|
+
false
|
193
|
+
end
|
164
194
|
end
|
165
195
|
end
|
166
196
|
end
|
@@ -9,10 +9,14 @@ module ShopifyAPI
|
|
9
9
|
sig { returns(Integer) }
|
10
10
|
attr_reader :code
|
11
11
|
|
12
|
-
sig {
|
13
|
-
|
12
|
+
sig { returns(ShopifyAPI::Clients::HttpResponse) }
|
13
|
+
attr_reader :response
|
14
|
+
|
15
|
+
sig { params(response: ShopifyAPI::Clients::HttpResponse).void }
|
16
|
+
def initialize(response:)
|
14
17
|
super
|
15
|
-
@code = code
|
18
|
+
@code = T.let(response.code, Integer)
|
19
|
+
@response = response
|
16
20
|
end
|
17
21
|
end
|
18
22
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module ShopifyAPI
|
5
|
+
class Logger
|
6
|
+
LOG_LEVELS = T.let({ debug: 0, info: 1, warn: 2, error: 3, off: 6 }, T::Hash[Symbol, Integer])
|
7
|
+
DEFAULT_LOG_LEVEL = :info
|
8
|
+
|
9
|
+
class << self
|
10
|
+
extend T::Sig
|
11
|
+
|
12
|
+
sig { params(message: String).void }
|
13
|
+
def debug(message)
|
14
|
+
send_to_logger(:debug, message)
|
15
|
+
end
|
16
|
+
|
17
|
+
sig { params(message: String).void }
|
18
|
+
def info(message)
|
19
|
+
send_to_logger(:info, message)
|
20
|
+
end
|
21
|
+
|
22
|
+
sig { params(message: String).void }
|
23
|
+
def warn(message)
|
24
|
+
send_to_logger(:warn, message)
|
25
|
+
end
|
26
|
+
|
27
|
+
sig { params(message: String).void }
|
28
|
+
def error(message)
|
29
|
+
send_to_logger(:error, message)
|
30
|
+
end
|
31
|
+
|
32
|
+
sig { params(message: String, version: String).void }
|
33
|
+
def deprecated(message, version)
|
34
|
+
return unless enabled_for_log_level?(:warn)
|
35
|
+
|
36
|
+
raise Errors::FeatureDeprecatedError unless valid_version(version)
|
37
|
+
|
38
|
+
send_to_logger(:warn, message)
|
39
|
+
end
|
40
|
+
|
41
|
+
sig { returns(T::Array[Symbol]) }
|
42
|
+
def levels
|
43
|
+
LOG_LEVELS.keys
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
sig { params(log_level: Symbol).returns(String) }
|
49
|
+
def context(log_level)
|
50
|
+
current_shop = ShopifyAPI::Context.active_session&.shop
|
51
|
+
|
52
|
+
if current_shop.nil?
|
53
|
+
"[ ShopifyAPI | #{log_level.to_s.upcase} ]"
|
54
|
+
else
|
55
|
+
"[ ShopifyAPI | #{log_level.to_s.upcase} | #{current_shop} ]"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
sig { params(log_level: Symbol, message: String).void }
|
60
|
+
def send_to_logger(log_level, message)
|
61
|
+
return unless enabled_for_log_level?(log_level)
|
62
|
+
|
63
|
+
full_message = "#{context(log_level)} #{message}"
|
64
|
+
|
65
|
+
ShopifyAPI::Context.logger.public_send(log_level, full_message)
|
66
|
+
end
|
67
|
+
|
68
|
+
sig { params(log_level: Symbol).returns(T::Boolean) }
|
69
|
+
def enabled_for_log_level?(log_level)
|
70
|
+
T.must(LOG_LEVELS[log_level]) >= T.must(LOG_LEVELS[ShopifyAPI::Context.log_level] ||
|
71
|
+
LOG_LEVELS[DEFAULT_LOG_LEVEL])
|
72
|
+
end
|
73
|
+
|
74
|
+
sig { params(version: String).returns(T::Boolean) }
|
75
|
+
def valid_version(version)
|
76
|
+
current_version = Gem::Version.create(ShopifyAPI::VERSION)
|
77
|
+
deprecate_version = Gem::Version.create(version)
|
78
|
+
current_version < deprecate_version
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -17,12 +17,13 @@ module ShopifyAPI
|
|
17
17
|
).returns(T.nilable(Auth::Session))
|
18
18
|
end
|
19
19
|
def load_current_session(auth_header: nil, cookies: nil, is_online: false)
|
20
|
+
validate_session_storage_for_deprecated_utils
|
20
21
|
return load_private_session if Context.private?
|
21
22
|
|
22
23
|
session_id = current_session_id(auth_header, cookies, is_online)
|
23
24
|
return nil unless session_id
|
24
25
|
|
25
|
-
Context.session_storage.load_session(session_id)
|
26
|
+
T.must(Context.session_storage).load_session(session_id)
|
26
27
|
end
|
27
28
|
|
28
29
|
sig do
|
@@ -33,10 +34,12 @@ module ShopifyAPI
|
|
33
34
|
).returns(T::Boolean)
|
34
35
|
end
|
35
36
|
def delete_current_session(auth_header: nil, cookies: nil, is_online: false)
|
37
|
+
validate_session_storage_for_deprecated_utils
|
38
|
+
|
36
39
|
session_id = current_session_id(auth_header, cookies, is_online)
|
37
40
|
return false unless session_id
|
38
41
|
|
39
|
-
Context.session_storage.delete_session(session_id)
|
42
|
+
T.must(Context.session_storage).delete_session(session_id)
|
40
43
|
end
|
41
44
|
|
42
45
|
sig do
|
@@ -46,8 +49,10 @@ module ShopifyAPI
|
|
46
49
|
).returns(T.nilable(Auth::Session))
|
47
50
|
end
|
48
51
|
def load_offline_session(shop:, include_expired: false)
|
52
|
+
validate_session_storage_for_deprecated_utils
|
53
|
+
|
49
54
|
session_id = offline_session_id(shop)
|
50
|
-
session = Context.session_storage.load_session(session_id)
|
55
|
+
session = T.must(Context.session_storage).load_session(session_id)
|
51
56
|
return nil if session && !include_expired && session.expires && T.must(session.expires) < Time.now
|
52
57
|
|
53
58
|
session
|
@@ -59,23 +64,10 @@ module ShopifyAPI
|
|
59
64
|
).returns(T::Boolean)
|
60
65
|
end
|
61
66
|
def delete_offline_session(shop:)
|
62
|
-
|
63
|
-
Context.session_storage.delete_session(session_id)
|
64
|
-
end
|
65
|
-
|
66
|
-
private
|
67
|
+
validate_session_storage_for_deprecated_utils
|
67
68
|
|
68
|
-
|
69
|
-
|
70
|
-
unless Context.private_shop
|
71
|
-
raise Errors::SessionNotFoundError, "Could not load private shop, Context.private_shop is nil."
|
72
|
-
end
|
73
|
-
|
74
|
-
Auth::Session.new(
|
75
|
-
shop: T.must(Context.private_shop),
|
76
|
-
access_token: Context.api_secret_key,
|
77
|
-
scope: Context.scope.to_a,
|
78
|
-
)
|
69
|
+
session_id = offline_session_id(shop)
|
70
|
+
T.must(Context.session_storage).delete_session(session_id)
|
79
71
|
end
|
80
72
|
|
81
73
|
sig do
|
@@ -89,8 +81,10 @@ module ShopifyAPI
|
|
89
81
|
if Context.embedded?
|
90
82
|
if auth_header
|
91
83
|
matches = auth_header.match(/^Bearer (.+)$/)
|
92
|
-
|
93
|
-
"Missing Bearer token in authorization header"
|
84
|
+
unless matches
|
85
|
+
ShopifyAPI::Logger.warn("Missing Bearer token in authorization header")
|
86
|
+
raise Errors::MissingJwtTokenError, "Missing Bearer token in authorization header"
|
87
|
+
end
|
94
88
|
|
95
89
|
jwt_payload = Auth::JwtPayload.new(T.must(matches[1]))
|
96
90
|
shop = jwt_payload.shop
|
@@ -129,6 +123,29 @@ module ShopifyAPI
|
|
129
123
|
def cookie_session_id(cookies)
|
130
124
|
cookies[Auth::Oauth::SessionCookie::SESSION_COOKIE_NAME]
|
131
125
|
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
sig { void }
|
130
|
+
def validate_session_storage_for_deprecated_utils
|
131
|
+
unless Context.session_storage
|
132
|
+
raise ShopifyAPI::Errors::SessionStorageError,
|
133
|
+
"session_storage is required in ShopifyAPI::Context when using deprecated Session utility methods."
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
sig { returns(Auth::Session) }
|
138
|
+
def load_private_session
|
139
|
+
unless Context.private_shop
|
140
|
+
raise Errors::SessionNotFoundError, "Could not load private shop, Context.private_shop is nil."
|
141
|
+
end
|
142
|
+
|
143
|
+
Auth::Session.new(
|
144
|
+
shop: T.must(Context.private_shop),
|
145
|
+
access_token: Context.api_secret_key,
|
146
|
+
scope: Context.scope.to_a,
|
147
|
+
)
|
148
|
+
end
|
132
149
|
end
|
133
150
|
end
|
134
151
|
end
|
data/lib/shopify_api/version.rb
CHANGED
data/shopify_api.gemspec
CHANGED
@@ -32,6 +32,7 @@ Gem::Specification.new do |s|
|
|
32
32
|
|
33
33
|
s.required_ruby_version = ">= 2.6"
|
34
34
|
|
35
|
+
s.add_runtime_dependency("activesupport")
|
35
36
|
s.add_runtime_dependency("concurrent-ruby")
|
36
37
|
s.add_runtime_dependency("hash_diff")
|
37
38
|
s.add_runtime_dependency("httparty")
|
@@ -40,9 +41,8 @@ Gem::Specification.new do |s|
|
|
40
41
|
s.add_runtime_dependency("openssl")
|
41
42
|
s.add_runtime_dependency("securerandom")
|
42
43
|
s.add_runtime_dependency("sorbet-runtime")
|
43
|
-
s.add_runtime_dependency("zeitwerk", "~> 2.5")
|
44
|
+
s.add_runtime_dependency("zeitwerk", "~> 2.5", "< 2.6.5") # https://github.com/Shopify/shopify-api-ruby/issues/1058
|
44
45
|
|
45
|
-
s.add_development_dependency("activesupport")
|
46
46
|
s.add_development_dependency("pry-byebug")
|
47
47
|
s.add_development_dependency("rake")
|
48
48
|
s.add_development_dependency("rubocop")
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shopify_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 12.
|
4
|
+
version: 12.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
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'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: concurrent-ruby
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -129,6 +143,9 @@ dependencies:
|
|
129
143
|
- - "~>"
|
130
144
|
- !ruby/object:Gem::Version
|
131
145
|
version: '2.5'
|
146
|
+
- - "<"
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: 2.6.5
|
132
149
|
type: :runtime
|
133
150
|
prerelease: false
|
134
151
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -136,20 +153,9 @@ dependencies:
|
|
136
153
|
- - "~>"
|
137
154
|
- !ruby/object:Gem::Version
|
138
155
|
version: '2.5'
|
139
|
-
-
|
140
|
-
name: activesupport
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - ">="
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: '0'
|
146
|
-
type: :development
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - ">="
|
156
|
+
- - "<"
|
151
157
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
158
|
+
version: 2.6.5
|
153
159
|
- !ruby/object:Gem::Dependency
|
154
160
|
name: pry-byebug
|
155
161
|
requirement: !ruby/object:Gem::Requirement
|
@@ -325,6 +331,7 @@ files:
|
|
325
331
|
- lib/shopify_api/context.rb
|
326
332
|
- lib/shopify_api/errors/context_not_setup_error.rb
|
327
333
|
- lib/shopify_api/errors/cookie_not_found_error.rb
|
334
|
+
- lib/shopify_api/errors/feature_deprecated_error.rb
|
328
335
|
- lib/shopify_api/errors/http_response_error.rb
|
329
336
|
- lib/shopify_api/errors/invalid_graphql_request_error.rb
|
330
337
|
- lib/shopify_api/errors/invalid_http_request_error.rb
|
@@ -332,6 +339,7 @@ files:
|
|
332
339
|
- lib/shopify_api/errors/invalid_oauth_error.rb
|
333
340
|
- lib/shopify_api/errors/invalid_webhook_error.rb
|
334
341
|
- lib/shopify_api/errors/invalid_webhook_registration_error.rb
|
342
|
+
- lib/shopify_api/errors/log_level_not_found_error.rb
|
335
343
|
- lib/shopify_api/errors/max_http_retries_exceeded_error.rb
|
336
344
|
- lib/shopify_api/errors/missing_jwt_token_error.rb
|
337
345
|
- lib/shopify_api/errors/missing_required_argument_error.rb
|
@@ -346,6 +354,7 @@ files:
|
|
346
354
|
- lib/shopify_api/errors/unsupported_version_error.rb
|
347
355
|
- lib/shopify_api/errors/webhook_registration_error.rb
|
348
356
|
- lib/shopify_api/inflector.rb
|
357
|
+
- lib/shopify_api/logger.rb
|
349
358
|
- lib/shopify_api/rest/base.rb
|
350
359
|
- lib/shopify_api/rest/base_errors.rb
|
351
360
|
- lib/shopify_api/rest/resources/2022_01/abandoned_checkout.rb
|