mirror of
https://github.com/lingble/chatwoot.git
synced 2025-12-25 23:27:15 +00:00
We wanted to provide an option for users to specify the domains on which
they can show the website. The rest of the sites shouldn't see the
widget at all.
It's not possible generally through Origin because you can't get Origin
when loading via an iframe. What I've done is add frame ancestors for
the domains specified in allowed domains. I hope this solves most of the
problems.
This is added in a way that it won't affect existing widgets. Only If
they have configured allowed domains, it will start blocking. Otherwise,
it would follow the previous behavior without any changes.
This change supports called wild card domains as well. You can add a
comma‑separated list of domains, either wild card or regular domains.
---
To test, deploy to staging. Call the following API to update the
allowed_domains list.
```
URL: PATCH /api/v1/accounts/<account-id>/inboxes/<inbox-id>
Payload:
{
"channel": { "allowed_domains": "*.chatwoot.dev,chatwoot.com" }
}
```
Fixes https://github.com/chatwoot/chatwoot/issues/1985
109 lines
3.9 KiB
Ruby
109 lines
3.9 KiB
Ruby
# == Schema Information
|
|
#
|
|
# Table name: channel_web_widgets
|
|
#
|
|
# id :integer not null, primary key
|
|
# allowed_domains :text default("")
|
|
# continuity_via_email :boolean default(TRUE), not null
|
|
# feature_flags :integer default(7), not null
|
|
# hmac_mandatory :boolean default(FALSE)
|
|
# hmac_token :string
|
|
# pre_chat_form_enabled :boolean default(FALSE)
|
|
# pre_chat_form_options :jsonb
|
|
# reply_time :integer default("in_a_few_minutes")
|
|
# website_token :string
|
|
# website_url :string
|
|
# welcome_tagline :string
|
|
# welcome_title :string
|
|
# widget_color :string default("#1f93ff")
|
|
# created_at :datetime not null
|
|
# updated_at :datetime not null
|
|
# account_id :integer
|
|
#
|
|
# Indexes
|
|
#
|
|
# index_channel_web_widgets_on_hmac_token (hmac_token) UNIQUE
|
|
# index_channel_web_widgets_on_website_token (website_token) UNIQUE
|
|
#
|
|
|
|
class Channel::WebWidget < ApplicationRecord
|
|
include Channelable
|
|
include FlagShihTzu
|
|
|
|
self.table_name = 'channel_web_widgets'
|
|
EDITABLE_ATTRS = [:website_url, :widget_color, :welcome_title, :welcome_tagline, :reply_time, :pre_chat_form_enabled,
|
|
:continuity_via_email, :hmac_mandatory, :allowed_domains,
|
|
{ pre_chat_form_options: [:pre_chat_message, :require_email,
|
|
{ pre_chat_fields:
|
|
[:field_type, :label, :placeholder, :name, :enabled, :type, :enabled, :required,
|
|
:locale, { values: [] }, :regex_pattern, :regex_cue] }] },
|
|
{ selected_feature_flags: [] }].freeze
|
|
|
|
before_validation :validate_pre_chat_options
|
|
validates :website_url, presence: true
|
|
validates :widget_color, presence: true
|
|
has_many :portals, foreign_key: 'channel_web_widget_id', dependent: :nullify, inverse_of: :channel_web_widget
|
|
|
|
has_secure_token :website_token
|
|
has_secure_token :hmac_token
|
|
|
|
has_flags 1 => :attachments,
|
|
2 => :emoji_picker,
|
|
3 => :end_conversation,
|
|
4 => :use_inbox_avatar_for_bot,
|
|
:column => 'feature_flags',
|
|
:check_for_column => false
|
|
|
|
enum reply_time: { in_a_few_minutes: 0, in_a_few_hours: 1, in_a_day: 2 }
|
|
|
|
def name
|
|
'Website'
|
|
end
|
|
|
|
def web_widget_script
|
|
"
|
|
<script>
|
|
(function(d,t) {
|
|
var BASE_URL=\"#{ENV.fetch('FRONTEND_URL', '')}\";
|
|
var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
|
|
g.src=BASE_URL+\"/packs/js/sdk.js\";
|
|
g.async = true;
|
|
s.parentNode.insertBefore(g,s);
|
|
g.onload=function(){
|
|
window.chatwootSDK.run({
|
|
websiteToken: '#{website_token}',
|
|
baseUrl: BASE_URL
|
|
})
|
|
}
|
|
})(document,\"script\");
|
|
</script>
|
|
"
|
|
end
|
|
|
|
def validate_pre_chat_options
|
|
return if pre_chat_form_options.with_indifferent_access['pre_chat_fields'].present?
|
|
|
|
self.pre_chat_form_options = {
|
|
pre_chat_message: 'Share your queries or comments here.',
|
|
pre_chat_fields: [
|
|
{
|
|
'field_type': 'standard', 'label': 'Email Id', 'name': 'emailAddress', 'type': 'email', 'required': true, 'enabled': false
|
|
},
|
|
{
|
|
'field_type': 'standard', 'label': 'Full name', 'name': 'fullName', 'type': 'text', 'required': false, 'enabled': false
|
|
},
|
|
{
|
|
'field_type': 'standard', 'label': 'Phone number', 'name': 'phoneNumber', 'type': 'text', 'required': false, 'enabled': false
|
|
}
|
|
]
|
|
}
|
|
end
|
|
|
|
def create_contact_inbox(additional_attributes = {})
|
|
::ContactInboxWithContactBuilder.new({
|
|
inbox: inbox,
|
|
contact_attributes: { additional_attributes: additional_attributes }
|
|
}).perform
|
|
end
|
|
end
|