diff --git a/config/application.rb b/config/application.rb index f54fca0e4f..c835223d4e 100644 --- a/config/application.rb +++ b/config/application.rb @@ -21,9 +21,9 @@ require "rails" end require_relative "../lib/open_food_network/i18n_config" - require_relative '../lib/spree/core/environment' require_relative '../lib/spree/core/mail_interceptor' +require_relative "../lib/session_cookie_upgrader" if defined?(Bundler) # If you precompile assets before deploying to production, use this line @@ -34,6 +34,15 @@ end module Openfoodnetwork class Application < Rails::Application + config.middleware.insert_before( + ActionDispatch::Cookies, + SessionCookieUpgrader, { + old_key: "_session_id", + new_key: "_ofn_session_id", + domain: "." + ENV["SITE_URL"].delete_prefix("www.") + } + ) if Rails.env.staging? || Rails.env.production? + config.after_initialize do # We need this here because the test env file loads before the Spree engine is loaded Spree::Core::Engine.routes.default_url_options[:host] = 'test.host' if Rails.env == 'test' diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb index d301b88739..f5e1ed786f 100644 --- a/config/initializers/session_store.rb +++ b/config/initializers/session_store.rb @@ -1,10 +1,11 @@ # Be sure to restart your server when you modify this file. -# The cookie_store can be too small for very long URLs stored by Devise. -# The maximum size of cookies is 4096 bytes. -#Openfoodnetwork::Application.config.session_store :cookie_store, key: '_openfoodnetwork_session' - # Use the database for sessions instead of the cookie-based default, # which shouldn't be used to store highly confidential information # (create the session table with "rails generate session_migration") -Openfoodnetwork::Application.config.session_store :active_record_store +Openfoodnetwork::Application.config.session_store( + :active_record_store, + key: "_ofn_session_id", + domain: :all, + tld_length: 2 +) diff --git a/engines/web/app/views/web/angular_templates/cookies_policy.html.haml b/engines/web/app/views/web/angular_templates/cookies_policy.html.haml index 4b00ac32f1..385262ae74 100644 --- a/engines/web/app/views/web/angular_templates/cookies_policy.html.haml +++ b/engines/web/app/views/web/angular_templates/cookies_policy.html.haml @@ -13,7 +13,7 @@ = t 'legal.cookies_policy.essential_cookies_desc' %table{ng: { controller:"CookiesPolicyModalCtrl"}} - = render_cookie_entry( "_session_id", t( "legal.cookies_policy.cookie_session_desc" ) ) + = render_cookie_entry( "_ofn_session_id", t( "legal.cookies_policy.cookie_session_desc" ) ) = render_cookie_entry( "cookies_consent", t( "legal.cookies_policy.cookie_consent_desc" ) ) = render_cookie_entry( "remember_spree_user_token", t( "legal.cookies_policy.cookie_remember_me_desc" ) ) = render_cookie_entry( "qos_token", t( "legal.cookies_policy.cookie_openstreemap_desc" ), "openstreetmap.org" ) diff --git a/engines/web/spec/features/consumer/cookies_spec.rb b/engines/web/spec/features/consumer/cookies_spec.rb index e447364fe2..48c1845b84 100644 --- a/engines/web/spec/features/consumer/cookies_spec.rb +++ b/engines/web/spec/features/consumer/cookies_spec.rb @@ -79,7 +79,7 @@ feature "Cookies", js: true do scenario "shows session_id cookies description with correct instance domain" do visit '/#/policies/cookies' - expect(page).to have_content('_session_id') + expect(page).to have_content('_ofn_session_id') .and have_content('127.0.0.1') end diff --git a/lib/session_cookie_upgrader.rb b/lib/session_cookie_upgrader.rb new file mode 100644 index 0000000000..feb2480760 --- /dev/null +++ b/lib/session_cookie_upgrader.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +class SessionCookieUpgrader + def initialize(app, options = {}) + @app = app + @options = options + end + + def call(env) + request = ::Rack::Request.new(env) + cookies = request.cookies + old_key = @options[:old_key] + new_key = @options[:new_key] + + # Set the session id for this request from the old session cookie (if present) + # This must be done before @app.call(env) or a new session will be initialized + cookies[new_key] = cookies[old_key] if cookies[old_key] + + status, headers, body = @app.call(env) + + if cookies[old_key] + # Create new session cookie with pre-existing session id + Rack::Utils.set_cookie_header!( + headers, + new_key, + { value: cookies[old_key], path: "/", domain: @options[:domain] } + ) + + # Delete old session cookie + Rack::Utils.delete_cookie_header!(headers, old_key) + end + + [status, headers, body] + end +end