From e5065cf7575ee05c040945a4b00b7fd90bf39b83 Mon Sep 17 00:00:00 2001 From: Carlos Tadeu Panato Junior Date: Wed, 1 Mar 2017 15:28:38 +0100 Subject: Make all emails with the same pattern on subject (#5198) * make all email subject standard * move SendPasswordReset to app/email.go update per review * update email subjects per review update error fix expected subject * Update email_test.go * Update en.json * fix missing quotes --- app/email.go | 52 ++++++++++++++++++++++++++++------- app/email_test.go | 82 +++++++++++++++++++++++++++++++++++++++++++------------ app/user.go | 61 ++++++++++++++++------------------------- 3 files changed, 129 insertions(+), 66 deletions(-) (limited to 'app') diff --git a/app/email.go b/app/email.go index 007a24505..61ee52c15 100644 --- a/app/email.go +++ b/app/email.go @@ -16,8 +16,9 @@ import ( func SendChangeUsernameEmail(oldUsername, newUsername, email, locale, siteURL string) *model.AppError { T := utils.GetUserTranslations(locale) - subject := fmt.Sprintf("[%v] %v", utils.Cfg.TeamSettings.SiteName, T("api.templates.username_change_subject", - map[string]interface{}{"TeamDisplayName": utils.Cfg.TeamSettings.SiteName})) + subject := T("api.templates.username_change_subject", + map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"], + "TeamDisplayName": utils.Cfg.TeamSettings.SiteName}) bodyPage := utils.NewHTMLTemplate("email_change_body", locale) bodyPage.Props["SiteURL"] = siteURL @@ -37,8 +38,10 @@ func SendEmailChangeVerifyEmail(userId, newUserEmail, locale, siteURL string) *m link := fmt.Sprintf("%s/do_verify_email?uid=%s&hid=%s&email=%s", siteURL, userId, model.HashPassword(userId+utils.Cfg.EmailSettings.InviteSalt), url.QueryEscape(newUserEmail)) - subject := fmt.Sprintf("[%v] %v", utils.Cfg.TeamSettings.SiteName, T("api.templates.email_change_verify_subject", - map[string]interface{}{"TeamDisplayName": utils.Cfg.TeamSettings.SiteName})) + subject := T("api.templates.email_change_verify_subject", + map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"], + "TeamDisplayName": utils.Cfg.TeamSettings.SiteName}) + bodyPage := utils.NewHTMLTemplate("email_change_verify_body", locale) bodyPage.Props["SiteURL"] = siteURL @@ -58,8 +61,9 @@ func SendEmailChangeVerifyEmail(userId, newUserEmail, locale, siteURL string) *m func SendEmailChangeEmail(oldEmail, newEmail, locale, siteURL string) *model.AppError { T := utils.GetUserTranslations(locale) - subject := fmt.Sprintf("[%v] %v", utils.Cfg.TeamSettings.SiteName, T("api.templates.email_change_subject", - map[string]interface{}{"TeamDisplayName": utils.Cfg.TeamSettings.SiteName})) + subject := T("api.templates.email_change_subject", + map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"], + "TeamDisplayName": utils.Cfg.TeamSettings.SiteName}) bodyPage := utils.NewHTMLTemplate("email_change_body", locale) bodyPage.Props["SiteURL"] = siteURL @@ -122,7 +126,9 @@ func SendWelcomeEmail(userId string, email string, verified bool, locale, siteUR rawUrl, _ := url.Parse(siteURL) - subject := T("api.templates.welcome_subject", map[string]interface{}{"ServerURL": rawUrl.Host}) + subject := T("api.templates.welcome_subject", + map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"], + "ServerURL": rawUrl.Host}) bodyPage := utils.NewHTMLTemplate("welcome_body", locale) bodyPage.Props["SiteURL"] = siteURL @@ -154,7 +160,8 @@ func SendPasswordChangeEmail(email, method, locale, siteURL string) *model.AppEr T := utils.GetUserTranslations(locale) subject := T("api.templates.password_change_subject", - map[string]interface{}{"TeamDisplayName": utils.Cfg.TeamSettings.SiteName, "SiteName": utils.Cfg.TeamSettings.SiteName}) + map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"], + "TeamDisplayName": utils.Cfg.TeamSettings.SiteName}) bodyPage := utils.NewHTMLTemplate("password_change_body", locale) bodyPage.Props["SiteURL"] = siteURL @@ -169,11 +176,34 @@ func SendPasswordChangeEmail(email, method, locale, siteURL string) *model.AppEr return nil } +func SendPasswordResetEmail(email string, recovery *model.PasswordRecovery, locale, siteURL string) (bool, *model.AppError) { + + T := utils.GetUserTranslations(locale) + + link := fmt.Sprintf("%s/reset_password_complete?code=%s", siteURL, url.QueryEscape(recovery.Code)) + + subject := T("api.templates.reset_subject", + map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"]}) + + bodyPage := utils.NewHTMLTemplate("reset_body", locale) + bodyPage.Props["SiteURL"] = siteURL + bodyPage.Props["Title"] = T("api.templates.reset_body.title") + bodyPage.Html["Info"] = template.HTML(T("api.templates.reset_body.info")) + bodyPage.Props["ResetUrl"] = link + bodyPage.Props["Button"] = T("api.templates.reset_body.button") + + if err := utils.SendMail(email, subject, bodyPage.Render()); err != nil { + return false, model.NewLocAppError("SendPasswordReset", "api.user.send_password_reset.send.app_error", nil, "err="+err.Message) + } + + return true, nil +} + func SendMfaChangeEmail(email string, activated bool, locale, siteURL string) *model.AppError { T := utils.GetUserTranslations(locale) subject := T("api.templates.mfa_change_subject", - map[string]interface{}{"SiteName": utils.Cfg.TeamSettings.SiteName}) + map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"]}) bodyPage := utils.NewHTMLTemplate("mfa_change_body", locale) bodyPage.Props["SiteURL"] = siteURL @@ -203,7 +233,9 @@ func SendInviteEmails(team *model.Team, senderName string, invites []string, sit senderRole := utils.T("api.team.invite_members.member") subject := utils.T("api.templates.invite_subject", - map[string]interface{}{"SenderName": senderName, "TeamDisplayName": team.DisplayName, "SiteName": utils.ClientCfg["SiteName"]}) + map[string]interface{}{"SenderName": senderName, + "TeamDisplayName": team.DisplayName, + "SiteName": utils.ClientCfg["SiteName"]}) bodyPage := utils.NewHTMLTemplate("invite_body", model.DEFAULT_LOCALE) bodyPage.Props["SiteURL"] = siteURL diff --git a/app/email_test.go b/app/email_test.go index ecaa389bf..6cd46fee0 100644 --- a/app/email_test.go +++ b/app/email_test.go @@ -7,6 +7,7 @@ import ( "strings" "testing" + "github.com/mattermost/platform/model" "github.com/mattermost/platform/utils" ) @@ -18,8 +19,8 @@ func TestSendChangeUsernameEmail(t *testing.T) { var newUsername string = "fancyusername" var locale string = "en" var siteURL string = "" - var expectedPartialMessage string = "Your username for Mattermost has been changed to " + newUsername + "." - var expectedSubject string = "[" + utils.Cfg.TeamSettings.SiteName + "] Your username has changed for Mattermost" + var expectedPartialMessage string = "Your username for " + utils.Cfg.TeamSettings.SiteName + " has been changed to " + newUsername + "." + var expectedSubject string = "[" + utils.Cfg.TeamSettings.SiteName + "] Your username has changed" //Delete all the messages before check the sample email utils.DeleteMailBox(emailTo) @@ -33,7 +34,7 @@ func TestSendChangeUsernameEmail(t *testing.T) { t.Fatal("Wrong To recipient") } else { if resultsEmail, err := utils.GetMessageFromMailbox(emailTo, resultsMailbox[0].ID); err == nil { - if !strings.Contains(resultsEmail.Subject, expectedSubject) { + if resultsEmail.Subject != expectedSubject { t.Log(resultsEmail.Subject) t.Fatal("Wrong Subject") } @@ -55,7 +56,7 @@ func TestSendEmailChangeVerifyEmail(t *testing.T) { var locale string = "en" var siteURL string = "" var expectedPartialMessage string = "You updated your email" - var expectedSubject string = "[" + utils.Cfg.TeamSettings.SiteName + "] Verify new email address for Mattermost" + var expectedSubject string = "[" + utils.Cfg.TeamSettings.SiteName + "] Verify new email address" //Delete all the messages before check the sample email utils.DeleteMailBox(newUserEmail) @@ -69,7 +70,7 @@ func TestSendEmailChangeVerifyEmail(t *testing.T) { t.Fatal("Wrong To recipient") } else { if resultsEmail, err := utils.GetMessageFromMailbox(newUserEmail, resultsMailbox[0].ID); err == nil { - if !strings.Contains(resultsEmail.Subject, expectedSubject) { + if resultsEmail.Subject != expectedSubject { t.Log(resultsEmail.Subject) t.Fatal("Wrong Subject") } @@ -95,7 +96,7 @@ func TestSendEmailChangeEmail(t *testing.T) { var locale string = "en" var siteURL string = "" var expectedPartialMessage string = "Your email address for Mattermost has been changed to " + newUserEmail - var expectedSubject string = "[" + utils.Cfg.TeamSettings.SiteName + "] Your email address has changed for Mattermost" + var expectedSubject string = "[" + utils.Cfg.TeamSettings.SiteName + "] Your email address has changed" //Delete all the messages before check the sample email utils.DeleteMailBox(oldEmail) @@ -109,7 +110,7 @@ func TestSendEmailChangeEmail(t *testing.T) { t.Fatal("Wrong To recipient") } else { if resultsEmail, err := utils.GetMessageFromMailbox(oldEmail, resultsMailbox[0].ID); err == nil { - if !strings.Contains(resultsEmail.Subject, expectedSubject) { + if resultsEmail.Subject != expectedSubject { t.Log(resultsEmail.Subject) t.Fatal("Wrong Subject") } @@ -145,7 +146,7 @@ func TestSendVerifyEmail(t *testing.T) { t.Fatal("Wrong To recipient") } else { if resultsEmail, err := utils.GetMessageFromMailbox(userEmail, resultsMailbox[0].ID); err == nil { - if !strings.Contains(resultsEmail.Subject, expectedSubject) { + if resultsEmail.Subject != expectedSubject { t.Log(resultsEmail.Subject) t.Fatal("Wrong Subject") } @@ -171,7 +172,7 @@ func TestSendSignInChangeEmail(t *testing.T) { var siteURL string = "" var method string = "AD/LDAP" var expectedPartialMessage string = "You updated your sign-in method on Mattermost to " + method + "." - var expectedSubject string = "You updated your sign-in method on Mattermost" + var expectedSubject string = "[" + utils.Cfg.TeamSettings.SiteName + "] You updated your sign-in method on " + utils.Cfg.TeamSettings.SiteName //Delete all the messages before check the sample email utils.DeleteMailBox(email) @@ -185,7 +186,7 @@ func TestSendSignInChangeEmail(t *testing.T) { t.Fatal("Wrong To recipient") } else { if resultsEmail, err := utils.GetMessageFromMailbox(email, resultsMailbox[0].ID); err == nil { - if !strings.Contains(resultsEmail.Subject, expectedSubject) { + if resultsEmail.Subject != expectedSubject { t.Log(resultsEmail.Subject) t.Fatal("Wrong Subject") } @@ -208,7 +209,7 @@ func TestSendWelcomeEmail(t *testing.T) { var siteURL string = "http://test.mattermost.io" var verified bool = true var expectedPartialMessage string = "Mattermost lets you share messages and files from your PC or phone, with instant search and archiving" - var expectedSubject string = "You joined test.mattermost.io" + var expectedSubject string = "[" + utils.Cfg.TeamSettings.SiteName + "] You joined test.mattermost.io" //Delete all the messages before check the sample email utils.DeleteMailBox(email) @@ -222,7 +223,7 @@ func TestSendWelcomeEmail(t *testing.T) { t.Fatal("Wrong To recipient") } else { if resultsEmail, err := utils.GetMessageFromMailbox(email, resultsMailbox[0].ID); err == nil { - if !strings.Contains(resultsEmail.Subject, expectedSubject) { + if resultsEmail.Subject != expectedSubject { t.Log(resultsEmail.Subject) t.Fatal("Wrong Subject") } @@ -277,7 +278,7 @@ func TestSendPasswordChangeEmail(t *testing.T) { var siteURL string = "http://test.mattermost.io" var method string = "using a reset password link" var expectedPartialMessage string = "Your password has been updated for " + utils.Cfg.TeamSettings.SiteName + " on " + siteURL + " by " + method - var expectedSubject string = "Your password has been updated for " + utils.Cfg.TeamSettings.SiteName + " on " + utils.Cfg.TeamSettings.SiteName + var expectedSubject string = "[" + utils.Cfg.TeamSettings.SiteName + "] Your password has been updated" //Delete all the messages before check the sample email utils.DeleteMailBox(email) @@ -291,7 +292,7 @@ func TestSendPasswordChangeEmail(t *testing.T) { t.Fatal("Wrong To recipient") } else { if resultsEmail, err := utils.GetMessageFromMailbox(email, resultsMailbox[0].ID); err == nil { - if !strings.Contains(resultsEmail.Subject, expectedSubject) { + if resultsEmail.Subject != expectedSubject { t.Log(resultsEmail.Subject) t.Fatal("Wrong Subject") } @@ -313,7 +314,7 @@ func TestSendMfaChangeEmail(t *testing.T) { var siteURL string = "http://test.mattermost.io" var activated bool = true var expectedPartialMessage string = "Multi-factor authentication has been added to your account on " + siteURL + "." - var expectedSubject string = "Your MFA has been updated on " + utils.Cfg.TeamSettings.SiteName + var expectedSubject string = "[" + utils.Cfg.TeamSettings.SiteName + "] Your MFA has been updated" //Delete all the messages before check the sample email utils.DeleteMailBox(email) @@ -327,7 +328,7 @@ func TestSendMfaChangeEmail(t *testing.T) { t.Fatal("Wrong To recipient") } else { if resultsEmail, err := utils.GetMessageFromMailbox(email, resultsMailbox[0].ID); err == nil { - if !strings.Contains(resultsEmail.Subject, expectedSubject) { + if resultsEmail.Subject != expectedSubject { t.Log(resultsEmail.Subject) t.Fatal("Wrong Subject") } @@ -375,7 +376,7 @@ func TestSendInviteEmails(t *testing.T) { var siteURL string = "http://test.mattermost.io" invites := []string{email1, email2} var expectedPartialMessage string = "The team member *" + senderName + "* , has invited you to join *" + th.BasicTeam.DisplayName + "*" - var expectedSubject string = senderName + " invited you to join " + th.BasicTeam.DisplayName + " Team on " + utils.Cfg.TeamSettings.SiteName + var expectedSubject string = "[" + utils.Cfg.TeamSettings.SiteName + "] " + senderName + " invited you to join " + th.BasicTeam.DisplayName + " Team" //Delete all the messages before check the sample email utils.DeleteMailBox(email1) @@ -388,7 +389,7 @@ func TestSendInviteEmails(t *testing.T) { t.Fatal("Wrong To recipient") } else { if resultsEmail, err := utils.GetMessageFromMailbox(email1, resultsMailbox[0].ID); err == nil { - if !strings.Contains(resultsEmail.Subject, expectedSubject) { + if resultsEmail.Subject != expectedSubject { t.Log(resultsEmail.Subject) t.Log(expectedSubject) t.Fatal("Wrong Subject") @@ -417,3 +418,48 @@ func TestSendInviteEmails(t *testing.T) { } } } + +func TestSendPasswordReset(t *testing.T) { + th := Setup().InitBasic() + utils.LoadConfig("config.json") + + var siteURL string = "http://test.mattermost.io" + // var locale string = "en" + var expectedPartialMessage string = "To change your password" + var expectedSubject string = "[" + utils.Cfg.TeamSettings.SiteName + "] Reset your password" + + //Delete all the messages before check the sample email + utils.DeleteMailBox(th.BasicUser.Email) + + if _, err := SendPasswordReset(th.BasicUser.Email, siteURL); err != nil { + t.Log(err) + t.Fatal("Should send change username email") + } else { + //Check if the email was send to the rigth email address + if resultsMailbox, err := utils.GetMailBox(th.BasicUser.Email); err != nil && !strings.ContainsAny(resultsMailbox[0].To[0], th.BasicUser.Email) { + t.Fatal("Wrong To recipient") + } else { + if resultsEmail, err := utils.GetMessageFromMailbox(th.BasicUser.Email, resultsMailbox[0].ID); err == nil { + if resultsEmail.Subject != expectedSubject { + t.Log(resultsEmail.Subject) + t.Fatal("Wrong Subject") + } + if !strings.Contains(resultsEmail.Body.Text, expectedPartialMessage) { + t.Log(resultsEmail.Body.Text) + t.Fatal("Wrong Body message") + } + var recoveryKey *model.PasswordRecovery + if result := <-Srv.Store.PasswordRecovery().Get(th.BasicUser.Id); result.Err != nil { + t.Fatal(result.Err) + } else { + recoveryKey = result.Data.(*model.PasswordRecovery) + if !strings.Contains(resultsEmail.Body.Text, recoveryKey.Code) { + t.Log(resultsEmail.Body.Text) + t.Log(recoveryKey.Code) + t.Fatal("Received wrong recovery code") + } + } + } + } + } +} diff --git a/app/user.go b/app/user.go index 53e389947..d1ddceb23 100644 --- a/app/user.go +++ b/app/user.go @@ -7,7 +7,6 @@ import ( "bytes" "fmt" "hash/fnv" - "html/template" "image" "image/color" "image/draw" @@ -18,7 +17,6 @@ import ( "io/ioutil" "mime/multipart" "net/http" - "net/url" "strconv" "strings" @@ -989,42 +987,6 @@ func UpdatePasswordSendEmail(user *model.User, newPassword, method, siteURL stri return nil } -func SendPasswordReset(email string, siteURL string) (bool, *model.AppError) { - var user *model.User - var err *model.AppError - if user, err = GetUserByEmail(email); err != nil { - return false, nil - } - - if user.AuthData != nil && len(*user.AuthData) != 0 { - return false, model.NewAppError("SendPasswordReset", "api.user.send_password_reset.sso.app_error", nil, "userId="+user.Id, http.StatusBadRequest) - } - - var recovery *model.PasswordRecovery - if recovery, err = CreatePasswordRecovery(user.Id); err != nil { - return false, err - } - - T := utils.GetUserTranslations(user.Locale) - - link := fmt.Sprintf("%s/reset_password_complete?code=%s", siteURL, url.QueryEscape(recovery.Code)) - - subject := T("api.templates.reset_subject") - - bodyPage := utils.NewHTMLTemplate("reset_body", user.Locale) - bodyPage.Props["SiteURL"] = siteURL - bodyPage.Props["Title"] = T("api.templates.reset_body.title") - bodyPage.Html["Info"] = template.HTML(T("api.templates.reset_body.info")) - bodyPage.Props["ResetUrl"] = link - bodyPage.Props["Button"] = T("api.templates.reset_body.button") - - if err := utils.SendMail(email, subject, bodyPage.Render()); err != nil { - return false, model.NewLocAppError("SendPasswordReset", "api.user.send_password_reset.send.app_error", nil, "err="+err.Message) - } - - return true, nil -} - func ResetPasswordFromCode(code, newPassword, siteURL string) *model.AppError { var recovery *model.PasswordRecovery var err *model.AppError @@ -1058,6 +1020,29 @@ func ResetPasswordFromCode(code, newPassword, siteURL string) *model.AppError { return nil } +func SendPasswordReset(email string, siteURL string) (bool, *model.AppError) { + var user *model.User + var err *model.AppError + if user, err = GetUserByEmail(email); err != nil { + return false, nil + } + + if user.AuthData != nil && len(*user.AuthData) != 0 { + return false, model.NewAppError("SendPasswordReset", "api.user.send_password_reset.sso.app_error", nil, "userId="+user.Id, http.StatusBadRequest) + } + + var recovery *model.PasswordRecovery + if recovery, err = CreatePasswordRecovery(user.Id); err != nil { + return false, err + } + + if _, err := SendPasswordResetEmail(email, recovery, user.Locale, siteURL); err != nil { + return false, model.NewLocAppError("SendPasswordReset", "api.user.send_password_reset.send.app_error", nil, "err="+err.Message) + } + + return true, nil +} + func CreatePasswordRecovery(userId string) (*model.PasswordRecovery, *model.AppError) { recovery := &model.PasswordRecovery{} recovery.UserId = userId -- cgit v1.2.3-1-g7c22