shopify_app 13.1.1 → 13.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0aa049c80b093fe0a9467aff641dacca475d2e752a852a980da05b7b64b764a3
4
- data.tar.gz: c041d5de39c2c62026b5748d391592c74d4847c9ad00691282a66a6da7cd1fa8
3
+ metadata.gz: 342e069a4f4d0d9bd824403f44cbcf25e398c8e869b4c31058199c7a13daca19
4
+ data.tar.gz: cebba3a407077d4dd86183b6aa4fe702593cfacb5de7f630305fefb7bf0ed545
5
5
  SHA512:
6
- metadata.gz: ce925fec4a16a886424e0c4233f9be474f1166ff9e2cf4fe4463825a633a373f4bac82041cab051f37d4afbf227d5ae89189fc28a104eeb035ce856576a27203
7
- data.tar.gz: 23f6483d6cf1b4767ea6c66b8178c0d5458c3c40abb968d6cca22f0adbf27250257b39e20c9d87a140e562a249006f11137c93737c4e0e6e4b3b101fc93a2932
6
+ metadata.gz: 3d7e6c9dc9a521fe022f91e3c2761ff451a34fb67a61ebe3ac5888e5a19924d8eea912a9d644c4255ab0570c959ee8f56f6b30b98809b9d6bb9e09323f7bfec3
7
+ data.tar.gz: 67ed9dbc2897dce008f35c760251d64c708319a2171617692caedf01026b8366dd5f3ac9609d23c2ee8d196d2b90a34adce2bcf2974e7541bfa24a74a06c303b
@@ -1,3 +1,9 @@
1
+ 13.2.0
2
+ ------
3
+ * Get current shop domain from JWT header
4
+ * Validate that the omniauth data matches the JWT data
5
+ * Persist the token information to the session store
6
+
1
7
  13.1.1
2
8
  ------
3
9
  * Update browser_sniffer to 1.2.2
@@ -6,10 +6,22 @@ module ShopifyApp
6
6
  include ShopifyApp::LoginProtection
7
7
 
8
8
  def callback
9
- if auth_hash
10
- login_shop
9
+ unless auth_hash
10
+ return respond_with_error
11
+ end
12
+
13
+ if jwt_request? && !valid_jwt_auth?
14
+ return respond_with_error
15
+ end
16
+
17
+ if jwt_request?
18
+ set_shopify_session
19
+ head(:ok)
20
+ else
21
+ reset_session_options
22
+ set_shopify_session
11
23
 
12
- if ShopifyApp::SessionRepository.user_storage.present? && user_session.blank?
24
+ if redirect_for_user_token?
13
25
  return redirect_to(login_url_with_optional_shop)
14
26
  end
15
27
 
@@ -18,17 +30,30 @@ module ShopifyApp
18
30
  perform_after_authenticate_job
19
31
 
20
32
  redirect_to(return_address)
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def respond_with_error
39
+ if jwt_request?
40
+ head(:unauthorized)
21
41
  else
22
42
  flash[:error] = I18n.t('could_not_log_in')
23
43
  redirect_to(login_url_with_optional_shop)
24
44
  end
25
45
  end
26
46
 
27
- private
47
+ def redirect_for_user_token?
48
+ ShopifyApp::SessionRepository.user_storage.present? && user_session.blank?
49
+ end
28
50
 
29
- def login_shop
30
- reset_session_options
31
- set_shopify_session
51
+ def jwt_request?
52
+ jwt_shopify_domain || jwt_shopify_user_id
53
+ end
54
+
55
+ def valid_jwt_auth?
56
+ auth_hash && jwt_shopify_domain == shop_name && jwt_shopify_user_id == associated_user_id
32
57
  end
33
58
 
34
59
  def auth_hash
@@ -45,6 +70,10 @@ module ShopifyApp
45
70
  auth_hash['extra']['associated_user']
46
71
  end
47
72
 
73
+ def associated_user_id
74
+ associated_user && associated_user['id']
75
+ end
76
+
48
77
  def token
49
78
  auth_hash['credentials']['token']
50
79
  end
@@ -125,7 +125,7 @@ module ShopifyApp
125
125
  end
126
126
 
127
127
  def copy_return_to_param_to_session
128
- session[:return_to] = params[:return_to] if params[:return_to]
128
+ session[:return_to] = RedirectSafely.make_safe(params[:return_to], '/') if params[:return_to]
129
129
  end
130
130
 
131
131
  def render_invalid_shop_error
@@ -9,7 +9,7 @@ module ShopifyApp
9
9
  params.permit!
10
10
  job_args = { shop_domain: shop_domain, webhook: webhook_params.to_h }
11
11
  webhook_job_klass.perform_later(job_args)
12
- head(:no_content)
12
+ head(:ok)
13
13
  end
14
14
 
15
15
  private
@@ -3,6 +3,7 @@ Releasing ShopifyApp
3
3
  1. Check the Semantic Versioning page for info on how to version the new release: http://semver.org
4
4
  2. Create a pull request with the following changes:
5
5
  * Update the version of ShopifyApp in lib/shopify_app/version.rb
6
+ * Update the version of shopify_app in package.json
6
7
  * Add a CHANGELOG entry for the new release with the date
7
8
  * Change the title of the PR to something like: "Packaging for release X.Y.Z"
8
9
  3. Merge your pull request
@@ -8,7 +8,7 @@ ShopifyApp.configure do |config|
8
8
  config.embedded_app = <%= embedded_app? %>
9
9
  config.after_authenticate_job = false
10
10
  config.api_version = "<%= @api_version %>"
11
- config.shop_session_repository = 'ShopifyApp::InMemoryShopSessionStore'
11
+ config.shop_session_repository = 'Shop'
12
12
  end
13
13
 
14
14
  # ShopifyApp::Utils.fetch_known_api_versions # Uncomment to fetch known api versions from shopify servers on boot
@@ -4,6 +4,7 @@ require 'shopify_app/version'
4
4
  # deps
5
5
  require 'shopify_api'
6
6
  require 'omniauth-shopify-oauth2'
7
+ require 'redirect_safely'
7
8
 
8
9
  module ShopifyApp
9
10
  def self.rails6?
@@ -42,6 +43,7 @@ module ShopifyApp
42
43
  require 'shopify_app/managers/scripttags_manager'
43
44
 
44
45
  # middleware
46
+ require 'shopify_app/middleware/jwt_middleware'
45
47
  require 'shopify_app/middleware/same_site_cookie_middleware'
46
48
 
47
49
  # session
@@ -83,17 +83,11 @@ module ShopifyApp
83
83
  protected
84
84
 
85
85
  def jwt_shopify_domain
86
- return unless jwt
87
- @jwt_shopify_domain ||= JWT.new(jwt).shopify_domain
86
+ request.env['jwt.shopify_domain']
88
87
  end
89
88
 
90
89
  def jwt_shopify_user_id
91
- return unless jwt
92
- @jwt_user_id ||= JWT.new(jwt).shopify_user_id
93
- end
94
-
95
- def jwt
96
- @jwt ||= authenticate_with_http_token { |token| token }
90
+ request.env['jwt.shopify_user_id']
97
91
  end
98
92
 
99
93
  def redirect_to_login
@@ -139,7 +133,7 @@ module ShopifyApp
139
133
  query_params = {}
140
134
  query_params[:shop] = sanitized_params[:shop] if params[:shop].present?
141
135
 
142
- return_to = session[:return_to] || params[:return_to]
136
+ return_to = RedirectSafely.make_safe(session[:return_to] || params[:return_to], nil)
143
137
 
144
138
  if return_to.present? && return_to_param_required?
145
139
  query_params[:return_to] = return_to
@@ -170,7 +164,10 @@ module ShopifyApp
170
164
  end
171
165
 
172
166
  def current_shopify_domain
173
- shopify_domain = sanitized_shop_name || session[:shopify_domain]
167
+ shopify_domain = sanitized_shop_name ||
168
+ jwt_shopify_domain ||
169
+ session[:shopify_domain]
170
+
174
171
  return shopify_domain if shopify_domain.present?
175
172
 
176
173
  raise ShopifyDomainNotFound
@@ -16,6 +16,10 @@ module ShopifyApp
16
16
 
17
17
  initializer "shopify_app.middleware" do |app|
18
18
  app.config.middleware.insert_after(::Rack::Runtime, ShopifyApp::SameSiteCookieMiddleware)
19
+
20
+ if ShopifyApp.configuration.allow_jwt_authentication
21
+ app.config.middleware.insert_after(ShopifyApp::SameSiteCookieMiddleware, ShopifyApp::JWTMiddleware)
22
+ end
19
23
  end
20
24
  end
21
25
  end
@@ -0,0 +1,41 @@
1
+ module ShopifyApp
2
+ class JWTMiddleware
3
+ TOKEN_REGEX = /^Bearer\s+(.*?)$/
4
+
5
+ def initialize(app)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ return call_next(env) unless authorization_header(env)
11
+
12
+ token = extract_token(env)
13
+ return call_next(env) unless token
14
+
15
+ set_env_variables(token, env)
16
+ call_next(env)
17
+ end
18
+
19
+ private
20
+
21
+ def call_next(env)
22
+ @app.call(env)
23
+ end
24
+
25
+ def authorization_header(env)
26
+ env['HTTP_AUTHORIZATION']
27
+ end
28
+
29
+ def extract_token(env)
30
+ match = authorization_header(env).match(TOKEN_REGEX)
31
+ match && match[1]
32
+ end
33
+
34
+ def set_env_variables(token, env)
35
+ jwt = ShopifyApp::JWT.new(token)
36
+
37
+ env['jwt.shopify_domain'] = jwt.shopify_domain
38
+ env['jwt.shopify_user_id'] = jwt.shopify_user_id
39
+ end
40
+ end
41
+ end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module ShopifyApp
3
- VERSION = '13.1.1'
3
+ VERSION = '13.2.0'
4
4
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shopify_app",
3
- "version": "13.1.1",
3
+ "version": "13.2.0",
4
4
  "repository": "git@github.com:Shopify/shopify_app.git",
5
5
  "author": "Shopify",
6
6
  "license": "MIT",
@@ -15,9 +15,10 @@ Gem::Specification.new do |s|
15
15
 
16
16
  s.add_runtime_dependency('browser_sniffer', '~> 1.2.2')
17
17
  s.add_runtime_dependency('rails', '> 5.2.1')
18
- s.add_runtime_dependency('shopify_api', '~> 9.0.2')
18
+ s.add_runtime_dependency('shopify_api', '~> 9.1.0')
19
19
  s.add_runtime_dependency('omniauth-shopify-oauth2', '~> 2.2.2')
20
20
  s.add_runtime_dependency('jwt', '~> 2.2.1')
21
+ s.add_runtime_dependency('redirect_safely', '~> 1.0')
21
22
 
22
23
  s.add_development_dependency('rake')
23
24
  s.add_development_dependency('byebug')
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: 13.1.1
4
+ version: 13.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-06 00:00:00.000000000 Z
11
+ date: 2020-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: browser_sniffer
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 9.0.2
47
+ version: 9.1.0
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: 9.0.2
54
+ version: 9.1.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: omniauth-shopify-oauth2
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 2.2.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: redirect_safely
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rake
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -351,6 +365,7 @@ files:
351
365
  - lib/shopify_app/jobs/webhooks_manager_job.rb
352
366
  - lib/shopify_app/managers/scripttags_manager.rb
353
367
  - lib/shopify_app/managers/webhooks_manager.rb
368
+ - lib/shopify_app/middleware/jwt_middleware.rb
354
369
  - lib/shopify_app/middleware/same_site_cookie_middleware.rb
355
370
  - lib/shopify_app/session/in_memory_session_store.rb
356
371
  - lib/shopify_app/session/in_memory_shop_session_store.rb