@@ -164,13 +164,7 @@ func SendCollaboratorMail(u, doer *models.User, repo *models.Repository) {
164164 SendAsync (msg )
165165}
166166
167- func composeIssueCommentMessage (issue * models.Issue , doer * models.User , actionType models.ActionType , fromMention bool ,
168- content string , comment * models.Comment , tos []string , info string ) * Message {
169-
170- if err := issue .LoadPullRequest (); err != nil {
171- log .Error ("LoadPullRequest: %v" , err )
172- return nil
173- }
167+ func composeIssueCommentMessages (ctx * mailCommentContext , tos []string , fromMention bool , info string ) []* Message {
174168
175169 var (
176170 subject string
@@ -182,29 +176,29 @@ func composeIssueCommentMessage(issue *models.Issue, doer *models.User, actionTy
182176 )
183177
184178 commentType := models .CommentTypeComment
185- if comment != nil {
179+ if ctx . Comment != nil {
186180 prefix = "Re: "
187- commentType = comment .Type
188- link = issue . HTMLURL () + "#" + comment .HashTag ()
181+ commentType = ctx . Comment .Type
182+ link = ctx . Issue . HTMLURL () + "#" + ctx . Comment .HashTag ()
189183 } else {
190- link = issue .HTMLURL ()
184+ link = ctx . Issue .HTMLURL ()
191185 }
192186
193187 reviewType := models .ReviewTypeComment
194- if comment != nil && comment .Review != nil {
195- reviewType = comment .Review .Type
188+ if ctx . Comment != nil && ctx . Comment .Review != nil {
189+ reviewType = ctx . Comment .Review .Type
196190 }
197191
198- fallback = prefix + fallbackMailSubject (issue )
192+ fallback = prefix + fallbackMailSubject (ctx . Issue )
199193
200194 // This is the body of the new issue or comment, not the mail body
201- body := string (markup .RenderByType (markdown .MarkupName , []byte (content ), issue . Repo .HTMLURL (), issue .Repo .ComposeMetas ()))
195+ body := string (markup .RenderByType (markdown .MarkupName , []byte (ctx . Content ), ctx . Issue . Repo .HTMLURL (), ctx . Issue .Repo .ComposeMetas ()))
202196
203- actType , actName , tplName := actionToTemplate (issue , actionType , commentType , reviewType )
197+ actType , actName , tplName := actionToTemplate (ctx . Issue , ctx . ActionType , commentType , reviewType )
204198
205- if comment != nil && comment .Review != nil {
199+ if ctx . Comment != nil && ctx . Comment .Review != nil {
206200 reviewComments = make ([]* models.Comment , 0 , 10 )
207- for _ , lines := range comment .Review .CodeComments {
201+ for _ , lines := range ctx . Comment .Review .CodeComments {
208202 for _ , comments := range lines {
209203 reviewComments = append (reviewComments , comments ... )
210204 }
@@ -215,12 +209,12 @@ func composeIssueCommentMessage(issue *models.Issue, doer *models.User, actionTy
215209 "FallbackSubject" : fallback ,
216210 "Body" : body ,
217211 "Link" : link ,
218- "Issue" : issue ,
219- "Comment" : comment ,
220- "IsPull" : issue .IsPull ,
221- "User" : issue .Repo .MustOwner (),
222- "Repo" : issue .Repo .FullName (),
223- "Doer" : doer ,
212+ "Issue" : ctx . Issue ,
213+ "Comment" : ctx . Comment ,
214+ "IsPull" : ctx . Issue .IsPull ,
215+ "User" : ctx . Issue .Repo .MustOwner (),
216+ "Repo" : ctx . Issue .Repo .FullName (),
217+ "Doer" : ctx . Doer ,
224218 "IsMention" : fromMention ,
225219 "SubjectPrefix" : prefix ,
226220 "ActionType" : actType ,
@@ -246,18 +240,23 @@ func composeIssueCommentMessage(issue *models.Issue, doer *models.User, actionTy
246240 log .Error ("ExecuteTemplate [%s]: %v" , string (tplName )+ "/body" , err )
247241 }
248242
249- msg := NewMessageFrom (tos , doer .DisplayName (), setting .MailService .FromEmail , subject , mailBody .String ())
250- msg .Info = fmt .Sprintf ("Subject: %s, %s" , subject , info )
251-
252- // Set Message-ID on first message so replies know what to reference
253- if comment == nil {
254- msg .SetHeader ("Message-ID" , "<" + issue .ReplyReference ()+ ">" )
255- } else {
256- msg .SetHeader ("In-Reply-To" , "<" + issue .ReplyReference ()+ ">" )
257- msg .SetHeader ("References" , "<" + issue .ReplyReference ()+ ">" )
243+ // Make sure to compose independent messages to avoid leaking user emails
244+ msgs := make ([]* Message , 0 , len (tos ))
245+ for _ , to := range tos {
246+ msg := NewMessageFrom ([]string {to }, ctx .Doer .DisplayName (), setting .MailService .FromEmail , subject , mailBody .String ())
247+ msg .Info = fmt .Sprintf ("Subject: %s, %s" , subject , info )
248+
249+ // Set Message-ID on first message so replies know what to reference
250+ if ctx .Comment == nil {
251+ msg .SetHeader ("Message-ID" , "<" + ctx .Issue .ReplyReference ()+ ">" )
252+ } else {
253+ msg .SetHeader ("In-Reply-To" , "<" + ctx .Issue .ReplyReference ()+ ">" )
254+ msg .SetHeader ("References" , "<" + ctx .Issue .ReplyReference ()+ ">" )
255+ }
256+ msgs = append (msgs , msg )
258257 }
259258
260- return msg
259+ return msgs
261260}
262261
263262func sanitizeSubject (subject string ) string {
@@ -269,21 +268,15 @@ func sanitizeSubject(subject string) string {
269268 return mime .QEncoding .Encode ("utf-8" , string (runes ))
270269}
271270
272- // SendIssueCommentMail composes and sends issue comment emails to target receivers.
273- func SendIssueCommentMail (issue * models.Issue , doer * models.User , actionType models.ActionType , content string , comment * models.Comment , tos []string ) {
274- if len (tos ) == 0 {
275- return
276- }
277-
278- SendAsync (composeIssueCommentMessage (issue , doer , actionType , false , content , comment , tos , "issue comment" ))
279- }
280-
281- // SendIssueMentionMail composes and sends issue mention emails to target receivers.
282- func SendIssueMentionMail (issue * models.Issue , doer * models.User , actionType models.ActionType , content string , comment * models.Comment , tos []string ) {
283- if len (tos ) == 0 {
284- return
285- }
286- SendAsync (composeIssueCommentMessage (issue , doer , actionType , true , content , comment , tos , "issue mention" ))
271+ // SendIssueAssignedMail composes and sends issue assigned email
272+ func SendIssueAssignedMail (issue * models.Issue , doer * models.User , content string , comment * models.Comment , tos []string ) {
273+ SendAsyncs (composeIssueCommentMessages (& mailCommentContext {
274+ Issue : issue ,
275+ Doer : doer ,
276+ ActionType : models .ActionType (0 ),
277+ Content : content ,
278+ Comment : comment ,
279+ }, tos , false , "issue assigned" ))
287280}
288281
289282// actionToTemplate returns the type and name of the action facing the user
@@ -341,8 +334,3 @@ func actionToTemplate(issue *models.Issue, actionType models.ActionType,
341334 }
342335 return
343336}
344-
345- // SendIssueAssignedMail composes and sends issue assigned email
346- func SendIssueAssignedMail (issue * models.Issue , doer * models.User , content string , comment * models.Comment , tos []string ) {
347- SendAsync (composeIssueCommentMessage (issue , doer , models .ActionType (0 ), false , content , comment , tos , "issue assigned" ))
348- }
0 commit comments