2025-09-05 14:09:06 +02:00

66 lines
1.5 KiB
Ruby

require 'sinatra'
require 'json'
require 'openssl'
SERVER_PORT = 5080
MAX_WEBHOOK_AGE = 120 * 1000 # 2 minutes in milliseconds
OPENVIDU_MEET_API_KEY = 'meet-api-key'
set :port, SERVER_PORT
set :bind, '0.0.0.0'
set :environment, :production
disable :protection
post '/webhook' do
body_content = request.body.read
begin
body = JSON.parse(body_content)
rescue JSON::ParserError
status 400
return 'Invalid JSON'
end
headers = {}
request.env.each do |key, value|
if key.start_with?('HTTP_')
header_name = key[5..-1].downcase.gsub('_', '-')
headers[header_name] = value
end
end
unless webhook_event_valid?(body, headers)
puts 'Invalid webhook signature'
status 401
return 'Invalid webhook signature'
end
puts "Webhook received: #{body_content}"
status 200
''
end
def webhook_event_valid?(body, headers)
signature = headers['x-signature']
timestamp_str = headers['x-timestamp']
return false if signature.nil? || timestamp_str.nil?
begin
timestamp = Integer(timestamp_str)
rescue ArgumentError
return false
end
current = (Time.now.to_f * 1000).to_i
diff_time = current - timestamp
return false if diff_time >= MAX_WEBHOOK_AGE
signed_payload = "#{timestamp}.#{body.to_json}"
expected = OpenSSL::HMAC.hexdigest('SHA256', OPENVIDU_MEET_API_KEY, signed_payload)
OpenSSL.fixed_length_secure_compare(expected, signature)
end
puts "Webhook server listening on port #{SERVER_PORT}"