diff --git a/politeiawww/legacy/pi/events.go b/politeiawww/legacy/pi/events.go index 956e9e317..552e1ae8a 100644 --- a/politeiawww/legacy/pi/events.go +++ b/politeiawww/legacy/pi/events.go @@ -342,9 +342,7 @@ func (p *Pi) ntfnCommentNewProposalAuthor(c cmv1.Comment, proposalAuthorID, prop } // Send notification email - recipient := map[uuid.UUID]string{ - pauthor.ID: pauthor.Email, - } + recipient := []string{pauthor.Email} err = p.mailNtfnCommentNewToProposalAuthor(c.Token, c.CommentID, c.Username, proposalName, recipient) if err != nil { @@ -573,7 +571,7 @@ func (p *Pi) ntfnVoteStarted(sd tkv1.StartDetails, eventUser user.User, authorID ) // Compile user notification list - recipients := make(map[uuid.UUID]string, 1024) + var recipients []string err := p.userdb.AllUsers(func(u *user.User) { switch { case u.ID.String() == eventUser.ID.String(): @@ -589,7 +587,7 @@ func (p *Pi) ntfnVoteStarted(sd tkv1.StartDetails, eventUser user.User, authorID return default: // User has notification bit set - recipients[u.ID] = u.Email + recipients = append(recipients, u.Email) } }) if err != nil { diff --git a/politeiawww/legacy/pi/mail.go b/politeiawww/legacy/pi/mail.go index 625816b94..3ccf8b629 100644 --- a/politeiawww/legacy/pi/mail.go +++ b/politeiawww/legacy/pi/mail.go @@ -241,7 +241,7 @@ var commentNewToProposalAuthorTmpl = template.Must( template.New("commentNewToProposalAuthor"). Parse(commentNewToProposalAuthorText)) -func (p *Pi) mailNtfnCommentNewToProposalAuthor(token string, commentID uint32, commentUsername, proposalName string, recipient map[uuid.UUID]string) error { +func (p *Pi) mailNtfnCommentNewToProposalAuthor(token string, commentID uint32, commentUsername, proposalName string, recipient []string) error { cid := strconv.FormatUint(uint64(commentID), 10) route := strings.Replace(guiRouteRecordComment, "{token}", token, 1) route = strings.Replace(route, "{id}", cid, 1) @@ -262,7 +262,9 @@ func (p *Pi) mailNtfnCommentNewToProposalAuthor(token string, commentID uint32, return err } - return p.mail.SendToUsers(subject, body, recipient) + // Don't subject this email to rate limits. A proposal can receive multiple + // comments in a short amount of time at no fault of the proposal owner. + return p.mail.SendTo(subject, body, recipient) } type commentReply struct { @@ -354,7 +356,7 @@ Voting has started on a Politeia proposal. var voteStartedTmpl = template.Must( template.New("voteStarted").Parse(voteStartedText)) -func (p *Pi) mailNtfnVoteStarted(token, name string, recipients map[uuid.UUID]string) error { +func (p *Pi) mailNtfnVoteStarted(token, name string, recipients []string) error { route := strings.Replace(guiRouteRecordDetails, "{token}", token, 1) u, err := url.Parse(p.cfg.WebServerAddress + route) if err != nil { @@ -371,7 +373,9 @@ func (p *Pi) mailNtfnVoteStarted(token, name string, recipients map[uuid.UUID]st return err } - return p.mail.SendToUsers(subject, body, recipients) + // Don't subject this email to rate limits because proposal voting can only + // be started by admins, not regular users. + return p.mail.SendTo(subject, body, recipients) } type voteStartedToAuthor struct {