fix(voice): scope all VoiceController Call lookups to the inbox

Every Call lookup in the Twilio webhook controller is now constrained
to the inbox resolved from the URL phone number. Prevents tampered
params from attaching the agent leg or outbound leg to a Call belonging
to another inbox/account.

Factored out the common `inbox_calls` scope used by
find_call_for_agent, sync_outbound_leg, and find_call_for_conference!.
This commit is contained in:
Muhsin
2026-04-17 22:49:46 +04:00
parent 91da28a329
commit d62037676c
@@ -98,17 +98,21 @@ class Twilio::VoiceController < ApplicationController
sid = params[:call_sid].presence
raise ArgumentError, 'call_sid is required for agent leg' if sid.blank?
Call.find_by!(provider: :twilio, provider_call_id: sid)
inbox_calls.find_by!(provider_call_id: sid)
end
def sync_outbound_leg(call_sid:, direction:)
parent_sid = params['ParentCallSid'].presence
lookup_sid = direction == 'outbound-dial' ? parent_sid || call_sid : call_sid
call = Call.find_by!(provider: :twilio, provider_call_id: lookup_sid)
call = inbox_calls.find_by!(provider_call_id: lookup_sid)
Voice::CallSessionSyncService.new(call: call, parent_call_sid: parent_sid).perform
end
def inbox_calls
Call.where(inbox_id: inbox.id, provider: :twilio)
end
def conference_twiml(call)
Twilio::TwiML::VoiceResponse.new.tap do |response|
response.dial do |dial|
@@ -137,7 +141,6 @@ class Twilio::VoiceController < ApplicationController
end
def find_call_for_conference!(friendly_name:, call_sid:)
inbox_calls = Call.where(inbox_id: inbox.id, provider: :twilio)
name = friendly_name.to_s
call = inbox_calls.by_conference_sid(name).first if name.present?
call || inbox_calls.find_by!(provider_call_id: call_sid)