From 6bdb9d85721cca5804d3512b3adc9a4e60068ee5 Mon Sep 17 00:00:00 2001 From: Hampton Lintorn-Catlin Date: Wed, 17 Jun 2026 14:22:14 +0100 Subject: [PATCH] Fix ActionCable request fallback Amp-Thread-ID: https://ampcode.com/threads/T-019ed5b7-79c3-72b4-baf5-8fce6488f470 Co-authored-by: Amp --- .../channels/coplan/plan_presence_channel.rb | 2 +- .../coplan/plan_presence_channel_spec.rb | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/engine/app/channels/coplan/plan_presence_channel.rb b/engine/app/channels/coplan/plan_presence_channel.rb index e6ee4a8a..31235cc7 100644 --- a/engine/app/channels/coplan/plan_presence_channel.rb +++ b/engine/app/channels/coplan/plan_presence_channel.rb @@ -40,7 +40,7 @@ def current_user def resolve_current_user return connection.current_user if connection.respond_to?(:current_user) && connection.current_user - CoPlan::Authentication.user_from_request(connection.request) + CoPlan::Authentication.user_from_request(connection.__send__(:request)) end def broadcast_viewers diff --git a/spec/channels/coplan/plan_presence_channel_spec.rb b/spec/channels/coplan/plan_presence_channel_spec.rb index 9e7da87f..9d1916dc 100644 --- a/spec/channels/coplan/plan_presence_channel_spec.rb +++ b/spec/channels/coplan/plan_presence_channel_spec.rb @@ -30,6 +30,29 @@ expect(CoPlan::PlanViewer.where(plan: plan, user: websocket_user)).to exist end + it "authenticates through the engine callback when ActionCable keeps the request private" do + request = ActionDispatch::Request.empty + private_request_connection = Class.new do + def initialize(request) + @request = request + end + + private + + attr_reader :request + end.new(request) + channel = described_class.allocate + allow(channel).to receive(:connection).and_return(private_request_connection) + allow(CoPlan.configuration).to receive(:authenticate).and_return( + ->(received_request) { { external_id: "private-request-user", name: received_request.object_id.to_s } } + ) + + websocket_user = channel.send(:resolve_current_user) + + expect(websocket_user.external_id).to eq("private-request-user") + expect(websocket_user.name).to eq(request.object_id.to_s) + end + it "rejects when plan does not exist" do subscribe(plan_id: "nonexistent") expect(subscription).to be_rejected