shopify_app 13.0.0 → 13.3.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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rubocop.yml +28 -0
  3. data/.rubocop.yml +13 -6
  4. data/.travis.yml +4 -3
  5. data/CHANGELOG.md +33 -0
  6. data/Gemfile +5 -0
  7. data/README.md +67 -38
  8. data/Rakefile +1 -0
  9. data/SECURITY.md +59 -0
  10. data/app/controllers/concerns/shopify_app/require_known_shop.rb +39 -0
  11. data/app/controllers/shopify_app/authenticated_controller.rb +1 -0
  12. data/app/controllers/shopify_app/callback_controller.rb +39 -8
  13. data/app/controllers/shopify_app/extension_verification_controller.rb +2 -7
  14. data/app/controllers/shopify_app/sessions_controller.rb +9 -6
  15. data/app/controllers/shopify_app/webhooks_controller.rb +6 -5
  16. data/config/locales/fi.yml +1 -1
  17. data/config/locales/nl.yml +7 -7
  18. data/config/routes.rb +1 -0
  19. data/docs/Quickstart.md +5 -14
  20. data/docs/Releasing.md +1 -0
  21. data/lib/generators/shopify_app/add_after_authenticate_job/add_after_authenticate_job_generator.rb +5 -3
  22. data/lib/generators/shopify_app/add_after_authenticate_job/templates/after_authenticate_job.rb +1 -0
  23. data/lib/generators/shopify_app/add_marketing_activity_extension/add_marketing_activity_extension_generator.rb +2 -1
  24. data/lib/generators/shopify_app/add_marketing_activity_extension/templates/marketing_activities_controller.rb +4 -4
  25. data/lib/generators/shopify_app/add_webhook/add_webhook_generator.rb +5 -4
  26. data/lib/generators/shopify_app/add_webhook/templates/{webhook_job.rb → webhook_job.rb.tt} +5 -0
  27. data/lib/generators/shopify_app/app_proxy_controller/app_proxy_controller_generator.rb +4 -3
  28. data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_controller.rb +3 -3
  29. data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_route.rb +10 -9
  30. data/lib/generators/shopify_app/controllers/controllers_generator.rb +1 -0
  31. data/lib/generators/shopify_app/home_controller/home_controller_generator.rb +4 -3
  32. data/lib/generators/shopify_app/install/install_generator.rb +10 -9
  33. data/lib/generators/shopify_app/install/templates/omniauth.rb +2 -1
  34. data/lib/generators/shopify_app/install/templates/{shopify_app.rb → shopify_app.rb.tt} +1 -1
  35. data/lib/generators/shopify_app/install/templates/user_agent.rb +2 -1
  36. data/lib/generators/shopify_app/routes/routes_generator.rb +1 -0
  37. data/lib/generators/shopify_app/routes/templates/routes.rb +10 -9
  38. data/lib/generators/shopify_app/shop_model/shop_model_generator.rb +12 -7
  39. data/lib/generators/shopify_app/shop_model/templates/shop.rb +1 -0
  40. data/lib/generators/shopify_app/shopify_app_generator.rb +4 -3
  41. data/lib/generators/shopify_app/user_model/templates/user.rb +1 -0
  42. data/lib/generators/shopify_app/user_model/user_model_generator.rb +12 -7
  43. data/lib/generators/shopify_app/views/views_generator.rb +1 -0
  44. data/lib/shopify_app.rb +11 -5
  45. data/lib/shopify_app/configuration.rb +15 -8
  46. data/lib/shopify_app/controller_concerns/app_proxy_verification.rb +3 -3
  47. data/lib/shopify_app/controller_concerns/embedded_app.rb +3 -2
  48. data/lib/shopify_app/controller_concerns/localization.rb +1 -0
  49. data/lib/shopify_app/controller_concerns/login_protection.rb +52 -15
  50. data/lib/shopify_app/controller_concerns/payload_verification.rb +24 -0
  51. data/lib/shopify_app/controller_concerns/webhook_verification.rb +3 -18
  52. data/lib/shopify_app/engine.rb +5 -0
  53. data/lib/shopify_app/jobs/scripttags_manager_job.rb +1 -1
  54. data/lib/shopify_app/jobs/webhooks_manager_job.rb +1 -1
  55. data/lib/shopify_app/managers/scripttags_manager.rb +4 -3
  56. data/lib/shopify_app/managers/webhooks_manager.rb +4 -3
  57. data/lib/shopify_app/middleware/jwt_middleware.rb +42 -0
  58. data/lib/shopify_app/middleware/same_site_cookie_middleware.rb +2 -1
  59. data/lib/shopify_app/session/in_memory_session_store.rb +7 -3
  60. data/lib/shopify_app/session/in_memory_shop_session_store.rb +10 -0
  61. data/lib/shopify_app/session/in_memory_user_session_store.rb +10 -0
  62. data/lib/shopify_app/session/jwt.rb +61 -0
  63. data/lib/shopify_app/session/null_user_session_store.rb +22 -0
  64. data/lib/shopify_app/session/session_repository.rb +13 -16
  65. data/lib/shopify_app/session/session_storage.rb +1 -0
  66. data/lib/shopify_app/session/shop_session_storage.rb +21 -9
  67. data/lib/shopify_app/session/user_session_storage.rb +19 -8
  68. data/lib/shopify_app/test_helpers/all.rb +2 -0
  69. data/lib/shopify_app/test_helpers/webhook_verification_helper.rb +17 -0
  70. data/lib/shopify_app/utils.rb +6 -5
  71. data/lib/shopify_app/version.rb +2 -1
  72. data/package-lock.json +4 -4
  73. data/package.json +1 -1
  74. data/shopify_app.gemspec +12 -7
  75. data/yarn.lock +3 -3
  76. metadata +48 -10
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+ module ShopifyApp
3
+ class JWT
4
+ class InvalidDestinationError < StandardError; end
5
+ class MismatchedHostsError < StandardError; end
6
+ class InvalidAudienceError < StandardError; end
7
+
8
+ WARN_EXCEPTIONS = [
9
+ ::JWT::DecodeError,
10
+ ::JWT::ExpiredSignature,
11
+ ::JWT::ImmatureSignature,
12
+ ::JWT::VerificationError,
13
+ InvalidAudienceError,
14
+ InvalidDestinationError,
15
+ MismatchedHostsError,
16
+ ]
17
+
18
+ def initialize(token)
19
+ @token = token
20
+ set_payload
21
+ end
22
+
23
+ def shopify_domain
24
+ @payload && ShopifyApp::Utils.sanitize_shop_domain(@payload['dest'])
25
+ end
26
+
27
+ def shopify_user_id
28
+ @payload && @payload['sub']
29
+ end
30
+
31
+ private
32
+
33
+ def set_payload
34
+ payload, _ = parse_token_data(ShopifyApp.configuration&.secret, ShopifyApp.configuration&.old_secret)
35
+ @payload = validate_payload(payload)
36
+ rescue *WARN_EXCEPTIONS => error
37
+ Rails.logger.warn("[ShopifyApp::JWT] Failed to validate JWT: [#{error.class}] #{error}")
38
+ nil
39
+ end
40
+
41
+ def parse_token_data(secret, old_secret)
42
+ ::JWT.decode(@token, secret, true, { algorithm: 'HS256' })
43
+ rescue ::JWT::VerificationError
44
+ raise unless old_secret
45
+
46
+ ::JWT.decode(@token, old_secret, true, { algorithm: 'HS256' })
47
+ end
48
+
49
+ def validate_payload(payload)
50
+ dest_host = ShopifyApp::Utils.sanitize_shop_domain(payload['dest'])
51
+ iss_host = ShopifyApp::Utils.sanitize_shop_domain(payload['iss'])
52
+ api_key = ShopifyApp.configuration.api_key
53
+
54
+ raise InvalidAudienceError, "'aud' claim does not match api_key" unless payload['aud'] == api_key
55
+ raise InvalidDestinationError, "'dest' claim host not a valid shopify host" unless dest_host
56
+ raise MismatchedHostsError, "'dest' claim host does not match 'iss' claim host" unless dest_host == iss_host
57
+
58
+ payload
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+ module ShopifyApp
3
+ class NullUserSessionStore
4
+ class << self
5
+ def retrieve(_)
6
+ nil
7
+ end
8
+
9
+ def store(_, _)
10
+ raise SessionRepository::ConfigurationError, 'user_storage is not configured'
11
+ end
12
+
13
+ def retrieve_by_shopify_user_id(_)
14
+ nil
15
+ end
16
+
17
+ def blank?
18
+ true
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,23 +1,12 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyApp
2
3
  class SessionRepository
3
4
  class ConfigurationError < StandardError; end
4
5
 
5
6
  class << self
6
- def shop_storage=(storage)
7
- @shop_storage = storage
7
+ attr_writer :shop_storage
8
8
 
9
- unless storage.nil? || self.shop_storage.respond_to?(:store) && self.shop_storage.respond_to?(:retrieve)
10
- raise ArgumentError, "shop storage must respond to :store and :retrieve"
11
- end
12
- end
13
-
14
- def user_storage=(storage)
15
- @user_storage = storage
16
-
17
- unless storage.nil? || self.user_storage.respond_to?(:store) && self.user_storage.respond_to?(:retrieve)
18
- raise ArgumentError, "user storage must respond to :store and :retrieve"
19
- end
20
- end
9
+ attr_writer :user_storage
21
10
 
22
11
  def retrieve_shop_session(id)
23
12
  shop_storage.retrieve(id)
@@ -27,6 +16,14 @@ module ShopifyApp
27
16
  user_storage.retrieve(id)
28
17
  end
29
18
 
19
+ def retrieve_shop_session_by_shopify_domain(shopify_domain)
20
+ shop_storage.retrieve_by_shopify_domain(shopify_domain)
21
+ end
22
+
23
+ def retrieve_user_session_by_shopify_user_id(user_id)
24
+ user_storage.retrieve_by_shopify_user_id(user_id)
25
+ end
26
+
30
27
  def store_shop_session(session)
31
28
  shop_storage.store(session)
32
29
  end
@@ -36,7 +33,7 @@ module ShopifyApp
36
33
  end
37
34
 
38
35
  def shop_storage
39
- load_shop_storage || raise(ConfigurationError.new("ShopifySessionRepository.shop_storage is not configured!"))
36
+ load_shop_storage || raise(ConfigurationError, "ShopifySessionRepository.shop_storage is not configured!")
40
37
  end
41
38
 
42
39
  def user_storage
@@ -51,7 +48,7 @@ module ShopifyApp
51
48
  end
52
49
 
53
50
  def load_user_storage
54
- return unless @user_storage
51
+ return NullUserSessionStore unless @user_storage
55
52
  @user_storage.respond_to?(:safe_constantize) ? @user_storage.safe_constantize : @user_storage
56
53
  end
57
54
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyApp
2
3
  module SessionStorage
3
4
  extend ActiveSupport::Concern
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyApp
2
3
  module ShopSessionStorage
3
4
  extend ActiveSupport::Concern
@@ -8,7 +9,7 @@ module ShopifyApp
8
9
  end
9
10
 
10
11
  class_methods do
11
- def store(auth_session, *args)
12
+ def store(auth_session, *_args)
12
13
  shop = find_or_initialize_by(shopify_domain: auth_session.domain)
13
14
  shop.shopify_token = auth_session.token
14
15
  shop.save!
@@ -16,14 +17,25 @@ module ShopifyApp
16
17
  end
17
18
 
18
19
  def retrieve(id)
19
- return unless id
20
- if shop = self.find_by(id: id)
21
- ShopifyAPI::Session.new(
22
- domain: shop.shopify_domain,
23
- token: shop.shopify_token,
24
- api_version: shop.api_version
25
- )
26
- end
20
+ shop = find_by(id: id)
21
+ construct_session(shop)
22
+ end
23
+
24
+ def retrieve_by_shopify_domain(domain)
25
+ shop = find_by(shopify_domain: domain)
26
+ construct_session(shop)
27
+ end
28
+
29
+ private
30
+
31
+ def construct_session(shop)
32
+ return unless shop
33
+
34
+ ShopifyAPI::Session.new(
35
+ domain: shop.shopify_domain,
36
+ token: shop.shopify_token,
37
+ api_version: shop.api_version,
38
+ )
27
39
  end
28
40
  end
29
41
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyApp
2
3
  module UserSessionStorage
3
4
  extend ActiveSupport::Concern
@@ -17,14 +18,24 @@ module ShopifyApp
17
18
  end
18
19
 
19
20
  def retrieve(id)
20
- return unless id
21
- if user = find_by(id: id)
22
- ShopifyAPI::Session.new(
23
- domain: user.shopify_domain,
24
- token: user.shopify_token,
25
- api_version: user.api_version
26
- )
27
- end
21
+ user = find_by(id: id)
22
+ construct_session(user)
23
+ end
24
+
25
+ def retrieve_by_shopify_user_id(user_id)
26
+ user = find_by(shopify_user_id: user_id)
27
+ construct_session(user)
28
+ end
29
+
30
+ private
31
+
32
+ def construct_session(user)
33
+ return unless user
34
+ ShopifyAPI::Session.new(
35
+ domain: user.shopify_domain,
36
+ token: user.shopify_token,
37
+ api_version: user.api_version,
38
+ )
28
39
  end
29
40
  end
30
41
  end
@@ -0,0 +1,2 @@
1
+ # frozen_string_literal: true
2
+ require 'shopify_app/test_helpers/webhook_verification_helper'
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ module ShopifyApp
3
+ module TestHelpers
4
+ module WebhookVerificationHelper
5
+ def authorized_webhook_verification_headers!(params = {})
6
+ digest = OpenSSL::Digest.new('sha256')
7
+ secret = ShopifyApp.configuration.secret
8
+ valid_hmac = Base64.encode64(OpenSSL::HMAC.digest(digest, secret, params.to_query)).strip
9
+ @request.headers['HTTP_X_SHOPIFY_HMAC_SHA256'] = valid_hmac
10
+ end
11
+
12
+ def unauthorized_webhook_verification_headers!
13
+ @request.headers['HTTP_X_SHOPIFY_HMAC_SHA256'] = "invalid_hmac"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,13 +1,14 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyApp
2
3
  module Utils
3
-
4
4
  def self.sanitize_shop_domain(shop_domain)
5
+ myshopify_domain = ShopifyApp.configuration.myshopify_domain
5
6
  name = shop_domain.to_s.downcase.strip
6
- name += ".#{ShopifyApp.configuration.myshopify_domain}" if !name.include?("#{ShopifyApp.configuration.myshopify_domain}") && !name.include?(".")
7
+ name += ".#{myshopify_domain}" if !name.include?(myshopify_domain.to_s) && !name.include?(".")
7
8
  name.sub!(%r|https?://|, '')
8
9
 
9
10
  u = URI("http://#{name}")
10
- u.host if u.host&.match(/^[a-z0-9][a-z0-9\-]*[a-z0-9]\.#{Regexp.escape(ShopifyApp.configuration.myshopify_domain)}$/)
11
+ u.host if u.host&.match(/^[a-z0-9][a-z0-9\-]*[a-z0-9]\.#{Regexp.escape(myshopify_domain)}$/)
11
12
  rescue URI::InvalidURIError
12
13
  nil
13
14
  end
@@ -16,8 +17,8 @@ module ShopifyApp
16
17
  Rails.logger.info("[ShopifyAPI::ApiVersion] Fetching known Admin API Versions from Shopify...")
17
18
  ShopifyAPI::ApiVersion.fetch_known_versions
18
19
  Rails.logger.info("[ShopifyAPI::ApiVersion] Known API Versions: #{ShopifyAPI::ApiVersion.versions.keys}")
19
- rescue ActiveResource::ConnectionError
20
- logger.error( "[ShopifyAPI::ApiVersion] Unable to fetch api_versions from Shopify")
20
+ rescue ActiveResource::ConnectionError
21
+ logger.error("[ShopifyAPI::ApiVersion] Unable to fetch api_versions from Shopify")
21
22
  end
22
23
  end
23
24
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyApp
2
- VERSION = '13.0.0'.freeze
3
+ VERSION = '13.3.0'
3
4
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shopify_app",
3
- "version": "12.0.2",
3
+ "version": "13.0.0",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
@@ -1332,9 +1332,9 @@
1332
1332
  }
1333
1333
  },
1334
1334
  "acorn": {
1335
- "version": "6.3.0",
1336
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz",
1337
- "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==",
1335
+ "version": "6.4.1",
1336
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
1337
+ "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
1338
1338
  "dev": true
1339
1339
  },
1340
1340
  "after": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shopify_app",
3
- "version": "13.0.0",
3
+ "version": "13.3.0",
4
4
  "repository": "git@github.com:Shopify/shopify_app.git",
5
5
  "author": "Shopify",
6
6
  "license": "MIT",
@@ -1,4 +1,5 @@
1
- $LOAD_PATH.push File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+ $LOAD_PATH.push(File.expand_path('../lib', __FILE__))
2
3
  require "shopify_app/version"
3
4
 
4
5
  Gem::Specification.new do |s|
@@ -6,14 +7,18 @@ Gem::Specification.new do |s|
6
7
  s.version = ShopifyApp::VERSION
7
8
  s.platform = Gem::Platform::RUBY
8
9
  s.author = "Shopify"
9
- s.summary = %q{This gem is used to get quickly started with the Shopify API}
10
+ s.summary = 'This gem is used to get quickly started with the Shopify API'
10
11
 
11
- s.required_ruby_version = ">= 2.3.1"
12
+ s.required_ruby_version = ">= 2.4"
12
13
 
13
- s.add_runtime_dependency('browser_sniffer', '~> 1.2.0')
14
+ s.metadata['allowed_push_host'] = 'https://rubygems.org'
15
+
16
+ s.add_runtime_dependency('browser_sniffer', '~> 1.2.2')
14
17
  s.add_runtime_dependency('rails', '> 5.2.1')
15
- s.add_runtime_dependency('shopify_api', '~> 9.0.2')
18
+ s.add_runtime_dependency('shopify_api', '~> 9.1.0')
16
19
  s.add_runtime_dependency('omniauth-shopify-oauth2', '~> 2.2.2')
20
+ s.add_runtime_dependency('jwt', '~> 2.2.1')
21
+ s.add_runtime_dependency('redirect_safely', '~> 1.0')
17
22
 
18
23
  s.add_development_dependency('rake')
19
24
  s.add_development_dependency('byebug')
@@ -26,7 +31,7 @@ Gem::Specification.new do |s|
26
31
  s.add_development_dependency('mocha')
27
32
  s.add_development_dependency('webmock')
28
33
 
29
- s.files = `git ls-files`.split("\n").reject { |f| f.match(%r{^(test|example)/}) }
30
- s.test_files = `git ls-files -- {test}/*`.split("\n")
34
+ s.files = %x(git ls-files).split("\n").reject { |f| f.match(%r{^(test|example)/}) }
35
+ s.test_files = %x(git ls-files -- {test}/*).split("\n")
31
36
  s.require_paths = ["lib"]
32
37
  end
data/yarn.lock CHANGED
@@ -994,9 +994,9 @@ accepts@~1.3.4:
994
994
  negotiator "0.6.2"
995
995
 
996
996
  acorn@^6.2.1:
997
- version "6.3.0"
998
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e"
999
- integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==
997
+ version "6.4.1"
998
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474"
999
+ integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==
1000
1000
 
1001
1001
  after@0.8.2:
1002
1002
  version "0.8.2"
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.0.0
4
+ version: 13.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: 2020-03-16 00:00:00.000000000 Z
11
+ date: 2020-06-01 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.2.0
19
+ version: 1.2.2
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.2.0
26
+ version: 1.2.2
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: 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
@@ -66,6 +66,34 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: 2.2.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: jwt
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 2.2.1
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
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'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: rake
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -216,6 +244,7 @@ files:
216
244
  - ".github/CODEOWNERS"
217
245
  - ".github/ISSUE_TEMPLATE.md"
218
246
  - ".github/probots.yml"
247
+ - ".github/workflows/rubocop.yml"
219
248
  - ".gitignore"
220
249
  - ".nvmrc"
221
250
  - ".rubocop.yml"
@@ -226,6 +255,7 @@ files:
226
255
  - LICENSE
227
256
  - README.md
228
257
  - Rakefile
258
+ - SECURITY.md
229
259
  - app/assets/images/storage_access.svg
230
260
  - app/assets/javascripts/shopify_app/enable_cookies.js
231
261
  - app/assets/javascripts/shopify_app/itp_helper.js
@@ -237,6 +267,7 @@ files:
237
267
  - app/assets/javascripts/shopify_app/top_level.js
238
268
  - app/assets/javascripts/shopify_app/top_level_interaction.js
239
269
  - app/controllers/concerns/shopify_app/authenticated.rb
270
+ - app/controllers/concerns/shopify_app/require_known_shop.rb
240
271
  - app/controllers/shopify_app/authenticated_controller.rb
241
272
  - app/controllers/shopify_app/callback_controller.rb
242
273
  - app/controllers/shopify_app/extension_verification_controller.rb
@@ -287,7 +318,7 @@ files:
287
318
  - lib/generators/shopify_app/add_marketing_activity_extension/add_marketing_activity_extension_generator.rb
288
319
  - lib/generators/shopify_app/add_marketing_activity_extension/templates/marketing_activities_controller.rb
289
320
  - lib/generators/shopify_app/add_webhook/add_webhook_generator.rb
290
- - lib/generators/shopify_app/add_webhook/templates/webhook_job.rb
321
+ - lib/generators/shopify_app/add_webhook/templates/webhook_job.rb.tt
291
322
  - lib/generators/shopify_app/app_proxy_controller/app_proxy_controller_generator.rb
292
323
  - lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_controller.rb
293
324
  - lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_route.rb
@@ -305,7 +336,7 @@ files:
305
336
  - lib/generators/shopify_app/install/templates/omniauth.rb
306
337
  - lib/generators/shopify_app/install/templates/session_store.rb
307
338
  - lib/generators/shopify_app/install/templates/shopify_app.js
308
- - lib/generators/shopify_app/install/templates/shopify_app.rb
339
+ - lib/generators/shopify_app/install/templates/shopify_app.rb.tt
309
340
  - lib/generators/shopify_app/install/templates/shopify_app_index.js
310
341
  - lib/generators/shopify_app/install/templates/shopify_provider.rb
311
342
  - lib/generators/shopify_app/install/templates/user_agent.rb
@@ -331,20 +362,26 @@ files:
331
362
  - lib/shopify_app/controller_concerns/itp.rb
332
363
  - lib/shopify_app/controller_concerns/localization.rb
333
364
  - lib/shopify_app/controller_concerns/login_protection.rb
365
+ - lib/shopify_app/controller_concerns/payload_verification.rb
334
366
  - lib/shopify_app/controller_concerns/webhook_verification.rb
335
367
  - lib/shopify_app/engine.rb
336
368
  - lib/shopify_app/jobs/scripttags_manager_job.rb
337
369
  - lib/shopify_app/jobs/webhooks_manager_job.rb
338
370
  - lib/shopify_app/managers/scripttags_manager.rb
339
371
  - lib/shopify_app/managers/webhooks_manager.rb
372
+ - lib/shopify_app/middleware/jwt_middleware.rb
340
373
  - lib/shopify_app/middleware/same_site_cookie_middleware.rb
341
374
  - lib/shopify_app/session/in_memory_session_store.rb
342
375
  - lib/shopify_app/session/in_memory_shop_session_store.rb
343
376
  - lib/shopify_app/session/in_memory_user_session_store.rb
377
+ - lib/shopify_app/session/jwt.rb
378
+ - lib/shopify_app/session/null_user_session_store.rb
344
379
  - lib/shopify_app/session/session_repository.rb
345
380
  - lib/shopify_app/session/session_storage.rb
346
381
  - lib/shopify_app/session/shop_session_storage.rb
347
382
  - lib/shopify_app/session/user_session_storage.rb
383
+ - lib/shopify_app/test_helpers/all.rb
384
+ - lib/shopify_app/test_helpers/webhook_verification_helper.rb
348
385
  - lib/shopify_app/utils.rb
349
386
  - lib/shopify_app/version.rb
350
387
  - package-lock.json
@@ -357,7 +394,8 @@ files:
357
394
  - yarn.lock
358
395
  homepage:
359
396
  licenses: []
360
- metadata: {}
397
+ metadata:
398
+ allowed_push_host: https://rubygems.org
361
399
  post_install_message:
362
400
  rdoc_options: []
363
401
  require_paths:
@@ -366,7 +404,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
366
404
  requirements:
367
405
  - - ">="
368
406
  - !ruby/object:Gem::Version
369
- version: 2.3.1
407
+ version: '2.4'
370
408
  required_rubygems_version: !ruby/object:Gem::Requirement
371
409
  requirements:
372
410
  - - ">="