shopify_app 12.0.7 → 13.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -6
  3. data/.travis.yml +4 -3
  4. data/CHANGELOG.md +33 -0
  5. data/Gemfile +3 -0
  6. data/README.md +98 -42
  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 +50 -17
  11. data/app/controllers/shopify_app/sessions_controller.rb +36 -10
  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/docs/Releasing.md +1 -0
  17. data/lib/generators/shopify_app/add_after_authenticate_job/add_after_authenticate_job_generator.rb +5 -3
  18. data/lib/generators/shopify_app/add_after_authenticate_job/templates/after_authenticate_job.rb +1 -0
  19. data/lib/generators/shopify_app/add_marketing_activity_extension/add_marketing_activity_extension_generator.rb +2 -1
  20. data/lib/generators/shopify_app/add_marketing_activity_extension/templates/marketing_activities_controller.rb +4 -4
  21. data/lib/generators/shopify_app/add_webhook/add_webhook_generator.rb +5 -4
  22. data/lib/generators/shopify_app/add_webhook/templates/{webhook_job.rb → webhook_job.rb.tt} +5 -0
  23. data/lib/generators/shopify_app/app_proxy_controller/app_proxy_controller_generator.rb +4 -3
  24. data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_controller.rb +3 -3
  25. data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_route.rb +10 -9
  26. data/lib/generators/shopify_app/controllers/controllers_generator.rb +1 -0
  27. data/lib/generators/shopify_app/home_controller/home_controller_generator.rb +4 -3
  28. data/lib/generators/shopify_app/home_controller/templates/index.html.erb +1 -1
  29. data/lib/generators/shopify_app/install/install_generator.rb +10 -9
  30. data/lib/generators/shopify_app/install/templates/embedded_app.html.erb +1 -1
  31. data/lib/generators/shopify_app/install/templates/omniauth.rb +2 -1
  32. data/lib/generators/shopify_app/install/templates/{shopify_app.rb → shopify_app.rb.tt} +1 -1
  33. data/lib/generators/shopify_app/install/templates/shopify_provider.rb +1 -1
  34. data/lib/generators/shopify_app/install/templates/user_agent.rb +2 -1
  35. data/lib/generators/shopify_app/routes/routes_generator.rb +1 -0
  36. data/lib/generators/shopify_app/routes/templates/routes.rb +10 -9
  37. data/lib/generators/shopify_app/shop_model/shop_model_generator.rb +12 -7
  38. data/lib/generators/shopify_app/shop_model/templates/shop.rb +2 -1
  39. data/lib/generators/shopify_app/shopify_app_generator.rb +4 -3
  40. data/lib/generators/shopify_app/user_model/templates/user.rb +2 -1
  41. data/lib/generators/shopify_app/user_model/user_model_generator.rb +12 -7
  42. data/lib/generators/shopify_app/views/views_generator.rb +1 -0
  43. data/lib/shopify_app.rb +11 -4
  44. data/lib/shopify_app/configuration.rb +21 -11
  45. data/lib/shopify_app/controller_concerns/app_proxy_verification.rb +3 -2
  46. data/lib/shopify_app/controller_concerns/embedded_app.rb +3 -2
  47. data/lib/shopify_app/controller_concerns/localization.rb +1 -0
  48. data/lib/shopify_app/controller_concerns/login_protection.rb +71 -29
  49. data/lib/shopify_app/controller_concerns/webhook_verification.rb +2 -1
  50. data/lib/shopify_app/engine.rb +5 -0
  51. data/lib/shopify_app/jobs/scripttags_manager_job.rb +1 -1
  52. data/lib/shopify_app/jobs/webhooks_manager_job.rb +1 -1
  53. data/lib/shopify_app/managers/scripttags_manager.rb +4 -3
  54. data/lib/shopify_app/managers/webhooks_manager.rb +4 -3
  55. data/lib/shopify_app/middleware/jwt_middleware.rb +41 -0
  56. data/lib/shopify_app/middleware/same_site_cookie_middleware.rb +2 -1
  57. data/lib/shopify_app/session/in_memory_session_store.rb +7 -3
  58. data/lib/shopify_app/session/in_memory_shop_session_store.rb +14 -0
  59. data/lib/shopify_app/session/in_memory_user_session_store.rb +14 -0
  60. data/lib/shopify_app/session/jwt.rb +61 -0
  61. data/lib/shopify_app/session/null_user_session_store.rb +22 -0
  62. data/lib/shopify_app/session/session_repository.rb +36 -14
  63. data/lib/shopify_app/session/session_storage.rb +1 -10
  64. data/lib/shopify_app/session/shop_session_storage.rb +42 -0
  65. data/lib/shopify_app/session/user_session_storage.rb +42 -0
  66. data/lib/shopify_app/test_helpers/all.rb +2 -0
  67. data/lib/shopify_app/test_helpers/webhook_verification_helper.rb +17 -0
  68. data/lib/shopify_app/utils.rb +6 -5
  69. data/lib/shopify_app/version.rb +2 -1
  70. data/package-lock.json +1231 -1210
  71. data/package.json +1 -1
  72. data/shopify_app.gemspec +13 -8
  73. data/yarn.lock +3 -3
  74. metadata +50 -14
  75. data/lib/shopify_app/session/storage_strategies/shop_storage_strategy.rb +0 -23
  76. data/lib/shopify_app/session/storage_strategies/user_storage_strategy.rb +0 -24
@@ -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 = '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,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,8 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  require 'shopify_app/version'
2
3
 
3
4
  # deps
4
5
  require 'shopify_api'
5
6
  require 'omniauth-shopify-oauth2'
7
+ require 'redirect_safely'
6
8
 
7
9
  module ShopifyApp
8
10
  def self.rails6?
@@ -41,12 +43,17 @@ module ShopifyApp
41
43
  require 'shopify_app/managers/scripttags_manager'
42
44
 
43
45
  # middleware
46
+ require 'shopify_app/middleware/jwt_middleware'
44
47
  require 'shopify_app/middleware/same_site_cookie_middleware'
45
48
 
46
49
  # 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
50
  require 'shopify_app/session/in_memory_session_store'
51
+ require 'shopify_app/session/in_memory_shop_session_store'
52
+ require 'shopify_app/session/in_memory_user_session_store'
53
+ require 'shopify_app/session/jwt'
54
+ require 'shopify_app/session/null_user_session_store'
55
+ require 'shopify_app/session/session_repository'
56
+ require 'shopify_app/session/session_storage'
57
+ require 'shopify_app/session/shop_session_storage'
58
+ require 'shopify_app/session/user_session_storage'
52
59
  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_accessor :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?
@@ -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,88 @@ 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
+ request.env['jwt.shopify_domain']
87
+ end
88
+
89
+ def jwt_shopify_user_id
90
+ request.env['jwt.shopify_user_id']
91
+ end
92
+
61
93
  def redirect_to_login
62
94
  if request.xhr?
63
- head :unauthorized
95
+ head(:unauthorized)
64
96
  else
65
97
  if request.get?
66
98
  path = request.path
@@ -70,18 +102,19 @@ module ShopifyApp
70
102
  path = referer.path
71
103
  query = "#{referer.query}&#{sanitized_params.to_query}"
72
104
  end
73
- session[:return_to] = "#{path}?#{query}"
105
+ session[:return_to] = query.blank? ? path.to_s : "#{path}?#{query}"
74
106
  redirect_to(login_url_with_optional_shop)
75
107
  end
76
108
  end
77
109
 
78
110
  def close_session
79
- clear_shop_session
111
+ clear_shopify_session
80
112
  redirect_to(login_url_with_optional_shop)
81
113
  end
82
114
 
83
- def clear_shop_session
84
- session[:shopify] = nil
115
+ def clear_shopify_session
116
+ session[:shop_id] = nil
117
+ session[:user_id] = nil
85
118
  session[:shopify_domain] = nil
86
119
  session[:shopify_user] = nil
87
120
  session[:user_session] = nil
@@ -100,7 +133,7 @@ module ShopifyApp
100
133
  query_params = {}
101
134
  query_params[:shop] = sanitized_params[:shop] if params[:shop].present?
102
135
 
103
- return_to = session[:return_to] || params[:return_to]
136
+ return_to = RedirectSafely.make_safe(session[:return_to] || params[:return_to], nil)
104
137
 
105
138
  if return_to.present? && return_to_param_required?
106
139
  query_params[:return_to] = return_to
@@ -123,14 +156,18 @@ module ShopifyApp
123
156
 
124
157
  def fullpage_redirect_to(url)
125
158
  if ShopifyApp.configuration.embedded_app?
126
- render 'shopify_app/shared/redirect', layout: false, locals: { url: url, current_shopify_domain: current_shopify_domain }
159
+ render('shopify_app/shared/redirect', layout: false,
160
+ locals: { url: url, current_shopify_domain: current_shopify_domain })
127
161
  else
128
- redirect_to url
162
+ redirect_to(url)
129
163
  end
130
164
  end
131
165
 
132
166
  def current_shopify_domain
133
- shopify_domain = sanitized_shop_name || session[:shopify_domain]
167
+ shopify_domain = sanitized_shop_name ||
168
+ jwt_shopify_domain ||
169
+ session[:shopify_domain]
170
+
134
171
  return shopify_domain if shopify_domain.present?
135
172
 
136
173
  raise ShopifyDomainNotFound
@@ -165,11 +202,16 @@ module ShopifyApp
165
202
  end
166
203
 
167
204
  def return_address
205
+ return base_return_address unless ShopifyApp.configuration.allow_jwt_authentication
206
+ return_address_with_params(shop: current_shopify_domain)
207
+ end
208
+
209
+ def base_return_address
168
210
  session.delete(:return_to) || ShopifyApp.configuration.root_url
169
211
  end
170
212
 
171
213
  def return_address_with_params(params)
172
- uri = URI(return_address)
214
+ uri = URI(base_return_address)
173
215
  uri.query = CGI.parse(uri.query.to_s)
174
216
  .symbolize_keys
175
217
  .transform_values { |v| v.one? ? v.first : v }