diff --git a/app/controllers/presence_controller.rb b/app/controllers/presence_controller.rb index 653250a8af9..fe26e68fab1 100644 --- a/app/controllers/presence_controller.rb +++ b/app/controllers/presence_controller.rb @@ -3,6 +3,7 @@ class PresenceController < ApplicationController skip_before_action :check_xhr before_action :ensure_logged_in, only: [:update] + before_action :skip_persist_session MAX_CHANNELS_PER_REQUEST ||= 50 @@ -75,4 +76,12 @@ class PresenceController < ApplicationController render json: response end + private + + def skip_persist_session + # Presence endpoints are often called asynchronously at the same time as other request, + # and never need to modify the session. Skipping ensures that an unneeded cookie rotation + # doesn't race against another request and cause issues. + session.options[:skip] = true + end end diff --git a/spec/requests/presence_controller_spec.rb b/spec/requests/presence_controller_spec.rb index 6fd04bf22e5..279df8a8a0e 100644 --- a/spec/requests/presence_controller_spec.rb +++ b/spec/requests/presence_controller_spec.rb @@ -113,6 +113,25 @@ describe PresenceController do expect(allowed_user_channel.user_ids).to eq([user.id]) expect(allowed_group_channel.user_ids).to eq([user.id]) end + + it "doesn't overwrite the session" do + sign_in(user) + + session_cookie_name = "_forum_session" + get "/session/csrf.json" + expect(response.status).to eq(200) + expect(response.cookies.keys).to include(session_cookie_name) + + client_id = SecureRandom.hex + post "/presence/update.json", params: { + client_id: client_id, + present_channels: [ + ch1.name, + ] + } + expect(response.status).to eq(200) + expect(response.cookies.keys).not_to include(session_cookie_name) + end end describe "#get" do