feature/DEV-185567,DEV-185564/Handled chat wdigit jwt token lacks expiration and chat widget loading on allowed domains
This commit is contained in:
@@ -6,6 +6,7 @@ class WidgetsController < ActionController::Base
|
||||
before_action :set_web_widget
|
||||
before_action :ensure_account_is_active
|
||||
before_action :ensure_location_is_supported
|
||||
before_action :validate_origin_domain
|
||||
before_action :set_token
|
||||
before_action :set_contact
|
||||
before_action :build_contact
|
||||
@@ -24,6 +25,75 @@ class WidgetsController < ActionController::Base
|
||||
render json: { error: 'web widget does not exist' }, status: :not_found
|
||||
end
|
||||
|
||||
def validate_origin_domain
|
||||
# Only validate origin if website_url is configured
|
||||
return if @web_widget.website_url.blank?
|
||||
|
||||
origin_domain = extract_domain_from_origin
|
||||
return if domain_allowed?(origin_domain, @web_widget.website_url)
|
||||
|
||||
Rails.logger.warn('Widget access denied.')
|
||||
render json: { error: 'Widget access denied.' }, status: :forbidden
|
||||
end
|
||||
|
||||
def domain_allowed?(origin_domain, website_url)
|
||||
return false if origin_domain.blank?
|
||||
|
||||
# Split website_url by comma to handle multiple domains/wildcards
|
||||
allowed_domains = website_url.split(',').map(&:strip).reject(&:blank?)
|
||||
|
||||
allowed_domains.any? do |allowed_domain|
|
||||
# Extract domain and protocol from the allowed domain
|
||||
allowed_domain_without_protocol = extract_domain_from_url(allowed_domain)
|
||||
allowed_protocol = extract_protocol_from_url(allowed_domain)
|
||||
origin_protocol = extract_protocol_from_origin
|
||||
|
||||
# Check if the extracted domain starts with wildcard
|
||||
if allowed_domain_without_protocol&.start_with?('*.')
|
||||
# Handle wildcard domains (e.g., "*.example.com")
|
||||
wildcard_suffix = allowed_domain_without_protocol[2..-1] # Remove "*.", keep "example.com"
|
||||
origin_domain.end_with?(wildcard_suffix) && origin_protocol == allowed_protocol
|
||||
else
|
||||
# Handle exact domain and protocol match
|
||||
origin_domain == allowed_domain_without_protocol && origin_protocol == allowed_protocol
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def extract_domain_from_origin
|
||||
origin = request.headers['Origin']
|
||||
return nil if origin.blank?
|
||||
|
||||
extract_domain_from_url(origin)
|
||||
end
|
||||
|
||||
def extract_protocol_from_origin
|
||||
origin = request.headers['Origin']
|
||||
return nil if origin.blank?
|
||||
|
||||
extract_protocol_from_url(origin)
|
||||
end
|
||||
|
||||
def extract_domain_from_url(url)
|
||||
return nil if url.blank?
|
||||
|
||||
# Parse the URL and extract the domain
|
||||
uri = URI.parse(url)
|
||||
uri.host&.downcase
|
||||
rescue URI::InvalidURIError
|
||||
nil
|
||||
end
|
||||
|
||||
def extract_protocol_from_url(url)
|
||||
return nil if url.blank?
|
||||
|
||||
# Parse the URL and extract the protocol
|
||||
uri = URI.parse(url)
|
||||
uri.scheme&.downcase
|
||||
rescue URI::InvalidURIError
|
||||
nil
|
||||
end
|
||||
|
||||
def set_token
|
||||
@token = permitted_params[:cw_conversation]
|
||||
@auth_token_params = if @token.present?
|
||||
|
||||
Reference in New Issue
Block a user