shopify_app 12.0.5 → 13.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -6
  3. data/.travis.yml +4 -3
  4. data/CHANGELOG.md +33 -1
  5. data/Gemfile +3 -0
  6. data/README.md +109 -41
  7. data/Rakefile +1 -0
  8. data/app/controllers/concerns/shopify_app/authenticated.rb +1 -1
  9. data/app/controllers/shopify_app/authenticated_controller.rb +1 -0
  10. data/app/controllers/shopify_app/callback_controller.rb +15 -11
  11. data/app/controllers/shopify_app/sessions_controller.rb +35 -9
  12. data/app/controllers/shopify_app/webhooks_controller.rb +6 -5
  13. data/config/locales/fi.yml +1 -1
  14. data/config/locales/nl.yml +7 -7
  15. data/config/routes.rb +1 -0
  16. data/lib/generators/shopify_app/add_after_authenticate_job/add_after_authenticate_job_generator.rb +5 -3
  17. data/lib/generators/shopify_app/add_after_authenticate_job/templates/after_authenticate_job.rb +1 -0
  18. data/lib/generators/shopify_app/add_marketing_activity_extension/add_marketing_activity_extension_generator.rb +2 -1
  19. data/lib/generators/shopify_app/add_marketing_activity_extension/templates/marketing_activities_controller.rb +4 -4
  20. data/lib/generators/shopify_app/add_webhook/add_webhook_generator.rb +5 -4
  21. data/lib/generators/shopify_app/add_webhook/templates/{webhook_job.rb → webhook_job.rb.tt} +5 -0
  22. data/lib/generators/shopify_app/app_proxy_controller/app_proxy_controller_generator.rb +4 -3
  23. data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_controller.rb +3 -3
  24. data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_route.rb +10 -9
  25. data/lib/generators/shopify_app/controllers/controllers_generator.rb +1 -0
  26. data/lib/generators/shopify_app/home_controller/home_controller_generator.rb +4 -3
  27. data/lib/generators/shopify_app/home_controller/templates/index.html.erb +1 -1
  28. data/lib/generators/shopify_app/install/install_generator.rb +10 -9
  29. data/lib/generators/shopify_app/install/templates/embedded_app.html.erb +1 -1
  30. data/lib/generators/shopify_app/install/templates/omniauth.rb +2 -1
  31. data/lib/generators/shopify_app/install/templates/{shopify_app.rb → shopify_app.rb.tt} +1 -1
  32. data/lib/generators/shopify_app/install/templates/shopify_provider.rb +1 -1
  33. data/lib/generators/shopify_app/install/templates/user_agent.rb +2 -1
  34. data/lib/generators/shopify_app/routes/routes_generator.rb +1 -0
  35. data/lib/generators/shopify_app/routes/templates/routes.rb +10 -9
  36. data/lib/generators/shopify_app/shop_model/shop_model_generator.rb +12 -7
  37. data/lib/generators/shopify_app/shop_model/templates/shop.rb +2 -1
  38. data/lib/generators/shopify_app/shopify_app_generator.rb +4 -3
  39. data/lib/generators/shopify_app/user_model/templates/user.rb +2 -1
  40. data/lib/generators/shopify_app/user_model/user_model_generator.rb +12 -7
  41. data/lib/generators/shopify_app/views/views_generator.rb +1 -0
  42. data/lib/shopify_app.rb +9 -4
  43. data/lib/shopify_app/configuration.rb +21 -17
  44. data/lib/shopify_app/controller_concerns/app_proxy_verification.rb +3 -2
  45. data/lib/shopify_app/controller_concerns/embedded_app.rb +3 -2
  46. data/lib/shopify_app/controller_concerns/localization.rb +1 -0
  47. data/lib/shopify_app/controller_concerns/login_protection.rb +72 -27
  48. data/lib/shopify_app/controller_concerns/webhook_verification.rb +2 -1
  49. data/lib/shopify_app/engine.rb +1 -0
  50. data/lib/shopify_app/jobs/scripttags_manager_job.rb +1 -1
  51. data/lib/shopify_app/jobs/webhooks_manager_job.rb +1 -1
  52. data/lib/shopify_app/managers/scripttags_manager.rb +4 -3
  53. data/lib/shopify_app/managers/webhooks_manager.rb +4 -3
  54. data/lib/shopify_app/middleware/same_site_cookie_middleware.rb +2 -1
  55. data/lib/shopify_app/session/in_memory_session_store.rb +7 -3
  56. data/lib/shopify_app/session/in_memory_shop_session_store.rb +14 -0
  57. data/lib/shopify_app/session/in_memory_user_session_store.rb +14 -0
  58. data/lib/shopify_app/session/jwt.rb +61 -0
  59. data/lib/shopify_app/session/null_user_session_store.rb +22 -0
  60. data/lib/shopify_app/session/session_repository.rb +36 -14
  61. data/lib/shopify_app/session/session_storage.rb +1 -10
  62. data/lib/shopify_app/session/shop_session_storage.rb +42 -0
  63. data/lib/shopify_app/session/user_session_storage.rb +42 -0
  64. data/lib/shopify_app/test_helpers/all.rb +2 -0
  65. data/lib/shopify_app/test_helpers/webhook_verification_helper.rb +17 -0
  66. data/lib/shopify_app/utils.rb +6 -5
  67. data/lib/shopify_app/version.rb +2 -1
  68. data/package-lock.json +1231 -1210
  69. data/package.json +1 -1
  70. data/shopify_app.gemspec +11 -7
  71. data/yarn.lock +3 -3
  72. metadata +33 -12
  73. data/lib/shopify_app/session/storage_strategies/shop_storage_strategy.rb +0 -23
  74. data/lib/shopify_app/session/storage_strategies/user_storage_strategy.rb +0 -24
@@ -2,7 +2,7 @@
2
2
 
3
3
  <ul>
4
4
  <% @products.each do |product| %>
5
- <li><%= link_to product.title, "https://#{@shop_session.domain}/admin/products/#{product.id}", target: "_top" %></li>
5
+ <li><%= link_to product.title, "https://#{@current_shopify_session.domain}/admin/products/#{product.id}", target: "_top" %></li>
6
6
  <% end %>
7
7
  </ul>
8
8
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rails/generators/base'
2
3
 
3
4
  module ShopifyApp
@@ -16,7 +17,7 @@ module ShopifyApp
16
17
  @scope = format_array_argument(options['scope'])
17
18
  @api_version = options['api_version'] || ShopifyAPI::Meta.admin_versions.find(&:latest_supported).handle
18
19
 
19
- template 'shopify_app.rb', 'config/initializers/shopify_app.rb'
20
+ template('shopify_app.rb', 'config/initializers/shopify_app.rb')
20
21
  end
21
22
 
22
23
  def create_session_store_initializer
@@ -24,28 +25,28 @@ module ShopifyApp
24
25
  end
25
26
 
26
27
  def create_and_inject_into_omniauth_initializer
27
- unless File.exist? "config/initializers/omniauth.rb"
28
- copy_file 'omniauth.rb', 'config/initializers/omniauth.rb'
28
+ unless File.exist?("config/initializers/omniauth.rb")
29
+ copy_file('omniauth.rb', 'config/initializers/omniauth.rb')
29
30
  end
30
31
 
31
32
  inject_into_file(
32
33
  'config/initializers/omniauth.rb',
33
34
  File.read(File.expand_path(find_in_source_paths('shopify_provider.rb'))),
34
- after: "Rails.application.config.middleware.use OmniAuth::Builder do\n"
35
+ after: "Rails.application.config.middleware.use(OmniAuth::Builder) do\n"
35
36
  )
36
37
  end
37
38
 
38
39
  def create_embedded_app_layout
39
40
  return unless embedded_app?
40
41
 
41
- copy_file 'embedded_app.html.erb', 'app/views/layouts/embedded_app.html.erb'
42
- copy_file '_flash_messages.html.erb', 'app/views/layouts/_flash_messages.html.erb'
42
+ copy_file('embedded_app.html.erb', 'app/views/layouts/embedded_app.html.erb')
43
+ copy_file('_flash_messages.html.erb', 'app/views/layouts/_flash_messages.html.erb')
43
44
 
44
45
  if ShopifyApp.use_webpacker?
45
46
  copy_file('shopify_app.js', 'app/javascript/shopify_app/shopify_app.js')
46
47
  copy_file('flash_messages.js', 'app/javascript/shopify_app/flash_messages.js')
47
48
  copy_file('shopify_app_index.js', 'app/javascript/shopify_app/index.js')
48
- append_to_file('app/javascript/packs/application.js', 'require("shopify_app")')
49
+ append_to_file('app/javascript/packs/application.js', "require(\"shopify_app\")\n")
49
50
  else
50
51
  copy_file('shopify_app.js', 'app/assets/javascripts/shopify_app.js')
51
52
  copy_file('flash_messages.js', 'app/assets/javascripts/flash_messages.js')
@@ -53,11 +54,11 @@ module ShopifyApp
53
54
  end
54
55
 
55
56
  def create_user_agent_initializer
56
- template 'user_agent.rb', 'config/initializers/user_agent.rb'
57
+ template('user_agent.rb', 'config/initializers/user_agent.rb')
57
58
  end
58
59
 
59
60
  def mount_engine
60
- route "mount ShopifyApp::Engine, at: '/'"
61
+ route("mount ShopifyApp::Engine, at: '/'")
61
62
  end
62
63
 
63
64
  def insert_hosts_into_development_config
@@ -28,7 +28,7 @@
28
28
 
29
29
  <%= content_tag(:div, nil, id: 'shopify-app-init', data: {
30
30
  api_key: ShopifyApp.configuration.api_key,
31
- shop_origin: (@shop_session.domain if @shop_session),
31
+ shop_origin: (@current_shopify_session.domain if @current_shopify_session),
32
32
  debug: Rails.env.development?
33
33
  } ) %>
34
34
 
@@ -1,2 +1,3 @@
1
- Rails.application.config.middleware.use OmniAuth::Builder do
1
+ # frozen_string_literal: true
2
+ Rails.application.config.middleware.use(OmniAuth::Builder) do
2
3
  end
@@ -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.session_repository = 'ShopifyApp::InMemorySessionStore'
11
+ config.shop_session_repository = 'ShopifyApp::InMemoryShopSessionStore'
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,7 +4,6 @@ provider :shopify,
4
4
  ShopifyApp.configuration.api_key,
5
5
  ShopifyApp.configuration.secret,
6
6
  scope: ShopifyApp.configuration.scope,
7
- per_user_permissions: ShopifyApp.configuration.per_user_tokens,
8
7
  setup: lambda { |env|
9
8
  strategy = env['omniauth.strategy']
10
9
 
@@ -17,4 +16,5 @@ provider :shopify,
17
16
 
18
17
  strategy.options[:client_options][:site] = shop
19
18
  strategy.options[:old_client_secret] = ShopifyApp.configuration.old_secret
19
+ strategy.options[:per_user_permissions] = strategy.session[:user_tokens]
20
20
  }
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class Base < ActiveResource::Base
3
- self.headers['User-Agent'] << " | ShopifyApp/#{ShopifyApp::VERSION}"
4
+ headers['User-Agent'] << " | ShopifyApp/#{ShopifyApp::VERSION}"
4
5
  end
5
6
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rails/generators/base'
2
3
 
3
4
  module ShopifyApp
@@ -1,11 +1,12 @@
1
+ # frozen_string_literal: true
1
2
 
2
- controller :sessions do
3
- get 'login' => :new, :as => :login
4
- post 'login' => :create, :as => :authenticate
5
- get 'auth/shopify/callback' => :callback
6
- get 'logout' => :destroy, :as => :logout
7
- end
3
+ controller :sessions do
4
+ get 'login' => :new, :as => :login
5
+ post 'login' => :create, :as => :authenticate
6
+ get 'auth/shopify/callback' => :callback
7
+ get 'logout' => :destroy, :as => :logout
8
+ end
8
9
 
9
- namespace :webhooks do
10
- post ':type' => :receive
11
- end
10
+ namespace :webhooks do
11
+ post ':type' => :receive
12
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rails/generators/base'
2
3
  require 'rails/generators/active_record'
3
4
 
@@ -8,19 +9,19 @@ module ShopifyApp
8
9
  source_root File.expand_path('../templates', __FILE__)
9
10
 
10
11
  def create_shop_model
11
- copy_file 'shop.rb', 'app/models/shop.rb'
12
+ copy_file('shop.rb', 'app/models/shop.rb')
12
13
  end
13
14
 
14
15
  def create_shop_migration
15
- migration_template 'db/migrate/create_shops.erb', 'db/migrate/create_shops.rb'
16
+ migration_template('db/migrate/create_shops.erb', 'db/migrate/create_shops.rb')
16
17
  end
17
18
 
18
19
  def update_shopify_app_initializer
19
- gsub_file 'config/initializers/shopify_app.rb', 'ShopifyApp::InMemorySessionStore', 'Shop'
20
+ gsub_file('config/initializers/shopify_app.rb', 'ShopifyApp::InMemoryShopSessionStore', 'Shop')
20
21
  end
21
22
 
22
23
  def create_shop_fixtures
23
- copy_file 'shops.yml', 'test/fixtures/shops.yml'
24
+ copy_file('shops.yml', 'test/fixtures/shops.yml')
24
25
  end
25
26
 
26
27
  private
@@ -29,9 +30,13 @@ module ShopifyApp
29
30
  Rails.version.match(/\d\.\d/)[0]
30
31
  end
31
32
 
32
- # for generating a timestamp when using `create_migration`
33
- def self.next_migration_number(dir)
34
- ActiveRecord::Generators::Base.next_migration_number(dir)
33
+ class << self
34
+ private :next_migration_number
35
+
36
+ # for generating a timestamp when using `create_migration`
37
+ def next_migration_number(dir)
38
+ ActiveRecord::Generators::Base.next_migration_number(dir)
39
+ end
35
40
  end
36
41
  end
37
42
  end
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  class Shop < ActiveRecord::Base
2
- include ShopifyApp::SessionStorage
3
+ include ShopifyApp::ShopSessionStorage
3
4
 
4
5
  def api_version
5
6
  ShopifyApp.configuration.api_version
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyApp
2
3
  module Generators
3
4
  class ShopifyAppGenerator < Rails::Generators::Base
@@ -7,10 +8,10 @@ module ShopifyApp
7
8
  end
8
9
 
9
10
  def run_all_generators
10
- generate "shopify_app:install #{@opts.join(' ')}"
11
- generate "shopify_app:shop_model"
11
+ generate("shopify_app:install #{@opts.join(' ')}")
12
+ generate("shopify_app:shop_model")
12
13
  generate("shopify_app:authenticated_controller")
13
- generate "shopify_app:home_controller"
14
+ generate("shopify_app:home_controller")
14
15
  end
15
16
  end
16
17
  end
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  class User < ActiveRecord::Base
2
- include ShopifyApp::SessionStorage
3
+ include ShopifyApp::UserSessionStorage
3
4
 
4
5
  def api_version
5
6
  ShopifyApp.configuration.api_version
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rails/generators/base'
2
3
  require 'rails/generators/active_record'
3
4
 
@@ -8,19 +9,19 @@ module ShopifyApp
8
9
  source_root File.expand_path('../templates', __FILE__)
9
10
 
10
11
  def create_user_model
11
- copy_file 'user.rb', 'app/models/user.rb'
12
+ copy_file('user.rb', 'app/models/user.rb')
12
13
  end
13
14
 
14
15
  def create_user_migration
15
- migration_template 'db/migrate/create_users.erb', 'db/migrate/create_users.rb'
16
+ migration_template('db/migrate/create_users.erb', 'db/migrate/create_users.rb')
16
17
  end
17
18
 
18
19
  def update_shopify_app_initializer
19
- gsub_file 'config/initializers/shopify_app.rb', 'ShopifyApp::InMemorySessionStore', 'User'
20
+ gsub_file('config/initializers/shopify_app.rb', 'ShopifyApp::InMemoryUserSessionStore', 'User')
20
21
  end
21
22
 
22
23
  def create_user_fixtures
23
- copy_file 'users.yml', 'test/fixtures/users.yml'
24
+ copy_file('users.yml', 'test/fixtures/users.yml')
24
25
  end
25
26
 
26
27
  private
@@ -29,9 +30,13 @@ module ShopifyApp
29
30
  Rails.version.match(/\d\.\d/)[0]
30
31
  end
31
32
 
32
- # for generating a timestamp when using `create_migration`
33
- def self.next_migration_number(dir)
34
- ActiveRecord::Generators::Base.next_migration_number(dir)
33
+ class << self
34
+ private :next_migration_number
35
+
36
+ # for generating a timestamp when using `create_migration`
37
+ def next_migration_number(dir)
38
+ ActiveRecord::Generators::Base.next_migration_number(dir)
39
+ end
35
40
  end
36
41
  end
37
42
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rails/generators/base'
2
3
 
3
4
  module ShopifyApp
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'shopify_app/version'
2
3
 
3
4
  # deps
@@ -44,9 +45,13 @@ module ShopifyApp
44
45
  require 'shopify_app/middleware/same_site_cookie_middleware'
45
46
 
46
47
  # session
47
- require 'shopify_app/session/storage_strategies/shop_storage_strategy'
48
- require 'shopify_app/session/storage_strategies/user_storage_strategy'
49
- require 'shopify_app/session/session_storage'
50
- require 'shopify_app/session/session_repository'
51
48
  require 'shopify_app/session/in_memory_session_store'
49
+ require 'shopify_app/session/in_memory_shop_session_store'
50
+ require 'shopify_app/session/in_memory_user_session_store'
51
+ require 'shopify_app/session/jwt'
52
+ require 'shopify_app/session/null_user_session_store'
53
+ require 'shopify_app/session/session_repository'
54
+ require 'shopify_app/session/session_storage'
55
+ require 'shopify_app/session/shop_session_storage'
56
+ require 'shopify_app/session/user_session_storage'
52
57
  end
@@ -1,11 +1,11 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyApp
2
3
  class Configuration
3
-
4
4
  # Shopify App settings. These values should match the configuration
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
- attr_reader :api_key
8
+ attr_accessor :api_key
9
9
  attr_accessor :secret
10
10
  attr_accessor :old_secret
11
11
  attr_accessor :scope
@@ -14,14 +14,11 @@ module ShopifyApp
14
14
  attr_accessor :webhooks
15
15
  attr_accessor :scripttags
16
16
  attr_accessor :after_authenticate_job
17
- attr_reader :session_repository
18
- attr_accessor :per_user_tokens
19
- alias_method :per_user_tokens?, :per_user_tokens
20
17
  attr_accessor :api_version
21
18
 
22
19
  # customise urls
23
20
  attr_accessor :root_url
24
- attr_accessor :login_url
21
+ attr_writer :login_url
25
22
 
26
23
  # customise ActiveJob queue names
27
24
  attr_accessor :scripttags_manager_queue_name
@@ -37,14 +34,16 @@ module ShopifyApp
37
34
  attr_accessor :webhook_jobs_namespace
38
35
 
39
36
  # allow enabling of same site none on cookies
40
- attr_accessor :enable_same_site_none
37
+ attr_writer :enable_same_site_none
38
+
39
+ # allow enabling jwt headers for authentication
40
+ attr_accessor :allow_jwt_authentication
41
41
 
42
42
  def initialize
43
43
  @root_url = '/'
44
44
  @myshopify_domain = 'myshopify.com'
45
45
  @scripttags_manager_queue_name = Rails.application.config.active_job.queue_name
46
46
  @webhooks_manager_queue_name = Rails.application.config.active_job.queue_name
47
- @per_user_tokens = false
48
47
  @disable_webpacker = ENV['SHOPIFY_APP_DISABLE_WEBPACKER'].present?
49
48
  end
50
49
 
@@ -52,9 +51,20 @@ module ShopifyApp
52
51
  @login_url || File.join(@root_url, 'login')
53
52
  end
54
53
 
55
- def session_repository=(klass)
56
- @session_repository = klass
57
- ShopifyApp::SessionRepository.storage = klass
54
+ def user_session_repository=(klass)
55
+ ShopifyApp::SessionRepository.user_storage = klass
56
+ end
57
+
58
+ def user_session_repository
59
+ ShopifyApp::SessionRepository.user_storage
60
+ end
61
+
62
+ def shop_session_repository=(klass)
63
+ ShopifyApp::SessionRepository.shop_storage = klass
64
+ end
65
+
66
+ def shop_session_repository
67
+ ShopifyApp::SessionRepository.shop_storage
58
68
  end
59
69
 
60
70
  def has_webhooks?
@@ -65,12 +75,6 @@ module ShopifyApp
65
75
  scripttags.present?
66
76
  end
67
77
 
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
-
74
78
  def enable_same_site_none
75
79
  !Rails.env.test? && (@enable_same_site_none.nil? ? embedded_app? : @enable_same_site_none)
76
80
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyApp
2
3
  module AppProxyVerification
3
4
  extend ActiveSupport::Concern
@@ -8,7 +9,7 @@ module ShopifyApp
8
9
  end
9
10
 
10
11
  def verify_proxy_request
11
- return head :forbidden unless query_string_valid?(request.query_string)
12
+ return head(:forbidden) unless query_string_valid?(request.query_string)
12
13
  end
13
14
 
14
15
  private
@@ -26,7 +27,7 @@ module ShopifyApp
26
27
  end
27
28
 
28
29
  def calculated_signature(query_hash_without_signature)
29
- sorted_params = query_hash_without_signature.collect{|k,v| "#{k}=#{Array(v).join(',')}"}.sort.join
30
+ sorted_params = query_hash_without_signature.collect { |k, v| "#{k}=#{Array(v).join(',')}" }.sort.join
30
31
 
31
32
  OpenSSL::HMAC.hexdigest(
32
33
  OpenSSL::Digest.new('sha256'),
@@ -1,11 +1,12 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyApp
2
3
  module EmbeddedApp
3
4
  extend ActiveSupport::Concern
4
5
 
5
6
  included do
6
7
  if ShopifyApp.configuration.embedded_app?
7
- after_action :set_esdk_headers
8
- layout 'embedded_app'
8
+ after_action(:set_esdk_headers)
9
+ layout('embedded_app')
9
10
  end
10
11
  end
11
12
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyApp
2
3
  module Localization
3
4
  extend ActiveSupport::Concern
@@ -11,56 +11,94 @@ module ShopifyApp
11
11
 
12
12
  included do
13
13
  after_action :set_test_cookie
14
- rescue_from ActiveResource::UnauthorizedAccess, :with => :close_session
14
+ rescue_from ActiveResource::UnauthorizedAccess, with: :close_session
15
15
  end
16
16
 
17
- def shopify_session
18
- return redirect_to_login unless shop_session
17
+ def activate_shopify_session
18
+ return redirect_to_login if current_shopify_session.blank?
19
19
  clear_top_level_oauth_cookie
20
20
 
21
21
  begin
22
- ShopifyAPI::Base.activate_session(shop_session)
22
+ ShopifyAPI::Base.activate_session(current_shopify_session)
23
23
  yield
24
24
  ensure
25
25
  ShopifyAPI::Base.clear_session
26
26
  end
27
27
  end
28
28
 
29
- def shop_session
30
- if ShopifyApp.configuration.per_user_tokens?
31
- return unless session[:shopify_user]
32
- @shop_session ||= ShopifyApp::SessionRepository.retrieve(session[:shopify_user]['id'])
33
- else
34
- return unless session[:shopify]
35
- @shop_session ||= ShopifyApp::SessionRepository.retrieve(session[:shopify])
29
+ def current_shopify_session
30
+ @current_shopify_session ||= begin
31
+ user_session || shop_session
36
32
  end
37
33
  end
38
34
 
35
+ def user_session
36
+ user_session_by_jwt || user_session_by_cookie
37
+ end
38
+
39
+ def user_session_by_jwt
40
+ return unless ShopifyApp.configuration.allow_jwt_authentication
41
+ return unless jwt_shopify_user_id
42
+ ShopifyApp::SessionRepository.retrieve_user_session_by_shopify_user_id(jwt_shopify_user_id)
43
+ end
44
+
45
+ def user_session_by_cookie
46
+ return unless session[:user_id].present?
47
+ ShopifyApp::SessionRepository.retrieve_user_session(session[:user_id])
48
+ end
49
+
50
+ def shop_session
51
+ shop_session_by_jwt || shop_session_by_cookie
52
+ end
53
+
54
+ def shop_session_by_jwt
55
+ return unless ShopifyApp.configuration.allow_jwt_authentication
56
+ return unless jwt_shopify_domain
57
+ ShopifyApp::SessionRepository.retrieve_shop_session_by_shopify_domain(jwt_shopify_domain)
58
+ end
59
+
60
+ def shop_session_by_cookie
61
+ return unless session[:shop_id].present?
62
+ ShopifyApp::SessionRepository.retrieve_shop_session(session[:shop_id])
63
+ end
64
+
39
65
  def login_again_if_different_user_or_shop
40
- if ShopifyApp.configuration.per_user_tokens?
41
- valid_session_data = session[:user_session].present? && params[:session].present? # session data was sent/stored correctly
42
- sessions_do_not_match = session[:user_session] != params[:session] # current user is different from stored user
66
+ if session[:user_session].present? && params[:session].present? # session data was sent/stored correctly
67
+ clear_session = session[:user_session] != params[:session] # current user is different from stored user
43
68
 
44
- if valid_session_data && sessions_do_not_match
45
- clear_session = true
46
- end
47
69
  end
48
70
 
49
- if shop_session && params[:shop] && params[:shop].is_a?(String) && (shop_session.domain != params[:shop])
71
+ if current_shopify_session &&
72
+ params[:shop] && params[:shop].is_a?(String) &&
73
+ (current_shopify_session.domain != params[:shop])
50
74
  clear_session = true
51
75
  end
52
76
 
53
77
  if clear_session
54
- clear_shop_session
78
+ clear_shopify_session
55
79
  redirect_to_login
56
80
  end
57
81
  end
58
82
 
59
83
  protected
60
84
 
85
+ def jwt_shopify_domain
86
+ return unless jwt
87
+ @jwt_shopify_domain ||= JWT.new(jwt).shopify_domain
88
+ end
89
+
90
+ 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 }
97
+ end
98
+
61
99
  def redirect_to_login
62
100
  if request.xhr?
63
- head :unauthorized
101
+ head(:unauthorized)
64
102
  else
65
103
  if request.get?
66
104
  path = request.path
@@ -70,18 +108,19 @@ module ShopifyApp
70
108
  path = referer.path
71
109
  query = "#{referer.query}&#{sanitized_params.to_query}"
72
110
  end
73
- session[:return_to] = "#{path}?#{query}"
111
+ session[:return_to] = query.blank? ? path.to_s : "#{path}?#{query}"
74
112
  redirect_to(login_url_with_optional_shop)
75
113
  end
76
114
  end
77
115
 
78
116
  def close_session
79
- clear_shop_session
117
+ clear_shopify_session
80
118
  redirect_to(login_url_with_optional_shop)
81
119
  end
82
120
 
83
- def clear_shop_session
84
- session[:shopify] = nil
121
+ def clear_shopify_session
122
+ session[:shop_id] = nil
123
+ session[:user_id] = nil
85
124
  session[:shopify_domain] = nil
86
125
  session[:shopify_user] = nil
87
126
  session[:user_session] = nil
@@ -123,9 +162,10 @@ module ShopifyApp
123
162
 
124
163
  def fullpage_redirect_to(url)
125
164
  if ShopifyApp.configuration.embedded_app?
126
- render 'shopify_app/shared/redirect', layout: false, locals: { url: url, current_shopify_domain: current_shopify_domain }
165
+ render('shopify_app/shared/redirect', layout: false,
166
+ locals: { url: url, current_shopify_domain: current_shopify_domain })
127
167
  else
128
- redirect_to url
168
+ redirect_to(url)
129
169
  end
130
170
  end
131
171
 
@@ -165,11 +205,16 @@ module ShopifyApp
165
205
  end
166
206
 
167
207
  def return_address
208
+ return base_return_address unless ShopifyApp.configuration.allow_jwt_authentication
209
+ return_address_with_params(shop: current_shopify_domain)
210
+ end
211
+
212
+ def base_return_address
168
213
  session.delete(:return_to) || ShopifyApp.configuration.root_url
169
214
  end
170
215
 
171
216
  def return_address_with_params(params)
172
- uri = URI(return_address)
217
+ uri = URI(base_return_address)
173
218
  uri.query = CGI.parse(uri.query.to_s)
174
219
  .symbolize_keys
175
220
  .transform_values { |v| v.one? ? v.first : v }