From f241973a428df3a660a26935ad64730a9b7ffdcb Mon Sep 17 00:00:00 2001 From: Cristina Mariscal Date: Thu, 25 May 2023 04:49:46 -0600 Subject: [PATCH] Adding CORS domain restriction based on webwidget url --- app/controllers/widgets_controller.rb | 8 ++++ config/initializers/cors.rb | 64 ++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/app/controllers/widgets_controller.rb b/app/controllers/widgets_controller.rb index 70e4c967b0108..16370c8ae4846 100644 --- a/app/controllers/widgets_controller.rb +++ b/app/controllers/widgets_controller.rb @@ -9,6 +9,7 @@ class WidgetsController < ActionController::Base before_action :set_token before_action :set_contact before_action :build_contact + before_action :check_domain after_action :allow_iframe_requests private @@ -24,6 +25,13 @@ def set_web_widget render json: { error: 'web widget does not exist' }, status: :not_found end + def check_domain + return if request.base_url.downcase.start_with? @web_widget.website_url.downcase + + Rails.logger.error('web widget does not match with expected domain') + render json: { error: 'web widget does not match with expected domain' }, status: :not_found + end + def set_token @token = permitted_params[:cw_conversation] @auth_token_params = if @token.present? diff --git a/config/initializers/cors.rb b/config/initializers/cors.rb index 1d516370fe6bc..daf81190271af 100644 --- a/config/initializers/cors.rb +++ b/config/initializers/cors.rb @@ -1,18 +1,58 @@ # config/initializers/cors.rb # ref: https://github.com/cyu/rack-cors -# font cors issue with CDN -# Ref: https://stackoverflow.com/questions/56960709/rails-font-cors-policy -Rails.application.config.middleware.insert_before 0, Rack::Cors do - allow do - origins '*' - resource '/packs/*', headers: :any, methods: [:get, :options] - resource '/audio/*', headers: :any, methods: [:get, :options] - # Make the public endpoints accessible to the frontend - resource '/public/api/*', headers: :any, methods: :any - - if ActiveModel::Type::Boolean.new.cast(ENV.fetch('CW_API_ONLY_SERVER', false)) || Rails.env.development? - resource '*', headers: :any, methods: :any, expose: %w[access-token client uid expiry] +# rubocop:disable Rails/ApplicationRecord +class WebWidget < ActiveRecord::Base + self.table_name = 'channel_web_widgets' +end +# rubocop:enable Rails/ApplicationRecord + +unless ENV.fetch('FRONTEND_URL', nil).nil? + Rails.application.config.middleware.insert_before 0, Rack::Cors do + allow do + origins ENV.fetch('FRONTEND_URL', '') + resource '/packs/*', headers: :any, methods: [:get, :options] + resource '/audio/*', headers: :any, methods: [:get, :options] + # Make the public endpoints accessible to the frontend + resource '/public/api/*', headers: :any, methods: :any + + if ActiveModel::Type::Boolean.new.cast(ENV.fetch('CW_API_ONLY_SERVER', false)) || Rails.env.development? + resource '*', headers: :any, methods: :any, expose: %w[access-token client uid expiry] + end + end + end +end + +if ENV.fetch('CORS_WIDGET_CONFIG', true) + WebWidget.all.each do |widget| + # font cors issue with CDN + # Ref: https://stackoverflow.com/questions/56960709/rails-font-cors-policy + Rails.application.config.middleware.insert_before 0, Rack::Cors do + allow do + origins widget.website_url + resource '/packs/*', headers: :any, methods: [:get, :options] + resource '/audio/*', headers: :any, methods: [:get, :options] + # Make the public endpoints accessible to the frontend + resource '/public/api/*', headers: :any, methods: :any + + if ActiveModel::Type::Boolean.new.cast(ENV.fetch('CW_API_ONLY_SERVER', false)) || Rails.env.development? + resource '*', headers: :any, methods: :any, expose: %w[access-token client uid expiry] + end + end + end + end +else + Rails.application.config.middleware.insert_before 0, Rack::Cors do + allow do + origins '*' + resource '/packs/*', headers: :any, methods: [:get, :options] + resource '/audio/*', headers: :any, methods: [:get, :options] + # Make the public endpoints accessible to the frontend + resource '/public/api/*', headers: :any, methods: :any + + if ActiveModel::Type::Boolean.new.cast(ENV.fetch('CW_API_ONLY_SERVER', false)) || Rails.env.development? + resource '*', headers: :any, methods: :any, expose: %w[access-token client uid expiry] + end end end end