From ec2f27f258b4016125a571b31972802dfd9bb247 Mon Sep 17 00:00:00 2001 From: Damon Foster Date: Tue, 11 Mar 2025 11:12:40 +0000 Subject: [PATCH] Require domain parameter for Intercom cookie deletion --- lib/intercom-rails/shutdown_helper.rb | 30 ++++++------ spec/shutdown_helper_spec.rb | 66 +++++++++++++++------------ 2 files changed, 53 insertions(+), 43 deletions(-) diff --git a/lib/intercom-rails/shutdown_helper.rb b/lib/intercom-rails/shutdown_helper.rb index 8256790..99d2b08 100644 --- a/lib/intercom-rails/shutdown_helper.rb +++ b/lib/intercom-rails/shutdown_helper.rb @@ -1,27 +1,31 @@ module IntercomRails module ShutdownHelper - # This helper allows to erase cookies when a user log out of an application - # It is recommanded to call this function every time a user log out of your application + # This helper allows to erase cookies when a user logs out of an application + # It is recommended to call this function every time a user logs out of your application # Do not use before a redirect_to because it will not clear the cookies on a redirection - def self.intercom_shutdown_helper(cookies, domain = nil) + # + # @param cookies [ActionDispatch::Cookies::CookieJar] The cookies object + # @param domain [String] The domain used for the Intercom cookies (required). + # Specify the same domain that Intercom uses for its cookies + # (typically your main domain with a leading dot, e.g. ".yourdomain.com"). + def self.intercom_shutdown_helper(cookies, domain) nil_session = { value: nil, expires: 1.day.ago } - nil_session = nil_session.merge(domain: domain) unless domain.nil? || domain == 'localhost' - - if (cookies.is_a?(ActionDispatch::Cookies::CookieJar)) - cookies["intercom-session-#{IntercomRails.config.app_id}"] = nil_session - else - controller = cookies - Rails.logger.info("Warning: IntercomRails::ShutdownHelper.intercom_shutdown_helper takes an instance of ActionDispatch::Cookies::CookieJar as an argument since v0.2.34. Passing a controller is depreciated. See https://github.com/intercom/intercom-rails#shutdown for more details.") - controller.response.delete_cookie("intercom-session-#{IntercomRails.config.app_id}", nil_session) + + unless domain == 'localhost' + dotted_domain = domain.start_with?('.') ? domain : ".#{domain}" + nil_session = nil_session.merge(domain: dotted_domain) end - rescue + + cookies["intercom-session-#{IntercomRails.config.app_id}"] = nil_session + rescue => e + Rails.logger.error("Error in intercom_shutdown_helper: #{e.message}") if defined?(Rails) && Rails.logger end def self.prepare_intercom_shutdown(session) session[:perform_intercom_shutdown] = true end - def self.intercom_shutdown(session, cookies, domain = nil) + def self.intercom_shutdown(session, cookies, domain) if session[:perform_intercom_shutdown] session.delete(:perform_intercom_shutdown) intercom_shutdown_helper(cookies, domain) diff --git a/spec/shutdown_helper_spec.rb b/spec/shutdown_helper_spec.rb index 40a1301..fc412f8 100644 --- a/spec/shutdown_helper_spec.rb +++ b/spec/shutdown_helper_spec.rb @@ -3,36 +3,42 @@ describe TestController, type: :controller do include IntercomRails::ShutdownHelper - context 'without domain' do - it 'clears response intercom-session-{app_id} cookie' do - IntercomRails::ShutdownHelper.intercom_shutdown_helper(cookies) - expect(cookies.has_key?('intercom-session-abc123')).to eq true - end - it 'creates session[:perform_intercom_shutdown] var' do - IntercomRails::ShutdownHelper.prepare_intercom_shutdown(session) - expect(session[:perform_intercom_shutdown]).to eq true - end - it 'erase intercom cookie, set preform_intercom_shutdown sessions to nil' do - session[:perform_intercom_shutdown] = true - IntercomRails::ShutdownHelper.intercom_shutdown(session, cookies) - expect(session[:perform_intercom_shutdown]).to eq nil - expect(cookies.has_key?('intercom-session-abc123')).to eq true - end + it 'clears response intercom-session-{app_id} cookie' do + IntercomRails::ShutdownHelper.intercom_shutdown_helper(cookies, 'intercom.com') + expect(cookies.has_key?('intercom-session-abc123')).to eq true end - context 'with domain' do - it 'clears response intercom-session-{app_id} cookie' do - IntercomRails::ShutdownHelper.intercom_shutdown_helper(cookies, 'intercom.com') - expect(cookies.has_key?('intercom-session-abc123')).to eq true - end - it 'creates session[:perform_intercom_shutdown] var' do - IntercomRails::ShutdownHelper.prepare_intercom_shutdown(session) - expect(session[:perform_intercom_shutdown]).to eq true - end - it 'erase intercom cookie, set preform_intercom_shutdown sessions to nil' do - session[:perform_intercom_shutdown] = true - IntercomRails::ShutdownHelper.intercom_shutdown(session, cookies, 'intercom.com') - expect(session[:perform_intercom_shutdown]).to eq nil - expect(cookies.has_key?('intercom-session-abc123')).to eq true - end + it 'creates session[:perform_intercom_shutdown] var' do + IntercomRails::ShutdownHelper.prepare_intercom_shutdown(session) + expect(session[:perform_intercom_shutdown]).to eq true + end + it 'erase intercom cookie, set preform_intercom_shutdown sessions to nil' do + session[:perform_intercom_shutdown] = true + IntercomRails::ShutdownHelper.intercom_shutdown(session, cookies, 'intercom.com') + expect(session[:perform_intercom_shutdown]).to eq nil + expect(cookies.has_key?('intercom-session-abc123')).to eq true + end + it 'adds a leading dot to the domain if not present' do + allow(cookies).to receive(:[]=) + IntercomRails::ShutdownHelper.intercom_shutdown_helper(cookies, 'intercom.com') + expect(cookies).to have_received(:[]=).with( + "intercom-session-#{IntercomRails.config.app_id}", + hash_including(domain: '.intercom.com') + ) + end + it 'keeps the domain as is if it already has a leading dot' do + allow(cookies).to receive(:[]=) + IntercomRails::ShutdownHelper.intercom_shutdown_helper(cookies, '.intercom.com') + expect(cookies).to have_received(:[]=).with( + "intercom-session-#{IntercomRails.config.app_id}", + hash_including(domain: '.intercom.com') + ) + end + it 'handles localhost domain specially' do + allow(cookies).to receive(:[]=) + IntercomRails::ShutdownHelper.intercom_shutdown_helper(cookies, 'localhost') + expect(cookies).to have_received(:[]=).with( + "intercom-session-#{IntercomRails.config.app_id}", + hash_not_including(domain: anything) + ) end end