Skip to content

Commit 38e9f74

Browse files
committed
Added additional email headers.
1 parent d6d2444 commit 38e9f74

File tree

3 files changed

+61
-21
lines changed

3 files changed

+61
-21
lines changed

services/mailer/mail.go

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"html/template"
1212
"mime"
1313
"regexp"
14+
"strconv"
1415
"strings"
1516
texttmpl "text/template"
1617

@@ -174,7 +175,7 @@ func SendCollaboratorMail(u, doer *models.User, repo *models.Repository) {
174175
SendAsync(msg)
175176
}
176177

177-
func composeIssueCommentMessages(ctx *mailCommentContext, lang string, tos []string, fromMention bool, info string) ([]*Message, error) {
178+
func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipients []*models.User, fromMention bool, info string) ([]*Message, error) {
178179
var (
179180
subject string
180181
link string
@@ -265,9 +266,9 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, tos []str
265266
}
266267

267268
// Make sure to compose independent messages to avoid leaking user emails
268-
msgs := make([]*Message, 0, len(tos))
269-
for _, to := range tos {
270-
msg := NewMessageFrom([]string{to}, ctx.Doer.DisplayName(), setting.MailService.FromEmail, subject, mailBody.String())
269+
msgs := make([]*Message, 0, len(recipients))
270+
for _, recipient := range recipients {
271+
msg := NewMessageFrom([]string{recipient.Email}, ctx.Doer.DisplayName(), setting.MailService.FromEmail, subject, mailBody.String())
271272
msg.Info = fmt.Sprintf("Subject: %s, %s", subject, info)
272273

273274
// Set Message-ID on first message so replies know what to reference
@@ -277,12 +278,51 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, tos []str
277278
msg.SetHeader("In-Reply-To", "<"+ctx.Issue.ReplyReference()+">")
278279
msg.SetHeader("References", "<"+ctx.Issue.ReplyReference()+">")
279280
}
281+
282+
for key, value := range generateAdditionalHeaders(ctx, actType, recipient) {
283+
msg.SetHeader(key, value)
284+
}
285+
280286
msgs = append(msgs, msg)
281287
}
282288

283289
return msgs, nil
284290
}
285291

292+
func generateAdditionalHeaders(ctx *mailCommentContext, actionType string, recipient *models.User) map[string]string {
293+
repo := ctx.Issue.Repo
294+
295+
return map[string]string{
296+
// https://datatracker.ietf.org/doc/html/rfc2919
297+
"List-ID": fmt.Sprintf("%s <%s.%s.%s>", repo.FullName(), repo.Name, repo.OwnerName, setting.Domain),
298+
299+
// https://datatracker.ietf.org/doc/html/rfc2369
300+
"List-Archive": fmt.Sprintf("<%s>", repo.HTMLURL()),
301+
//"List-Post": https://github.com/go-gitea/gitea/pull/13585
302+
//"List-Unsubscribe": https://github.com/go-gitea/gitea/issues/10808, https://github.com/go-gitea/gitea/issues/13283
303+
304+
"X-Gitea-Reason": actionType,
305+
"X-Gitea-Sender": ctx.Doer.DisplayName(),
306+
"X-Gitea-Recipient": recipient.DisplayName(),
307+
"X-Gitea-Recipient-Address": recipient.Email,
308+
"X-Gitea-Repository": repo.Name,
309+
"X-Gitea-Repository-Path": repo.FullName(),
310+
"X-Gitea-Repository-Link": repo.HTMLURL(),
311+
"X-Gitea-Issue-ID": strconv.FormatInt(ctx.Issue.Index, 10),
312+
"X-Gitea-Issue-Link": ctx.Issue.HTMLURL(),
313+
314+
"X-GitHub-Reason": actionType,
315+
"X-GitHub-Sender": ctx.Doer.DisplayName(),
316+
"X-GitHub-Recipient": recipient.DisplayName(),
317+
"X-GitHub-Recipient-Address": recipient.Email,
318+
319+
"X-GitLab-NotificationReason": actionType,
320+
"X-GitLab-Project": repo.Name,
321+
"X-GitLab-Project-Path": repo.FullName(),
322+
"X-GitLab-Issue-IID": strconv.FormatInt(ctx.Issue.Index, 10),
323+
}
324+
}
325+
286326
func sanitizeSubject(subject string) string {
287327
runes := []rune(strings.TrimSpace(subjectRemoveSpaces.ReplaceAllLiteralString(subject, " ")))
288328
if len(runes) > mailMaxSubjectRunes {
@@ -294,9 +334,9 @@ func sanitizeSubject(subject string) string {
294334

295335
// SendIssueAssignedMail composes and sends issue assigned email
296336
func SendIssueAssignedMail(issue *models.Issue, doer *models.User, content string, comment *models.Comment, recipients []*models.User) error {
297-
langMap := make(map[string][]string)
337+
langMap := make(map[string][]*models.User)
298338
for _, user := range recipients {
299-
langMap[user.Language] = append(langMap[user.Language], user.Email)
339+
langMap[user.Language] = append(langMap[user.Language], user)
300340
}
301341

302342
for lang, tos := range langMap {

services/mailer/mail_issue.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ func mailIssueCommentBatch(ctx *mailCommentContext, users []*models.User, visite
116116
checkUnit = models.UnitTypePullRequests
117117
}
118118

119-
langMap := make(map[string][]string)
119+
langMap := make(map[string][]*models.User)
120120
for _, user := range users {
121121
// At this point we exclude:
122122
// user that don't have all mails enabled or users only get mail on mention and this is one ...
@@ -138,7 +138,7 @@ func mailIssueCommentBatch(ctx *mailCommentContext, users []*models.User, visite
138138
continue
139139
}
140140

141-
langMap[user.Language] = append(langMap[user.Language], user.Email)
141+
langMap[user.Language] = append(langMap[user.Language], user)
142142
}
143143

144144
for lang, receivers := range langMap {

services/mailer/mail_test.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ func TestComposeIssueCommentMessage(t *testing.T) {
5757
btpl := template.Must(template.New("issue/comment").Parse(bodyTpl))
5858
InitMailRender(stpl, btpl)
5959

60-
tos := []string{"[email protected]", "[email protected]"}
60+
recipients := []*models.User{{Name: "Test", Email: "[email protected]"}, {Name: "Test2", Email: "[email protected]"}}
6161
msgs, err := composeIssueCommentMessages(&mailCommentContext{Issue: issue, Doer: doer, ActionType: models.ActionCommentIssue,
62-
Content: "test body", Comment: comment}, "en-US", tos, false, "issue comment")
62+
Content: "test body", Comment: comment}, "en-US", recipients, false, "issue comment")
6363
assert.NoError(t, err)
6464
assert.Len(t, msgs, 2)
6565
gomailMsg := msgs[0].ToMessage()
@@ -92,9 +92,9 @@ func TestComposeIssueMessage(t *testing.T) {
9292
btpl := template.Must(template.New("issue/new").Parse(bodyTpl))
9393
InitMailRender(stpl, btpl)
9494

95-
tos := []string{"[email protected]", "[email protected]"}
95+
recipients := []*models.User{{Name: "Test", Email: "[email protected]"}, {Name: "Test2", Email: "[email protected]"}}
9696
msgs, err := composeIssueCommentMessages(&mailCommentContext{Issue: issue, Doer: doer, ActionType: models.ActionCreateIssue,
97-
Content: "test body"}, "en-US", tos, false, "issue create")
97+
Content: "test body"}, "en-US", recipients, false, "issue create")
9898
assert.NoError(t, err)
9999
assert.Len(t, msgs, 2)
100100

@@ -122,7 +122,7 @@ func TestTemplateSelection(t *testing.T) {
122122
doer := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
123123
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1, Owner: doer}).(*models.Repository)
124124
issue := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 1, Repo: repo, Poster: doer}).(*models.Issue)
125-
tos := []string{"[email protected]"}
125+
recipients := []*models.User{{Name: "Test", Email: "[email protected]"}}
126126

127127
stpl := texttmpl.Must(texttmpl.New("issue/default").Parse("issue/default/subject"))
128128
texttmpl.Must(stpl.New("issue/new").Parse("issue/new/subject"))
@@ -146,22 +146,22 @@ func TestTemplateSelection(t *testing.T) {
146146
}
147147

148148
msg := testComposeIssueCommentMessage(t, &mailCommentContext{Issue: issue, Doer: doer, ActionType: models.ActionCreateIssue,
149-
Content: "test body"}, tos, false, "TestTemplateSelection")
149+
Content: "test body"}, recipients, false, "TestTemplateSelection")
150150
expect(t, msg, "issue/new/subject", "issue/new/body")
151151

152152
comment := models.AssertExistsAndLoadBean(t, &models.Comment{ID: 2, Issue: issue}).(*models.Comment)
153153
msg = testComposeIssueCommentMessage(t, &mailCommentContext{Issue: issue, Doer: doer, ActionType: models.ActionCommentIssue,
154-
Content: "test body", Comment: comment}, tos, false, "TestTemplateSelection")
154+
Content: "test body", Comment: comment}, recipients, false, "TestTemplateSelection")
155155
expect(t, msg, "issue/default/subject", "issue/default/body")
156156

157157
pull := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 2, Repo: repo, Poster: doer}).(*models.Issue)
158158
comment = models.AssertExistsAndLoadBean(t, &models.Comment{ID: 4, Issue: pull}).(*models.Comment)
159159
msg = testComposeIssueCommentMessage(t, &mailCommentContext{Issue: pull, Doer: doer, ActionType: models.ActionCommentPull,
160-
Content: "test body", Comment: comment}, tos, false, "TestTemplateSelection")
160+
Content: "test body", Comment: comment}, recipients, false, "TestTemplateSelection")
161161
expect(t, msg, "pull/comment/subject", "pull/comment/body")
162162

163163
msg = testComposeIssueCommentMessage(t, &mailCommentContext{Issue: issue, Doer: doer, ActionType: models.ActionCloseIssue,
164-
Content: "test body", Comment: comment}, tos, false, "TestTemplateSelection")
164+
Content: "test body", Comment: comment}, recipients, false, "TestTemplateSelection")
165165
expect(t, msg, "Re: [user2/repo1] issue1 (#1)", "issue/close/body")
166166
}
167167

@@ -187,9 +187,9 @@ func TestTemplateServices(t *testing.T) {
187187
btpl := template.Must(template.New("issue/default").Parse(tplBody))
188188
InitMailRender(stpl, btpl)
189189

190-
tos := []string{"[email protected]"}
190+
recipients := []*models.User{{Name: "Test", Email: "[email protected]"}}
191191
msg := testComposeIssueCommentMessage(t, &mailCommentContext{Issue: issue, Doer: doer, ActionType: actionType,
192-
Content: "test body", Comment: comment}, tos, fromMention, "TestTemplateServices")
192+
Content: "test body", Comment: comment}, recipients, fromMention, "TestTemplateServices")
193193

194194
subject := msg.ToMessage().GetHeader("Subject")
195195
msgbuf := new(bytes.Buffer)
@@ -219,8 +219,8 @@ func TestTemplateServices(t *testing.T) {
219219
"//Re: //")
220220
}
221221

222-
func testComposeIssueCommentMessage(t *testing.T, ctx *mailCommentContext, tos []string, fromMention bool, info string) *Message {
223-
msgs, err := composeIssueCommentMessages(ctx, "en-US", tos, fromMention, info)
222+
func testComposeIssueCommentMessage(t *testing.T, ctx *mailCommentContext, recipients []*models.User, fromMention bool, info string) *Message {
223+
msgs, err := composeIssueCommentMessages(ctx, "en-US", recipients, fromMention, info)
224224
assert.NoError(t, err)
225225
assert.Len(t, msgs, 1)
226226
return msgs[0]

0 commit comments

Comments
 (0)