shopify_app 12.0.7 → 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 +4 -4
- data/.rubocop.yml +12 -6
- data/.travis.yml +4 -3
- data/CHANGELOG.md +33 -0
- data/Gemfile +3 -0
- data/README.md +98 -42
- data/Rakefile +1 -0
- data/app/controllers/concerns/shopify_app/authenticated.rb +1 -1
- data/app/controllers/shopify_app/authenticated_controller.rb +1 -0
- data/app/controllers/shopify_app/callback_controller.rb +50 -17
- data/app/controllers/shopify_app/sessions_controller.rb +36 -10
- data/app/controllers/shopify_app/webhooks_controller.rb +6 -5
- data/config/locales/fi.yml +1 -1
- data/config/locales/nl.yml +7 -7
- data/config/routes.rb +1 -0
- data/docs/Releasing.md +1 -0
- data/lib/generators/shopify_app/add_after_authenticate_job/add_after_authenticate_job_generator.rb +5 -3
- data/lib/generators/shopify_app/add_after_authenticate_job/templates/after_authenticate_job.rb +1 -0
- data/lib/generators/shopify_app/add_marketing_activity_extension/add_marketing_activity_extension_generator.rb +2 -1
- data/lib/generators/shopify_app/add_marketing_activity_extension/templates/marketing_activities_controller.rb +4 -4
- data/lib/generators/shopify_app/add_webhook/add_webhook_generator.rb +5 -4
- data/lib/generators/shopify_app/add_webhook/templates/{webhook_job.rb → webhook_job.rb.tt} +5 -0
- data/lib/generators/shopify_app/app_proxy_controller/app_proxy_controller_generator.rb +4 -3
- data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_controller.rb +3 -3
- data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_route.rb +10 -9
- data/lib/generators/shopify_app/controllers/controllers_generator.rb +1 -0
- data/lib/generators/shopify_app/home_controller/home_controller_generator.rb +4 -3
- data/lib/generators/shopify_app/home_controller/templates/index.html.erb +1 -1
- data/lib/generators/shopify_app/install/install_generator.rb +10 -9
- data/lib/generators/shopify_app/install/templates/embedded_app.html.erb +1 -1
- data/lib/generators/shopify_app/install/templates/omniauth.rb +2 -1
- data/lib/generators/shopify_app/install/templates/{shopify_app.rb → shopify_app.rb.tt} +1 -1
- data/lib/generators/shopify_app/install/templates/shopify_provider.rb +1 -1
- data/lib/generators/shopify_app/install/templates/user_agent.rb +2 -1
- data/lib/generators/shopify_app/routes/routes_generator.rb +1 -0
- data/lib/generators/shopify_app/routes/templates/routes.rb +10 -9
- data/lib/generators/shopify_app/shop_model/shop_model_generator.rb +12 -7
- data/lib/generators/shopify_app/shop_model/templates/shop.rb +2 -1
- data/lib/generators/shopify_app/shopify_app_generator.rb +4 -3
- data/lib/generators/shopify_app/user_model/templates/user.rb +2 -1
- data/lib/generators/shopify_app/user_model/user_model_generator.rb +12 -7
- data/lib/generators/shopify_app/views/views_generator.rb +1 -0
- data/lib/shopify_app.rb +11 -4
- data/lib/shopify_app/configuration.rb +21 -11
- data/lib/shopify_app/controller_concerns/app_proxy_verification.rb +3 -2
- data/lib/shopify_app/controller_concerns/embedded_app.rb +3 -2
- data/lib/shopify_app/controller_concerns/localization.rb +1 -0
- data/lib/shopify_app/controller_concerns/login_protection.rb +71 -29
- data/lib/shopify_app/controller_concerns/webhook_verification.rb +2 -1
- data/lib/shopify_app/engine.rb +5 -0
- data/lib/shopify_app/jobs/scripttags_manager_job.rb +1 -1
- data/lib/shopify_app/jobs/webhooks_manager_job.rb +1 -1
- data/lib/shopify_app/managers/scripttags_manager.rb +4 -3
- data/lib/shopify_app/managers/webhooks_manager.rb +4 -3
- data/lib/shopify_app/middleware/jwt_middleware.rb +41 -0
- data/lib/shopify_app/middleware/same_site_cookie_middleware.rb +2 -1
- data/lib/shopify_app/session/in_memory_session_store.rb +7 -3
- data/lib/shopify_app/session/in_memory_shop_session_store.rb +14 -0
- data/lib/shopify_app/session/in_memory_user_session_store.rb +14 -0
- data/lib/shopify_app/session/jwt.rb +61 -0
- data/lib/shopify_app/session/null_user_session_store.rb +22 -0
- data/lib/shopify_app/session/session_repository.rb +36 -14
- data/lib/shopify_app/session/session_storage.rb +1 -10
- data/lib/shopify_app/session/shop_session_storage.rb +42 -0
- data/lib/shopify_app/session/user_session_storage.rb +42 -0
- data/lib/shopify_app/test_helpers/all.rb +2 -0
- data/lib/shopify_app/test_helpers/webhook_verification_helper.rb +17 -0
- data/lib/shopify_app/utils.rb +6 -5
- data/lib/shopify_app/version.rb +2 -1
- data/package-lock.json +1231 -1210
- data/package.json +1 -1
- data/shopify_app.gemspec +13 -8
- data/yarn.lock +3 -3
- metadata +50 -14
- data/lib/shopify_app/session/storage_strategies/shop_storage_strategy.rb +0 -23
- 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: (@ | 
| 31 | 
            +
                  shop_origin: (@current_shopify_session.domain if @current_shopify_session),
         | 
| 32 32 | 
             
                  debug: Rails.env.development?
         | 
| 33 33 | 
             
                } ) %>
         | 
| 34 34 |  | 
| @@ -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. | 
| 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,11 +1,12 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 1 2 |  | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 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 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 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 | 
| 12 | 
            +
                    copy_file('shop.rb', 'app/models/shop.rb')
         | 
| 12 13 | 
             
                  end
         | 
| 13 14 |  | 
| 14 15 | 
             
                  def create_shop_migration
         | 
| 15 | 
            -
                    migration_template | 
| 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 | 
| 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 | 
| 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 | 
            -
                   | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 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 | 
             
            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 | 
| 11 | 
            -
                    generate | 
| 11 | 
            +
                    generate("shopify_app:install #{@opts.join(' ')}")
         | 
| 12 | 
            +
                    generate("shopify_app:shop_model")
         | 
| 12 13 | 
             
                    generate("shopify_app:authenticated_controller")
         | 
| 13 | 
            -
                    generate | 
| 14 | 
            +
                    generate("shopify_app:home_controller")
         | 
| 14 15 | 
             
                  end
         | 
| 15 16 | 
             
                end
         | 
| 16 17 | 
             
              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_user_model
         | 
| 11 | 
            -
                    copy_file | 
| 12 | 
            +
                    copy_file('user.rb', 'app/models/user.rb')
         | 
| 12 13 | 
             
                  end
         | 
| 13 14 |  | 
| 14 15 | 
             
                  def create_user_migration
         | 
| 15 | 
            -
                    migration_template | 
| 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 | 
| 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 | 
| 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 | 
            -
                   | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 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
         | 
    
        data/lib/shopify_app.rb
    CHANGED
    
    | @@ -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 | 
| 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 | 
            -
                 | 
| 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 | 
            -
                 | 
| 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  | 
| 56 | 
            -
                   | 
| 57 | 
            -
             | 
| 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 | 
| 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 | 
| 8 | 
            -
                    layout | 
| 8 | 
            +
                    after_action(:set_esdk_headers)
         | 
| 9 | 
            +
                    layout('embedded_app')
         | 
| 9 10 | 
             
                  end
         | 
| 10 11 | 
             
                end
         | 
| 11 12 |  | 
| @@ -11,56 +11,88 @@ module ShopifyApp | |
| 11 11 |  | 
| 12 12 | 
             
                included do
         | 
| 13 13 | 
             
                  after_action :set_test_cookie
         | 
| 14 | 
            -
                  rescue_from ActiveResource::UnauthorizedAccess, : | 
| 14 | 
            +
                  rescue_from ActiveResource::UnauthorizedAccess, with: :close_session
         | 
| 15 15 | 
             
                end
         | 
| 16 16 |  | 
| 17 | 
            -
                def  | 
| 18 | 
            -
                  return redirect_to_login  | 
| 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( | 
| 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  | 
| 30 | 
            -
                   | 
| 31 | 
            -
                     | 
| 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  | 
| 41 | 
            -
                     | 
| 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  | 
| 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 | 
            -
                     | 
| 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 | 
| 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 | 
            -
                   | 
| 111 | 
            +
                  clear_shopify_session
         | 
| 80 112 | 
             
                  redirect_to(login_url_with_optional_shop)
         | 
| 81 113 | 
             
                end
         | 
| 82 114 |  | 
| 83 | 
            -
                def  | 
| 84 | 
            -
                  session[: | 
| 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 | 
| 159 | 
            +
                    render('shopify_app/shared/redirect', layout: false,
         | 
| 160 | 
            +
                           locals: { url: url, current_shopify_domain: current_shopify_domain })
         | 
| 127 161 | 
             
                  else
         | 
| 128 | 
            -
                    redirect_to | 
| 162 | 
            +
                    redirect_to(url)
         | 
| 129 163 | 
             
                  end
         | 
| 130 164 | 
             
                end
         | 
| 131 165 |  | 
| 132 166 | 
             
                def current_shopify_domain
         | 
| 133 | 
            -
                  shopify_domain = sanitized_shop_name || | 
| 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( | 
| 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 }
         |