shopify_app 12.0.1 → 12.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/README.md +23 -1
- data/app/controllers/shopify_app/sessions_controller.rb +16 -5
- data/lib/shopify_app/configuration.rb +7 -1
- data/lib/shopify_app/controller_concerns/login_protection.rb +10 -0
- data/lib/shopify_app/engine.rb +1 -1
- data/lib/shopify_app/middleware/same_site_cookie_middleware.rb +18 -45
- data/lib/shopify_app/version.rb +1 -1
- data/package.json +1 -1
- data/shopify_app.gemspec +3 -3
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4d5e8bb7adf27bed02320b5bac90179d8c2d59f6720d45af3e58f7860cbf0e58
|
4
|
+
data.tar.gz: 1640997a65a723a5a0d892c2fe736493e978c12f0bc66a506bd4680e5f5dd2db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: febaa42018e4dffcc2c93f28a9c1ed19cb3e33a1ca525067e96f3de1f577179db83d32a082107966f487b5c55b212e48a0c44b6996e5fea5c4ae19736244650c
|
7
|
+
data.tar.gz: e4217c593b8c7f7425a94da13c3a74c80ab91ec783df9ec361285bddea3cf2622e29a4e44d2065d7a45b6fe0c94a790c358cfe3f311b2686d050c36bfae30b46
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
12.0.6
|
2
|
+
------
|
3
|
+
* Adds changelog information and README updates for 8.4.0 #916
|
4
|
+
|
5
|
+
12.0.5
|
6
|
+
------
|
7
|
+
* Updating shopify_api gem to 9.0.1
|
8
|
+
|
9
|
+
12.0.4
|
10
|
+
------
|
11
|
+
* Reverts reverted PR (#895) #897
|
12
|
+
|
13
|
+
12.0.3
|
14
|
+
------
|
15
|
+
* Moves samesite middleware higher in the stack #898
|
16
|
+
* Fix issue where not redirecting user to granted storage page casues infinite loop #900
|
17
|
+
|
18
|
+
12.0.2
|
19
|
+
------
|
20
|
+
* Reverts "Fix for return_to in safari after enable_cookies/granted_storage_access" introduced in 12.0.1
|
21
|
+
|
1
22
|
12.0.1
|
2
23
|
------
|
3
24
|
* disable samesite cookie middleware in tests
|
@@ -174,6 +195,7 @@ Added support for rotating Shopify access tokens:
|
|
174
195
|
8.4.0
|
175
196
|
----
|
176
197
|
* Fix embedded app session management in Safari 12.1
|
198
|
+
* Note that with this change we have extracted the callback action in its own controller. If you are relying on it, see the README for more details: https://github.com/Shopify/shopify_app#callback
|
177
199
|
* Shop names passed to OAuth are no longer case sensitive
|
178
200
|
|
179
201
|
8.3.2
|
data/README.md
CHANGED
@@ -91,7 +91,9 @@ SHOPIFY_API_KEY=your api key
|
|
91
91
|
SHOPIFY_API_SECRET=your api secret
|
92
92
|
```
|
93
93
|
|
94
|
-
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.
|
94
|
+
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.
|
95
|
+
|
96
|
+
**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.**
|
95
97
|
|
96
98
|
### Install Generator
|
97
99
|
|
@@ -211,6 +213,17 @@ end
|
|
211
213
|
Authentication
|
212
214
|
--------------
|
213
215
|
|
216
|
+
### Callback
|
217
|
+
|
218
|
+
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:
|
219
|
+
* Logging into the shop and resetting the session
|
220
|
+
* [Installing Webhooks](https://github.com/Shopify/shopify_app#webhooksmanager)
|
221
|
+
* [Setting Scripttags](https://github.com/Shopify/shopify_app#scripttagsmanager)
|
222
|
+
* [Performing the AfterAuthenticate Job](https://github.com/Shopify/shopify_app#afterauthenticatejob)
|
223
|
+
* Redirecting to the return address
|
224
|
+
|
225
|
+
**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.**
|
226
|
+
|
214
227
|
### ShopifyApp::SessionRepository
|
215
228
|
|
216
229
|
`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.
|
@@ -287,6 +300,14 @@ bin/rails g shopify_app:add_after_authenticate_job
|
|
287
300
|
|
288
301
|
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.
|
289
302
|
|
303
|
+
API Versioning
|
304
|
+
--------------
|
305
|
+
|
306
|
+
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).
|
307
|
+
|
308
|
+
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).
|
309
|
+
|
310
|
+
See the [shopify_api gem README](https://github.com/Shopify/shopify_api/) for more details.
|
290
311
|
|
291
312
|
WebhooksManager
|
292
313
|
---------------
|
@@ -463,6 +484,7 @@ Questions or problems?
|
|
463
484
|
|
464
485
|
- [Ask questions!](https://ecommerce.shopify.com/c/shopify-apis-and-technology)
|
465
486
|
- [Read the docs!](https://help.shopify.com/api/guides)
|
487
|
+
- And don't forget to check the [Changelog](https://github.com/Shopify/shopify_app/blob/master/CHANGELOG.md) too!
|
466
488
|
|
467
489
|
Upgrading to 11.7.0
|
468
490
|
---------------------------
|
@@ -24,7 +24,10 @@ module ShopifyApp
|
|
24
24
|
return_to: params[:return_to]
|
25
25
|
),
|
26
26
|
has_storage_access_url: login_url_with_optional_shop(top_level: true),
|
27
|
-
app_target_url:
|
27
|
+
app_target_url: granted_storage_access_path(
|
28
|
+
shop: sanitized_shop_name,
|
29
|
+
return_to: params[:return_to]
|
30
|
+
),
|
28
31
|
current_shopify_domain: current_shopify_domain
|
29
32
|
})
|
30
33
|
end
|
@@ -39,8 +42,9 @@ module ShopifyApp
|
|
39
42
|
|
40
43
|
session['shopify.granted_storage_access'] = true
|
41
44
|
|
42
|
-
|
43
|
-
|
45
|
+
copy_return_to_param_to_session
|
46
|
+
|
47
|
+
redirect_to(return_address_with_params({ shop: @shop }))
|
44
48
|
end
|
45
49
|
|
46
50
|
def destroy
|
@@ -55,7 +59,7 @@ module ShopifyApp
|
|
55
59
|
return render_invalid_shop_error unless sanitized_shop_name.present?
|
56
60
|
session['shopify.omniauth_params'] = { shop: sanitized_shop_name }
|
57
61
|
|
58
|
-
|
62
|
+
copy_return_to_param_to_session
|
59
63
|
|
60
64
|
if user_agent_can_partition_cookies
|
61
65
|
authenticate_with_partitioning
|
@@ -94,6 +98,10 @@ module ShopifyApp
|
|
94
98
|
true
|
95
99
|
end
|
96
100
|
|
101
|
+
def copy_return_to_param_to_session
|
102
|
+
session[:return_to] = params[:return_to] if params[:return_to]
|
103
|
+
end
|
104
|
+
|
97
105
|
def render_invalid_shop_error
|
98
106
|
flash[:error] = I18n.t('invalid_shop_url')
|
99
107
|
redirect_to return_address
|
@@ -138,7 +146,10 @@ module ShopifyApp
|
|
138
146
|
return_to: session[:return_to]
|
139
147
|
),
|
140
148
|
has_storage_access_url: login_url_with_optional_shop(top_level: true),
|
141
|
-
app_target_url:
|
149
|
+
app_target_url: granted_storage_access_path(
|
150
|
+
shop: sanitized_shop_name,
|
151
|
+
return_to: session[:return_to]
|
152
|
+
),
|
142
153
|
current_shopify_domain: current_shopify_domain
|
143
154
|
}
|
144
155
|
)
|
@@ -5,7 +5,7 @@ module ShopifyApp
|
|
5
5
|
# for the app in your Shopify Partners page. Change your settings in
|
6
6
|
# `config/initializers/shopify_app.rb`
|
7
7
|
attr_accessor :application_name
|
8
|
-
|
8
|
+
attr_reader :api_key
|
9
9
|
attr_accessor :secret
|
10
10
|
attr_accessor :old_secret
|
11
11
|
attr_accessor :scope
|
@@ -65,6 +65,12 @@ module ShopifyApp
|
|
65
65
|
scripttags.present?
|
66
66
|
end
|
67
67
|
|
68
|
+
def api_key=(key)
|
69
|
+
raise 'API Key is required and is being returned nil. \
|
70
|
+
This may indicate that your enviroment variables have not been loaded.' if key.nil?
|
71
|
+
@api_key = key
|
72
|
+
end
|
73
|
+
|
68
74
|
def enable_same_site_none
|
69
75
|
!Rails.env.test? && (@enable_same_site_none.nil? ? embedded_app? : @enable_same_site_none)
|
70
76
|
end
|
@@ -167,5 +167,15 @@ module ShopifyApp
|
|
167
167
|
def return_address
|
168
168
|
session.delete(:return_to) || ShopifyApp.configuration.root_url
|
169
169
|
end
|
170
|
+
|
171
|
+
def return_address_with_params(params)
|
172
|
+
uri = URI(return_address)
|
173
|
+
uri.query = CGI.parse(uri.query.to_s)
|
174
|
+
.symbolize_keys
|
175
|
+
.transform_values { |v| v.one? ? v.first : v }
|
176
|
+
.merge(params)
|
177
|
+
.to_query
|
178
|
+
uri.to_s
|
179
|
+
end
|
170
180
|
end
|
171
181
|
end
|
data/lib/shopify_app/engine.rb
CHANGED
@@ -14,7 +14,7 @@ module ShopifyApp
|
|
14
14
|
end
|
15
15
|
|
16
16
|
initializer "shopify_app.middleware" do |app|
|
17
|
-
app.config.middleware.
|
17
|
+
app.config.middleware.insert_after(::Rack::Runtime, ShopifyApp::SameSiteCookieMiddleware)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -1,60 +1,33 @@
|
|
1
1
|
module ShopifyApp
|
2
2
|
class SameSiteCookieMiddleware
|
3
|
+
COOKIE_SEPARATOR = "\n"
|
4
|
+
|
3
5
|
def initialize(app)
|
4
6
|
@app = app
|
5
7
|
end
|
6
8
|
|
7
9
|
def call(env)
|
8
|
-
|
9
|
-
ensure
|
10
|
+
status, headers, body = @app.call(env)
|
10
11
|
user_agent = env['HTTP_USER_AGENT']
|
11
12
|
|
12
|
-
if headers && headers['Set-Cookie'] &&
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
if headers && headers['Set-Cookie'] &&
|
14
|
+
BrowserSniffer.new(user_agent).same_site_none_compatible? &&
|
15
|
+
ShopifyApp.configuration.enable_same_site_none &&
|
16
|
+
Rack::Request.new(env).ssl?
|
17
|
+
|
18
|
+
set_cookies = headers['Set-Cookie']
|
19
|
+
.split(COOKIE_SEPARATOR)
|
20
|
+
.compact
|
21
|
+
.map do |cookie|
|
22
|
+
cookie << '; Secure' if not cookie =~ /;\s*secure/i
|
23
|
+
cookie << '; SameSite=None' unless cookie =~ /;\s*samesite=/i
|
24
|
+
cookie
|
20
25
|
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
webkit_same_site_bug?(sniffer) || drops_unrecognized_same_site_cookies?(sniffer)
|
29
|
-
rescue
|
30
|
-
true
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.webkit_same_site_bug?(sniffer)
|
34
|
-
(sniffer.os == :ios && sniffer.os_version.match(/^([0-9]|1[12])[\.\_]/)) ||
|
35
|
-
(sniffer.os == :mac && sniffer.browser == :safari && sniffer.os_version.match(/^10[\.\_]14/))
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.drops_unrecognized_same_site_cookies?(sniffer)
|
39
|
-
(chromium_based?(sniffer) && sniffer.major_browser_version >= 51 && sniffer.major_browser_version <= 66) ||
|
40
|
-
(uc_browser?(sniffer) && !uc_browser_version_at_least?(sniffer: sniffer, major: 12, minor: 13, build: 2))
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.chromium_based?(sniffer)
|
44
|
-
sniffer.browser_name.downcase.match(/chrom(e|ium)/)
|
45
|
-
end
|
46
|
-
|
47
|
-
def self.uc_browser?(sniffer)
|
48
|
-
sniffer.user_agent.downcase.match(/uc\s?browser/)
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.uc_browser_version_at_least?(sniffer:, major:, minor:, build:)
|
52
|
-
digits = sniffer.browser_version.split('.').map(&:to_i)
|
53
|
-
return false unless digits.count >= 3
|
27
|
+
headers['Set-Cookie'] = set_cookies.join(COOKIE_SEPARATOR)
|
28
|
+
end
|
54
29
|
|
55
|
-
|
56
|
-
return digits[1] > minor if digits[1] != minor
|
57
|
-
digits[2] >= build
|
30
|
+
[status, headers, body]
|
58
31
|
end
|
59
32
|
end
|
60
33
|
end
|
data/lib/shopify_app/version.rb
CHANGED
data/package.json
CHANGED
data/shopify_app.gemspec
CHANGED
@@ -10,9 +10,9 @@ Gem::Specification.new do |s|
|
|
10
10
|
|
11
11
|
s.required_ruby_version = ">= 2.3.1"
|
12
12
|
|
13
|
-
s.add_runtime_dependency('browser_sniffer', '~> 1.
|
13
|
+
s.add_runtime_dependency('browser_sniffer', '~> 1.2.0')
|
14
14
|
s.add_runtime_dependency('rails', '> 5.2.1')
|
15
|
-
s.add_runtime_dependency('shopify_api', '~> 9.0')
|
15
|
+
s.add_runtime_dependency('shopify_api', '~> 9.0.1')
|
16
16
|
s.add_runtime_dependency('omniauth-shopify-oauth2', '~> 2.2.0')
|
17
17
|
|
18
18
|
s.add_development_dependency('rake')
|
@@ -29,4 +29,4 @@ Gem::Specification.new do |s|
|
|
29
29
|
s.files = `git ls-files`.split("\n").reject { |f| f.match(%r{^(test|example)/}) }
|
30
30
|
s.test_files = `git ls-files -- {test}/*`.split("\n")
|
31
31
|
s.require_paths = ["lib"]
|
32
|
-
end
|
32
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shopify_app
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 12.0.
|
4
|
+
version: 12.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: browser_sniffer
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.2.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: 1.2.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rails
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 9.0.1
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 9.0.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: omniauth-shopify-oauth2
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|