mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-10-30 18:47:51 +00:00 
			
		
		
		
	Chore: Feature lock email settings in UI (#1065)
* Chore: Feature lock email settings in UI The email settings under account settings needed to be feature locked in a way different from teh current way for it to be enabled for accounts in a self hosted scenario. Some refactorings were also done along with this change. 1. There was a feature flag defined in code in account model called domain_emails_enabled was used to check if the inbound emails was enabled for the account. But there was already a feature flag called "inbound_emails" defined in features.yml. So changed to use this to check if inbound emails are enabled for an account. 2. Renamed and re-purposed existing `domain_emails_enabled` to `custom_email_domain_enabled` to use for feature toggling the UI for email settings. 3. To enable & disable multiple features using the featurable concern we were passing an array of values. Changed this to accept a comma separated set of values. * Chore: Feature lock email settings in UI Fixed the specs for accounts controller & removed unneccessary code from Account seetings component in UI * Chore: Convert newlines to <br>s Removed the layout used while sending replies in conversation continuity. Converted the newlines in the messages to <br/> tags for the correct HTML rendering. * Chore: Bug fix in reply email domain Renamed the function custom_email_domain_enabled to inbound_email_enabled. Fixed bug on setting reply emails's domain.
This commit is contained in:
		| @@ -32,7 +32,7 @@ class Api::V1::AccountsController < Api::BaseController | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   def update |   def update | ||||||
|     @account.update!(account_params.slice(:name, :locale, :domain, :support_email, :domain_emails_enabled)) |     @account.update!(account_params.slice(:name, :locale, :domain, :support_email)) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def update_active_at |   def update_active_at | ||||||
| @@ -57,7 +57,7 @@ class Api::V1::AccountsController < Api::BaseController | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   def account_params |   def account_params | ||||||
|     params.permit(:account_name, :email, :name, :locale, :domain, :support_email, :domain_emails_enabled) |     params.permit(:account_name, :email, :name, :locale, :domain, :support_email) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def check_signup_enabled |   def check_signup_enabled | ||||||
|   | |||||||
| @@ -24,8 +24,8 @@ | |||||||
|         "ERROR": "" |         "ERROR": "" | ||||||
|       }, |       }, | ||||||
|       "DOMAIN": { |       "DOMAIN": { | ||||||
|         "LABEL": "Domain", |         "LABEL": "Incoming Email Domain", | ||||||
|         "PLACEHOLDER": "Your website domain", |         "PLACEHOLDER": "The domain where you will receive the emails", | ||||||
|         "ERROR": "" |         "ERROR": "" | ||||||
|       }, |       }, | ||||||
|       "SUPPORT_EMAIL": { |       "SUPPORT_EMAIL": { | ||||||
| @@ -33,14 +33,9 @@ | |||||||
|         "PLACEHOLDER": "Your company's support email", |         "PLACEHOLDER": "Your company's support email", | ||||||
|         "ERROR": "" |         "ERROR": "" | ||||||
|       }, |       }, | ||||||
|       "ENABLE_DOMAIN_EMAIL": { |       "FEATURES": { | ||||||
|         "LABEL": "Enable domain email", |         "INBOUND_EMAIL_ENABLED": "Conversation continuity with emails is enabled for your account.", | ||||||
|         "PLACEHOLDER": "Enable the custom domain email", |         "CUSTOM_EMAIL_DOMAIN_ENABLED": "You can receive emails in your custom domain now." | ||||||
|         "ERROR": "", |  | ||||||
|         "OPTIONS": { |  | ||||||
|           "ENABLED": "Enabled", |  | ||||||
|           "DISABLED": "Disabled" |  | ||||||
|         } |  | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -36,7 +36,15 @@ | |||||||
|               {{ $t('GENERAL_SETTINGS.FORM.LANGUAGE.ERROR') }} |               {{ $t('GENERAL_SETTINGS.FORM.LANGUAGE.ERROR') }} | ||||||
|             </span> |             </span> | ||||||
|           </label> |           </label> | ||||||
|           <label> |           <label v-if="featureInboundEmailEnabled"> | ||||||
|  |             {{ $t('GENERAL_SETTINGS.FORM.FEATURES.INBOUND_EMAIL_ENABLED') }} | ||||||
|  |           </label> | ||||||
|  |           <label v-if="featureCustomDomainEmailEnabled"> | ||||||
|  |             {{ | ||||||
|  |               $t('GENERAL_SETTINGS.FORM.FEATURES.CUSTOM_EMAIL_DOMAIN_ENABLED') | ||||||
|  |             }} | ||||||
|  |           </label> | ||||||
|  |           <label v-if="featureCustomDomainEmailEnabled"> | ||||||
|             {{ $t('GENERAL_SETTINGS.FORM.DOMAIN.LABEL') }} |             {{ $t('GENERAL_SETTINGS.FORM.DOMAIN.LABEL') }} | ||||||
|             <input |             <input | ||||||
|               v-model="domain" |               v-model="domain" | ||||||
| @@ -44,29 +52,7 @@ | |||||||
|               :placeholder="$t('GENERAL_SETTINGS.FORM.DOMAIN.PLACEHOLDER')" |               :placeholder="$t('GENERAL_SETTINGS.FORM.DOMAIN.PLACEHOLDER')" | ||||||
|             /> |             /> | ||||||
|           </label> |           </label> | ||||||
|           <label v-if="featureInboundEmailEnabled"> |           <label v-if="featureCustomDomainEmailEnabled"> | ||||||
|             {{ $t('GENERAL_SETTINGS.FORM.ENABLE_DOMAIN_EMAIL.LABEL') }} |  | ||||||
|             <select v-model="domainEmailsEnabled"> |  | ||||||
|               <option value="true"> |  | ||||||
|                 {{ |  | ||||||
|                   $t( |  | ||||||
|                     'GENERAL_SETTINGS.FORM.ENABLE_DOMAIN_EMAIL.OPTIONS.ENABLED' |  | ||||||
|                   ) |  | ||||||
|                 }} |  | ||||||
|               </option> |  | ||||||
|               <option value="false"> |  | ||||||
|                 {{ |  | ||||||
|                   $t( |  | ||||||
|                     'GENERAL_SETTINGS.FORM.ENABLE_DOMAIN_EMAIL.OPTIONS.DISABLED' |  | ||||||
|                   ) |  | ||||||
|                 }} |  | ||||||
|               </option> |  | ||||||
|             </select> |  | ||||||
|             <p class="help-text"> |  | ||||||
|               {{ $t('GENERAL_SETTINGS.FORM.ENABLE_DOMAIN_EMAIL.PLACEHOLDER') }} |  | ||||||
|             </p> |  | ||||||
|           </label> |  | ||||||
|           <label v-if="featureInboundEmailEnabled"> |  | ||||||
|             {{ $t('GENERAL_SETTINGS.FORM.SUPPORT_EMAIL.LABEL') }} |             {{ $t('GENERAL_SETTINGS.FORM.SUPPORT_EMAIL.LABEL') }} | ||||||
|             <input |             <input | ||||||
|               v-model="supportEmail" |               v-model="supportEmail" | ||||||
| @@ -106,7 +92,6 @@ export default { | |||||||
|       name: '', |       name: '', | ||||||
|       locale: 'en', |       locale: 'en', | ||||||
|       domain: '', |       domain: '', | ||||||
|       domainEmailsEnabled: false, |  | ||||||
|       supportEmail: '', |       supportEmail: '', | ||||||
|       features: {}, |       features: {}, | ||||||
|     }; |     }; | ||||||
| @@ -132,6 +117,10 @@ export default { | |||||||
|     featureInboundEmailEnabled() { |     featureInboundEmailEnabled() { | ||||||
|       return !!this.features.inbound_emails; |       return !!this.features.inbound_emails; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|  |     featureCustomDomainEmailEnabled() { | ||||||
|  |       return this.featureInboundEmailEnabled && !!this.customEmailDomainEnabled; | ||||||
|  |     }, | ||||||
|   }, |   }, | ||||||
|   mounted() { |   mounted() { | ||||||
|     if (!this.id) { |     if (!this.id) { | ||||||
| @@ -148,7 +137,7 @@ export default { | |||||||
|           id, |           id, | ||||||
|           domain, |           domain, | ||||||
|           support_email, |           support_email, | ||||||
|           domain_emails_enabled, |           custom_email_domain_enabled, | ||||||
|           features, |           features, | ||||||
|         } = this.getAccount(this.accountId); |         } = this.getAccount(this.accountId); | ||||||
|  |  | ||||||
| @@ -158,7 +147,7 @@ export default { | |||||||
|         this.id = id; |         this.id = id; | ||||||
|         this.domain = domain; |         this.domain = domain; | ||||||
|         this.supportEmail = support_email; |         this.supportEmail = support_email; | ||||||
|         this.domainEmailsEnabled = domain_emails_enabled; |         this.customEmailDomainEnabled = custom_email_domain_enabled; | ||||||
|         this.features = features; |         this.features = features; | ||||||
|       } catch (error) { |       } catch (error) { | ||||||
|         // Ignore error |         // Ignore error | ||||||
| @@ -177,7 +166,6 @@ export default { | |||||||
|           name: this.name, |           name: this.name, | ||||||
|           domain: this.domain, |           domain: this.domain, | ||||||
|           support_email: this.supportEmail, |           support_email: this.supportEmail, | ||||||
|           domain_emails_enabled: this.domainEmailsEnabled, |  | ||||||
|         }); |         }); | ||||||
|         Vue.config.lang = this.locale; |         Vue.config.lang = this.locale; | ||||||
|         this.showAlert(this.$t('GENERAL_SETTINGS.UPDATE.SUCCESS')); |         this.showAlert(this.$t('GENERAL_SETTINGS.UPDATE.SUCCESS')); | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| class ConversationReplyMailer < ApplicationMailer | class ConversationReplyMailer < ApplicationMailer | ||||||
|   default from: ENV.fetch('MAILER_SENDER_EMAIL', 'accounts@chatwoot.com') |   default from: ENV.fetch('MAILER_SENDER_EMAIL', 'accounts@chatwoot.com') | ||||||
|   layout 'mailer' |   layout :choose_layout | ||||||
|  |  | ||||||
|   def reply_with_summary(conversation, message_queued_time) |   def reply_with_summary(conversation, message_queued_time) | ||||||
|     return unless smtp_config_set_or_development? |     return unless smtp_config_set_or_development? | ||||||
| @@ -54,16 +54,16 @@ class ConversationReplyMailer < ApplicationMailer | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   def reply_email |   def reply_email | ||||||
|     if custom_domain_email_enabled? |     if inbound_email_enabled? | ||||||
|       "#{@agent.name} <reply+#{@conversation.uuid}@#{@account.domain}>" |       "#{@agent.name} <reply+#{@conversation.uuid}@#{current_domain}>" | ||||||
|     else |     else | ||||||
|       @agent&.email |       @agent&.email | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def from_email |   def from_email | ||||||
|     if custom_domain_email_enabled? |     if inbound_email_enabled? | ||||||
|       "#{@agent.name} <#{@account_support_email}>" |       "#{@agent.name} <#{account_support_email}>" | ||||||
|     else |     else | ||||||
|       "#{@agent.name} <#{ENV.fetch('MAILER_SENDER_EMAIL', 'accounts@chatwoot.com')}>" |       "#{@agent.name} <#{ENV.fetch('MAILER_SENDER_EMAIL', 'accounts@chatwoot.com')}>" | ||||||
|     end |     end | ||||||
| @@ -77,8 +77,8 @@ class ConversationReplyMailer < ApplicationMailer | |||||||
|     "<account/#{@account.id}/conversation/#{@conversation.uuid}@#{current_domain}>" |     "<account/#{@account.id}/conversation/#{@conversation.uuid}@#{current_domain}>" | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def custom_domain_email_enabled? |   def inbound_email_enabled? | ||||||
|     @custom_domain_email_enabled ||= @account.domain_emails_enabled? && current_domain.present? && account_support_email.present? |     @inbound_email_enabled ||= @account.feature_enabled?('inbound_emails') && current_domain.present? && account_support_email.present? | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def current_domain |   def current_domain | ||||||
| @@ -96,4 +96,10 @@ class ConversationReplyMailer < ApplicationMailer | |||||||
|         ENV.fetch('MAILER_SENDER_EMAIL', 'accounts@chatwoot.com') |         ENV.fetch('MAILER_SENDER_EMAIL', 'accounts@chatwoot.com') | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  |   def choose_layout | ||||||
|  |     return false if action_name == 'reply_without_summary' | ||||||
|  |  | ||||||
|  |     'mailer' | ||||||
|  |   end | ||||||
| end | end | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ class Account < ApplicationRecord | |||||||
|   }.freeze |   }.freeze | ||||||
|  |  | ||||||
|   ACCOUNT_SETTINGS_FLAGS = { |   ACCOUNT_SETTINGS_FLAGS = { | ||||||
|     1 => :domain_emails_enabled |     1 => :custom_email_domain_enabled | ||||||
|   }.freeze |   }.freeze | ||||||
|  |  | ||||||
|   validates :name, presence: true |   validates :name, presence: true | ||||||
|   | |||||||
| @@ -18,13 +18,13 @@ module Featurable | |||||||
|     before_create :enable_default_features |     before_create :enable_default_features | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def enable_features(names) |   def enable_features(*names) | ||||||
|     names.each do |name| |     names.each do |name| | ||||||
|       send("feature_#{name}=", true) |       send("feature_#{name}=", true) | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def disable_features(names) |   def disable_features(*names) | ||||||
|     names.each do |name| |     names.each do |name| | ||||||
|       send("feature_#{name}=", false) |       send("feature_#{name}=", false) | ||||||
|     end |     end | ||||||
|   | |||||||
| @@ -2,6 +2,6 @@ json.id @account.id | |||||||
| json.name @account.name | json.name @account.name | ||||||
| json.locale @account.locale | json.locale @account.locale | ||||||
| json.domain @account.domain | json.domain @account.domain | ||||||
| json.domain_emails_enabled @account.domain_emails_enabled | json.custom_email_domain_enabled @account.custom_email_domain_enabled | ||||||
| json.support_email @account.support_email | json.support_email @account.support_email | ||||||
| json.features @account.all_features | json.features @account.all_features | ||||||
|   | |||||||
| @@ -2,6 +2,6 @@ json.id @account.id | |||||||
| json.name @account.name | json.name @account.name | ||||||
| json.locale @account.locale | json.locale @account.locale | ||||||
| json.domain @account.domain | json.domain @account.domain | ||||||
| json.domain_emails_enabled @account.domain_emails_enabled | json.custom_email_domain_enabled @account.custom_email_domain_enabled | ||||||
| json.support_email @account.support_email | json.support_email @account.support_email | ||||||
| json.features @account.enabled_features | json.features @account.enabled_features | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| <% @messages.each do |message| %> | <% @messages.each do |message| %> | ||||||
|   <p> |   <p> | ||||||
|     <% if message.content %> |     <% if message.content %> | ||||||
|       <%= message.content %> |       <%= message.content.gsub("\n", "<br/>").html_safe %> | ||||||
|     <% end %> |     <% end %> | ||||||
|     <% if message.attachments %> |     <% if message.attachments %> | ||||||
|       <% message.attachments.each do |attachment| %> |       <% message.attachments.each do |attachment| %> | ||||||
|   | |||||||
| @@ -12,8 +12,8 @@ class RemoveMultipleFeatureFlags < ActiveRecord::Migration[6.0] | |||||||
|     twitter_config = feature_config.value.find { |value| value['name'] == 'channel_twitter' } |     twitter_config = feature_config.value.find { |value| value['name'] == 'channel_twitter' } | ||||||
|     Account.find_in_batches do |account_batch| |     Account.find_in_batches do |account_batch| | ||||||
|       account_batch.each do |account| |       account_batch.each do |account| | ||||||
|         account.enable_features(['channel_facebook']) if facebook_config['enabled'] |         account.enable_features('channel_facebook') if facebook_config['enabled'] | ||||||
|         account.enable_features(['channel_twitter']) if twitter_config['enabled'] |         account.enable_features('channel_twitter') if twitter_config['enabled'] | ||||||
|         account.save! |         account.save! | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
|   | |||||||
| @@ -169,8 +169,7 @@ RSpec.describe 'Accounts API', type: :request do | |||||||
|         name: 'New Name', |         name: 'New Name', | ||||||
|         locale: 'en', |         locale: 'en', | ||||||
|         domain: 'example.com', |         domain: 'example.com', | ||||||
|         support_email: 'care@example.com', |         support_email: 'care@example.com' | ||||||
|         domain_emails_enabled: true |  | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       it 'modifies an account' do |       it 'modifies an account' do | ||||||
| @@ -183,7 +182,6 @@ RSpec.describe 'Accounts API', type: :request do | |||||||
|         expect(account.reload.name).to eq(params[:name]) |         expect(account.reload.name).to eq(params[:name]) | ||||||
|         expect(account.reload.locale).to eq(params[:locale]) |         expect(account.reload.locale).to eq(params[:locale]) | ||||||
|         expect(account.reload.domain).to eq(params[:domain]) |         expect(account.reload.domain).to eq(params[:domain]) | ||||||
|         expect(account.reload.domain_emails_enabled).to eq(params[:domain_emails_enabled]) |  | ||||||
|         expect(account.reload.support_email).to eq(params[:support_email]) |         expect(account.reload.support_email).to eq(params[:support_email]) | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
| FactoryBot.define do | FactoryBot.define do | ||||||
|   factory :account do |   factory :account do | ||||||
|     sequence(:name) { |n| "Account #{n}" } |     sequence(:name) { |n| "Account #{n}" } | ||||||
|     domain_emails_enabled { false } |     custom_email_domain_enabled { false } | ||||||
|     domain { 'test.com' } |     domain { 'test.com' } | ||||||
|     support_email { 'support@test.com' } |     support_email { 'support@test.com' } | ||||||
|   end |   end | ||||||
|   | |||||||
| @@ -97,7 +97,7 @@ RSpec.describe ConversationReplyMailer, type: :mailer do | |||||||
|         account = conversation.account |         account = conversation.account | ||||||
|         account.domain = 'example.com' |         account.domain = 'example.com' | ||||||
|         account.support_email = 'support@example.com' |         account.support_email = 'support@example.com' | ||||||
|         account.domain_emails_enabled = true |         account.enable_features('inbound_emails') | ||||||
|         account.save! |         account.save! | ||||||
|       end |       end | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Sony Mathew
					Sony Mathew