From 4343facea5a1c89356c0224b0413633caa99adbf Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Tue, 20 Dec 2022 14:59:06 +0000 Subject: [PATCH 1/5] Add check for checkout (replace duplicate on API) --- lib/spree/auth/engine.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/spree/auth/engine.rb b/lib/spree/auth/engine.rb index 01ed4480..8867ff77 100644 --- a/lib/spree/auth/engine.rb +++ b/lib/spree/auth/engine.rb @@ -48,8 +48,8 @@ def self.activate ApplicationController.send :include, Spree::AuthenticationHelpers end - def self.api_available? - @@api_available ||= ::Rails::Engine.subclasses.map(&:instance).map{ |e| e.class.to_s }.include?('Spree::Api::Engine') + def self.checkout_available? + @@checkout_available ||= ::Rails::Engine.subclasses.map(&:instance).map{ |e| e.class.to_s }.include?('Spree::Checkout::Engine') end def self.backend_available? From 178fcdfb9b8c8268477bb6089d79d7547138d9eb Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Tue, 20 Dec 2022 15:00:18 +0000 Subject: [PATCH 2/5] Add adaptive routes, if using stand-alone checkout. --- config/routes.rb | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index 4d075165..bd319530 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -25,9 +25,19 @@ if Spree::Core::Engine.frontend_available? resources :users, only: [:edit, :update] - get '/checkout/registration' => 'checkout#registration', :as => :checkout_registration - put '/checkout/registration' => 'checkout#update_registration', :as => :update_checkout_registration resource :account, controller: 'users' + + unless Spree::Auth::Engine.checkout_available? + get '/checkout/registration' => 'checkout#registration', :as => :checkout_registration + put '/checkout/registration' => 'checkout#update_registration', :as => :update_checkout_registration + end + end + + if Spree::Auth::Engine.checkout_available? + namespace :checkout do + get :registration, to: 'orders#registration', as: :registration + put :registration, to: 'orders#update_registration', as: :update_registration + end end if Spree.respond_to?(:admin_path) && Spree::Core::Engine.backend_available? From 21cb60b2770932854f073119d694da50e0802f96 Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Tue, 20 Dec 2022 15:00:40 +0000 Subject: [PATCH 3/5] Add decorator for stand-alone checkout controller. --- .../checkout/orders_controller_decorator.rb | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 lib/controllers/checkout/spree/auth/checkout/orders_controller_decorator.rb diff --git a/lib/controllers/checkout/spree/auth/checkout/orders_controller_decorator.rb b/lib/controllers/checkout/spree/auth/checkout/orders_controller_decorator.rb new file mode 100644 index 00000000..f45b01f6 --- /dev/null +++ b/lib/controllers/checkout/spree/auth/checkout/orders_controller_decorator.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module Spree + module Auth + module Checkout + # + # Adds methods to Spree Checkout Orders + module OrdersControllerDecorator + def self.prepended(base) + base.before_action :check_authorization + base.before_action :check_registration, except: %i[registration update_registration] + end + + def registration + @user = Spree.user_class.new + @title = Spree.t(:registration) + end + + def update_registration + if order_params[:email] =~ Devise.email_regexp && current_order.update_attribute(:email, order_params[:email]) + redirect_to spree.checkout_state_path(:address) + else + flash[:error] = t(:email_is_invalid, scope: %i[errors messages]) + @user = Spree.user_class.new + render 'registration', status: :unprocessable_entity + end + end + + private + + def order_params + params[:order].present? ? params.require(:order).permit(:email) : {} + end + + def skip_state_validation? + %w[registration update_registration].include?(params[:action]) + end + + def check_authorization + authorize!(:edit, current_order, cookies.signed[:guest_token]) + end + + # Introduces a registration step whenever the +registration_step+ preference is true. + def check_registration + return unless Spree::Auth::Config[:registration_step] + return if spree_current_user || current_order.email + + store_location + redirect_to spree.checkout_registration_path + end + + Spree::Checkout::OrdersController.prepend(self) if ::Spree::Checkout::OrdersController.included_modules.exclude?(self) + end + end + end +end From 56d2069c38d429b7d0487d203968d2e5dc85bba9 Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Thu, 22 Dec 2022 10:28:31 +0000 Subject: [PATCH 4/5] Fix missing decorator. --- lib/spree/auth/engine.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/spree/auth/engine.rb b/lib/spree/auth/engine.rb index 8867ff77..ceb0ec37 100644 --- a/lib/spree/auth/engine.rb +++ b/lib/spree/auth/engine.rb @@ -30,6 +30,11 @@ def self.activate Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c| Rails.configuration.cache_classes ? require(c) : load(c) end + if Spree::Auth::Engine.checkout_available? + Dir.glob(File.join(File.dirname(__FILE__), "../../controllers/checkout/*/*/*/*_decorator*.rb")) do |c| + Rails.configuration.cache_classes ? require(c) : load(c) + end + end if Spree::Auth::Engine.backend_available? Dir.glob(File.join(File.dirname(__FILE__), "../../controllers/backend/*/*/*_decorator*.rb")) do |c| Rails.configuration.cache_classes ? require(c) : load(c) From f2c79c18caf478051dfda6978579f984a64bb960 Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Fri, 23 Dec 2022 13:53:12 +0000 Subject: [PATCH 5/5] Use the controller for storefornt sessions. --- .../spree/user_sessions_controller.rb | 86 +++++++++++++++++++ lib/spree/auth/engine.rb | 8 +- 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 lib/controllers/checkout/spree/user_sessions_controller.rb diff --git a/lib/controllers/checkout/spree/user_sessions_controller.rb b/lib/controllers/checkout/spree/user_sessions_controller.rb new file mode 100644 index 00000000..690116b2 --- /dev/null +++ b/lib/controllers/checkout/spree/user_sessions_controller.rb @@ -0,0 +1,86 @@ +class Spree::UserSessionsController < Devise::SessionsController + helper 'spree/base' + + include Spree::Core::ControllerHelpers::Auth + include Spree::Core::ControllerHelpers::Common + include Spree::Core::ControllerHelpers::Order + include Spree::Core::ControllerHelpers::Store + + include SpreeI18n::ControllerLocaleHelper if defined?(SpreeI18n::ControllerLocaleHelper) + + include Spree::Core::ControllerHelpers::Currency if defined?(Spree::Core::ControllerHelpers::Currency) + include Spree::Core::ControllerHelpers::Locale if defined?(Spree::Core::ControllerHelpers::Locale) + + include Spree::LocaleUrls if defined?(Spree::LocaleUrls) + + helper 'spree/locale' if defined?(Spree::LocaleHelper) + helper 'spree/currency' if defined?(Spree::CurrencyHelper) + helper 'spree/store' if defined?(Spree::StoreHelper) + + before_action :set_current_order + + def create + authenticate_spree_user! + + if spree_user_signed_in? + respond_to do |format| + format.html { + flash[:success] = Spree.t(:logged_in_successfully) + redirect_back_or_default(after_sign_in_redirect(spree_current_user)) + } + format.js { + render json: { user: spree_current_user, + ship_address: spree_current_user.ship_address, + bill_address: spree_current_user.bill_address }.to_json + } + end + else + respond_to do |format| + format.html { + flash.now[:error] = t('devise.failure.invalid') + render :new, status: :unprocessable_entity + } + format.js { + render json: { error: t('devise.failure.invalid') }, status: :unprocessable_entity + } + end + end + end + + protected + + def translation_scope + 'devise.user_sessions' + end + + private + + def accurate_title + Spree.t(:login) + end + + def redirect_back_or_default(default) + redirect_to(session["spree_user_return_to"] || default) + session["spree_user_return_to"] = nil + end + + def after_sign_in_redirect(resource_or_scope) + stored_location_for(resource_or_scope) || spree.account_path + end + + def respond_to_on_destroy + # We actually need to hardcode this as Rails default responder doesn't + # support returning empty response on GET request + respond_to do |format| + format.all { head :no_content } + format.any(*navigational_formats) { redirect_to after_sign_out_redirect(resource_name) } + end + end + + def after_sign_out_redirect(resource_or_scope) + scope = Devise::Mapping.find_scope!(resource_or_scope) + router_name = Devise.mappings[scope].router_name + context = router_name ? send(router_name) : self + context.respond_to?(:login_path) ? context.login_path(locale_param) : spree.root_path + end +end diff --git a/lib/spree/auth/engine.rb b/lib/spree/auth/engine.rb index ceb0ec37..081186af 100644 --- a/lib/spree/auth/engine.rb +++ b/lib/spree/auth/engine.rb @@ -31,7 +31,7 @@ def self.activate Rails.configuration.cache_classes ? require(c) : load(c) end if Spree::Auth::Engine.checkout_available? - Dir.glob(File.join(File.dirname(__FILE__), "../../controllers/checkout/*/*/*/*_decorator*.rb")) do |c| + Dir.glob(File.join(File.dirname(__FILE__), "../../controllers/checkout/**/*_decorator*.rb")) do |c| Rails.configuration.cache_classes ? require(c) : load(c) end end @@ -50,6 +50,7 @@ def self.activate Rails.configuration.cache_classes ? require(c) : load(c) end end + ApplicationController.send :include, Spree::AuthenticationHelpers end @@ -73,6 +74,11 @@ def self.emails_available? @@emails_available ||= ::Rails::Engine.subclasses.map(&:instance).map{ |e| e.class.to_s }.include?('Spree::Emails::Engine') end + if checkout_available? + paths["app/controllers"] << "lib/controllers/checkout" + paths["app/views"] << "lib/views/checkout" + end + if backend_available? paths["app/controllers"] << "lib/controllers/backend" paths["app/views"] << "lib/views/backend"