mirror of
https://github.com/discourse/discourse.git
synced 2025-05-24 01:21:23 +08:00
FEATURE: Allow sending group SMTP emails with from alias (#15687)
This commit allows group SMTP emails to be sent with a different from email address that has been set up as an alias in the email provider. Emails from the alias will be grouped correctly using Message-IDs in the mail client, and replies to the alias go into the correct group inbox.
This commit is contained in:
@ -37,6 +37,7 @@ export default Component.extend({
|
|||||||
EmberObject.create({
|
EmberObject.create({
|
||||||
email_username: this.group.email_username,
|
email_username: this.group.email_username,
|
||||||
email_password: this.group.email_password,
|
email_password: this.group.email_password,
|
||||||
|
email_from_alias: this.group.email_from_alias,
|
||||||
smtp_server: this.group.smtp_server,
|
smtp_server: this.group.smtp_server,
|
||||||
smtp_port: (this.group.smtp_port || "").toString(),
|
smtp_port: (this.group.smtp_port || "").toString(),
|
||||||
smtp_ssl: this.group.smtp_ssl,
|
smtp_ssl: this.group.smtp_ssl,
|
||||||
@ -73,6 +74,7 @@ export default Component.extend({
|
|||||||
smtp_port: this.form.smtp_port,
|
smtp_port: this.form.smtp_port,
|
||||||
smtp_ssl: this.form.smtp_ssl,
|
smtp_ssl: this.form.smtp_ssl,
|
||||||
email_username: this.form.email_username,
|
email_username: this.form.email_username,
|
||||||
|
email_from_alias: this.form.email_from_alias,
|
||||||
email_password: this.form.email_password,
|
email_password: this.form.email_password,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
@ -243,6 +243,7 @@ const Group = RestModel.extend({
|
|||||||
imap_mailbox_name: this.imap_mailbox_name,
|
imap_mailbox_name: this.imap_mailbox_name,
|
||||||
imap_enabled: this.imap_enabled,
|
imap_enabled: this.imap_enabled,
|
||||||
email_username: this.email_username,
|
email_username: this.email_username,
|
||||||
|
email_from_alias: this.email_from_alias,
|
||||||
email_password: this.email_password,
|
email_password: this.email_password,
|
||||||
flair_icon: null,
|
flair_icon: null,
|
||||||
flair_upload_id: null,
|
flair_upload_id: null,
|
||||||
|
@ -45,5 +45,5 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
{{group-manage-save-button model=group disabled=(not emailSettingsValid) beforeSave=beforeSave afterSave=afterSave tabindex="14"}}
|
{{group-manage-save-button model=group disabled=(not emailSettingsValid) beforeSave=beforeSave afterSave=afterSave tabindex="15"}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,11 +8,11 @@
|
|||||||
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label for="smtp_server">{{i18n "groups.manage.email.credentials.smtp_server"}}</label>
|
<label for="smtp_server">{{i18n "groups.manage.email.credentials.smtp_server"}}</label>
|
||||||
{{input type="text" name="smtp_server" value=form.smtp_server tabindex="3" onChange=(action "resetSettingsValid")}}
|
{{input type="text" name="smtp_server" value=form.smtp_server tabindex="4" onChange=(action "resetSettingsValid")}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label for="enable_ssl">
|
<label for="enable_ssl">
|
||||||
{{input type="checkbox" checked=form.smtp_ssl id="enable_ssl" tabindex="5" onChange=(action "resetSettingsValid")}}
|
{{input type="checkbox" checked=form.smtp_ssl id="enable_ssl" tabindex="6" onChange=(action "resetSettingsValid")}}
|
||||||
{{i18n "groups.manage.email.credentials.smtp_ssl"}}
|
{{i18n "groups.manage.email.credentials.smtp_ssl"}}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@ -25,7 +25,15 @@
|
|||||||
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label for="smtp_port">{{i18n "groups.manage.email.credentials.smtp_port"}}</label>
|
<label for="smtp_port">{{i18n "groups.manage.email.credentials.smtp_port"}}</label>
|
||||||
{{input type="text" name="smtp_port" value=form.smtp_port tabindex="4" onChange=(action "resetSettingsValid" form.smtp_port)}}
|
{{input type="text" name="smtp_port" value=form.smtp_port tabindex="5" onChange=(action "resetSettingsValid" form.smtp_port)}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="from_alias">{{i18n "groups.manage.email.settings.from_alias"}}</label>
|
||||||
|
{{input type="text" name="from_alias" id="from_alias" value=form.email_from_alias onChange=(action "resetSettingsValid") tabindex="3"}}
|
||||||
|
<p>{{i18n "groups.manage.email.settings.from_alias_hint"}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@ -43,7 +51,7 @@
|
|||||||
action=(action "testSmtpSettings")
|
action=(action "testSmtpSettings")
|
||||||
icon="cog"
|
icon="cog"
|
||||||
label="groups.manage.email.test_settings"
|
label="groups.manage.email.test_settings"
|
||||||
tabindex="6"
|
tabindex="7"
|
||||||
title="groups.manage.email.settings_required"
|
title="groups.manage.email.settings_required"
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
@ -106,6 +106,8 @@ acceptance(
|
|||||||
|
|
||||||
await fillIn('input[name="username"]', "myusername@gmail.com");
|
await fillIn('input[name="username"]', "myusername@gmail.com");
|
||||||
await fillIn('input[name="password"]', "password@gmail.com");
|
await fillIn('input[name="password"]', "password@gmail.com");
|
||||||
|
await fillIn("#from_alias", "akasomegroup@example.com");
|
||||||
|
|
||||||
await click(".test-smtp-settings");
|
await click(".test-smtp-settings");
|
||||||
|
|
||||||
assert.ok(exists(".smtp-settings-ok"), "tested settings are ok");
|
assert.ok(exists(".smtp-settings-ok"), "tested settings are ok");
|
||||||
|
@ -252,7 +252,7 @@ table.group-category-permissions {
|
|||||||
.group-imap-email-settings {
|
.group-imap-email-settings {
|
||||||
.groups-form {
|
.groups-form {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 3fr;
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
|
||||||
&.groups-form-imap {
|
&.groups-form-imap {
|
||||||
|
@ -713,6 +713,7 @@ class GroupsController < ApplicationController
|
|||||||
:imap_updated_at,
|
:imap_updated_at,
|
||||||
:email_username,
|
:email_username,
|
||||||
:email_password,
|
:email_password,
|
||||||
|
:email_from_alias,
|
||||||
:primary_group,
|
:primary_group,
|
||||||
:visibility_level,
|
:visibility_level,
|
||||||
:members_visibility_level,
|
:members_visibility_level,
|
||||||
|
@ -48,7 +48,7 @@ class GroupSmtpMailer < ActionMailer::Base
|
|||||||
add_re_to_subject: true,
|
add_re_to_subject: true,
|
||||||
locale: SiteSetting.default_locale,
|
locale: SiteSetting.default_locale,
|
||||||
delivery_method_options: delivery_options,
|
delivery_method_options: delivery_options,
|
||||||
from: from_group.email_username,
|
from: from_group.smtp_from_address,
|
||||||
from_alias: I18n.t('email_from_without_site', user_name: group_name),
|
from_alias: I18n.t('email_from_without_site', user_name: group_name),
|
||||||
html_override: html_override(post),
|
html_override: html_override(post),
|
||||||
cc: cc_addresses
|
cc: cc_addresses
|
||||||
|
@ -110,7 +110,8 @@ class Group < ActiveRecord::Base
|
|||||||
"imap_port",
|
"imap_port",
|
||||||
"imap_ssl",
|
"imap_ssl",
|
||||||
"email_username",
|
"email_username",
|
||||||
"email_password"
|
"email_password",
|
||||||
|
"email_from_alias"
|
||||||
]
|
]
|
||||||
|
|
||||||
ALIAS_LEVELS = {
|
ALIAS_LEVELS = {
|
||||||
@ -290,6 +291,10 @@ class Group < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def smtp_from_address
|
||||||
|
self.email_from_alias.present? ? self.email_from_alias : self.email_username
|
||||||
|
end
|
||||||
|
|
||||||
def downcase_incoming_email
|
def downcase_incoming_email
|
||||||
self.incoming_email = (incoming_email || "").strip.downcase.presence
|
self.incoming_email = (incoming_email || "").strip.downcase.presence
|
||||||
end
|
end
|
||||||
@ -708,7 +713,9 @@ class Group < ActiveRecord::Base
|
|||||||
|
|
||||||
def self.find_by_email(email)
|
def self.find_by_email(email)
|
||||||
self.where(
|
self.where(
|
||||||
"email_username = :email OR string_to_array(incoming_email, '|') @> ARRAY[:email]",
|
"email_username = :email OR
|
||||||
|
string_to_array(incoming_email, '|') @> ARRAY[:email] OR
|
||||||
|
email_from_alias = :email",
|
||||||
email: Email.downcase(email)
|
email: Email.downcase(email)
|
||||||
).first
|
).first
|
||||||
end
|
end
|
||||||
@ -1128,6 +1135,7 @@ end
|
|||||||
# imap_enabled :boolean default(FALSE)
|
# imap_enabled :boolean default(FALSE)
|
||||||
# imap_updated_at :datetime
|
# imap_updated_at :datetime
|
||||||
# imap_updated_by_id :integer
|
# imap_updated_by_id :integer
|
||||||
|
# email_from_alias :string
|
||||||
#
|
#
|
||||||
# Indexes
|
# Indexes
|
||||||
#
|
#
|
||||||
|
@ -32,6 +32,7 @@ class GroupShowSerializer < BasicGroupSerializer
|
|||||||
:imap_updated_by,
|
:imap_updated_by,
|
||||||
:email_username,
|
:email_username,
|
||||||
:email_password,
|
:email_password,
|
||||||
|
:email_from_alias,
|
||||||
:imap_last_error,
|
:imap_last_error,
|
||||||
:imap_old_emails,
|
:imap_old_emails,
|
||||||
:imap_new_emails,
|
:imap_new_emails,
|
||||||
|
@ -754,6 +754,8 @@ en:
|
|||||||
title: "Settings"
|
title: "Settings"
|
||||||
allow_unknown_sender_topic_replies: "Allow unknown sender topic replies."
|
allow_unknown_sender_topic_replies: "Allow unknown sender topic replies."
|
||||||
allow_unknown_sender_topic_replies_hint: "Allows unknown senders to reply to group topics. If this is not enabled, replies from email addresses not already invited to the topic will create a new topic."
|
allow_unknown_sender_topic_replies_hint: "Allows unknown senders to reply to group topics. If this is not enabled, replies from email addresses not already invited to the topic will create a new topic."
|
||||||
|
from_alias: "From Alias"
|
||||||
|
from_alias_hint: "Alias to use as the from address when sending group SMTP emails. Note this may not be supported by all mail providers, please consult your mail provider's documentation."
|
||||||
mailboxes:
|
mailboxes:
|
||||||
synchronized: "Synchronized Mailbox"
|
synchronized: "Synchronized Mailbox"
|
||||||
none_found: "No mailboxes were found in this email account."
|
none_found: "No mailboxes were found in this email account."
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AddEmailFromAliasToGroups < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
add_column :groups, :email_from_alias, :string, null: true
|
||||||
|
end
|
||||||
|
end
|
@ -1225,6 +1225,23 @@ describe Group do
|
|||||||
expect(group.smtp_updated_by).to eq(user)
|
expect(group.smtp_updated_by).to eq(user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "records the change for singular setting changes" do
|
||||||
|
group.update(
|
||||||
|
smtp_port: 587,
|
||||||
|
smtp_ssl: true,
|
||||||
|
smtp_server: "smtp.gmail.com",
|
||||||
|
email_username: "test@gmail.com",
|
||||||
|
email_password: "password",
|
||||||
|
)
|
||||||
|
group.record_email_setting_changes!(user)
|
||||||
|
group.reload
|
||||||
|
|
||||||
|
old_updated_at = group.smtp_updated_at
|
||||||
|
group.update(email_from_alias: "somealias@gmail.com")
|
||||||
|
group.record_email_setting_changes!(user)
|
||||||
|
expect(group.reload.smtp_updated_at).not_to eq_time(old_updated_at)
|
||||||
|
end
|
||||||
|
|
||||||
it "enables imap and records the change" do
|
it "enables imap and records the change" do
|
||||||
group.update(
|
group.update(
|
||||||
imap_port: 587,
|
imap_port: 587,
|
||||||
@ -1314,5 +1331,12 @@ describe Group do
|
|||||||
expect(Group.find_by_email("support@test.com")).to eq(group)
|
expect(Group.find_by_email("support@test.com")).to eq(group)
|
||||||
expect(Group.find_by_email("nope@test.com")).to eq(nil)
|
expect(Group.find_by_email("nope@test.com")).to eq(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "finds the group by its email_from_alias" do
|
||||||
|
group.update!(email_username: "abc@test.com", email_from_alias: "somealias@test.com")
|
||||||
|
expect(Group.find_by_email("abc@test.com")).to eq(group)
|
||||||
|
expect(Group.find_by_email("somealias@test.com")).to eq(group)
|
||||||
|
expect(Group.find_by_email("nope@test.com")).to eq(nil)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -221,6 +221,12 @@
|
|||||||
"null"
|
"null"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"email_from_alias": {
|
||||||
|
"type": [
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
},
|
||||||
"email_password": {
|
"email_password": {
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
|
Reference in New Issue
Block a user