github.com/gigforks/mattermost-server@v4.9.1-0.20180619094218-800d97fa55d0+incompatible/app/email.go (about) 1 // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "fmt" 8 "net/url" 9 10 "net/http" 11 12 "github.com/nicksnyder/go-i18n/i18n" 13 14 "github.com/mattermost/mattermost-server/mlog" 15 "github.com/mattermost/mattermost-server/model" 16 "github.com/mattermost/mattermost-server/utils" 17 ) 18 19 func (a *App) SendChangeUsernameEmail(oldUsername, newUsername, email, locale, siteURL string) *model.AppError { 20 T := utils.GetUserTranslations(locale) 21 22 subject := T("api.templates.username_change_subject", 23 map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"], 24 "TeamDisplayName": a.Config().TeamSettings.SiteName}) 25 26 bodyPage := a.NewEmailTemplate("email_change_body", locale) 27 bodyPage.Props["SiteURL"] = siteURL 28 bodyPage.Props["Title"] = T("api.templates.username_change_body.title") 29 bodyPage.Html["Info"] = utils.TranslateAsHtml(T, "api.templates.username_change_body.info", 30 map[string]interface{}{"TeamDisplayName": a.Config().TeamSettings.SiteName, "NewUsername": newUsername}) 31 32 if err := a.SendMail(email, subject, bodyPage.Render()); err != nil { 33 return model.NewAppError("SendChangeUsernameEmail", "api.user.send_email_change_username_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 34 } 35 36 return nil 37 } 38 39 func (a *App) SendEmailChangeVerifyEmail(newUserEmail, locale, siteURL, token string) *model.AppError { 40 T := utils.GetUserTranslations(locale) 41 42 link := fmt.Sprintf("%s/do_verify_email?token=%s&email=%s", siteURL, token, url.QueryEscape(newUserEmail)) 43 44 subject := T("api.templates.email_change_verify_subject", 45 map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"], 46 "TeamDisplayName": a.Config().TeamSettings.SiteName}) 47 48 bodyPage := a.NewEmailTemplate("email_change_verify_body", locale) 49 bodyPage.Props["SiteURL"] = siteURL 50 bodyPage.Props["Title"] = T("api.templates.email_change_verify_body.title") 51 bodyPage.Props["Info"] = T("api.templates.email_change_verify_body.info", 52 map[string]interface{}{"TeamDisplayName": a.Config().TeamSettings.SiteName}) 53 bodyPage.Props["VerifyUrl"] = link 54 bodyPage.Props["VerifyButton"] = T("api.templates.email_change_verify_body.button") 55 56 if err := a.SendMail(newUserEmail, subject, bodyPage.Render()); err != nil { 57 return model.NewAppError("SendEmailChangeVerifyEmail", "api.user.send_email_change_verify_email_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 58 } 59 60 return nil 61 } 62 63 func (a *App) SendEmailChangeEmail(oldEmail, newEmail, locale, siteURL string) *model.AppError { 64 T := utils.GetUserTranslations(locale) 65 66 subject := T("api.templates.email_change_subject", 67 map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"], 68 "TeamDisplayName": a.Config().TeamSettings.SiteName}) 69 70 bodyPage := a.NewEmailTemplate("email_change_body", locale) 71 bodyPage.Props["SiteURL"] = siteURL 72 bodyPage.Props["Title"] = T("api.templates.email_change_body.title") 73 bodyPage.Html["Info"] = utils.TranslateAsHtml(T, "api.templates.email_change_body.info", 74 map[string]interface{}{"TeamDisplayName": a.Config().TeamSettings.SiteName, "NewEmail": newEmail}) 75 76 if err := a.SendMail(oldEmail, subject, bodyPage.Render()); err != nil { 77 return model.NewAppError("SendEmailChangeEmail", "api.user.send_email_change_email_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 78 } 79 80 return nil 81 } 82 83 func (a *App) SendVerifyEmail(userEmail, locale, siteURL, token string) *model.AppError { 84 T := utils.GetUserTranslations(locale) 85 86 link := fmt.Sprintf("%s/do_verify_email?token=%s&email=%s", siteURL, token, url.QueryEscape(userEmail)) 87 88 url, _ := url.Parse(siteURL) 89 90 subject := T("api.templates.verify_subject", 91 map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"]}) 92 93 bodyPage := a.NewEmailTemplate("verify_body", locale) 94 bodyPage.Props["SiteURL"] = siteURL 95 bodyPage.Props["Title"] = T("api.templates.verify_body.title", map[string]interface{}{"ServerURL": url.Host}) 96 bodyPage.Props["Info"] = T("api.templates.verify_body.info") 97 bodyPage.Props["VerifyUrl"] = link 98 bodyPage.Props["Button"] = T("api.templates.verify_body.button") 99 100 if err := a.SendMail(userEmail, subject, bodyPage.Render()); err != nil { 101 return model.NewAppError("SendVerifyEmail", "api.user.send_verify_email_and_forget.failed.error", nil, err.Error(), http.StatusInternalServerError) 102 } 103 104 return nil 105 } 106 107 func (a *App) SendSignInChangeEmail(email, method, locale, siteURL string) *model.AppError { 108 T := utils.GetUserTranslations(locale) 109 110 subject := T("api.templates.signin_change_email.subject", 111 map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"]}) 112 113 bodyPage := a.NewEmailTemplate("signin_change_body", locale) 114 bodyPage.Props["SiteURL"] = siteURL 115 bodyPage.Props["Title"] = T("api.templates.signin_change_email.body.title") 116 bodyPage.Html["Info"] = utils.TranslateAsHtml(T, "api.templates.signin_change_email.body.info", 117 map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"], "Method": method}) 118 119 if err := a.SendMail(email, subject, bodyPage.Render()); err != nil { 120 return model.NewAppError("SendSignInChangeEmail", "api.user.send_sign_in_change_email_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 121 } 122 123 return nil 124 } 125 126 func (a *App) SendWelcomeEmail(userId string, email string, verified bool, locale, siteURL string) *model.AppError { 127 T := utils.GetUserTranslations(locale) 128 129 rawUrl, _ := url.Parse(siteURL) 130 131 subject := T("api.templates.welcome_subject", 132 map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"], 133 "ServerURL": rawUrl.Host}) 134 135 bodyPage := a.NewEmailTemplate("welcome_body", locale) 136 bodyPage.Props["SiteURL"] = siteURL 137 bodyPage.Props["Title"] = T("api.templates.welcome_body.title", map[string]interface{}{"ServerURL": rawUrl.Host}) 138 bodyPage.Props["Info"] = T("api.templates.welcome_body.info") 139 bodyPage.Props["Button"] = T("api.templates.welcome_body.button") 140 bodyPage.Props["Info2"] = T("api.templates.welcome_body.info2") 141 bodyPage.Props["Info3"] = T("api.templates.welcome_body.info3") 142 bodyPage.Props["SiteURL"] = siteURL 143 144 if *a.Config().NativeAppSettings.AppDownloadLink != "" { 145 bodyPage.Props["AppDownloadInfo"] = T("api.templates.welcome_body.app_download_info") 146 bodyPage.Props["AppDownloadLink"] = *a.Config().NativeAppSettings.AppDownloadLink 147 } 148 149 if !verified { 150 token, err := a.CreateVerifyEmailToken(userId) 151 if err != nil { 152 return err 153 } 154 link := fmt.Sprintf("%s/do_verify_email?token=%s&email=%s", siteURL, token.Token, url.QueryEscape(email)) 155 bodyPage.Props["VerifyUrl"] = link 156 } 157 158 if err := a.SendMail(email, subject, bodyPage.Render()); err != nil { 159 return model.NewAppError("SendWelcomeEmail", "api.user.send_welcome_email_and_forget.failed.error", nil, err.Error(), http.StatusInternalServerError) 160 } 161 162 return nil 163 } 164 165 func (a *App) SendPasswordChangeEmail(email, method, locale, siteURL string) *model.AppError { 166 T := utils.GetUserTranslations(locale) 167 168 subject := T("api.templates.password_change_subject", 169 map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"], 170 "TeamDisplayName": a.Config().TeamSettings.SiteName}) 171 172 bodyPage := a.NewEmailTemplate("password_change_body", locale) 173 bodyPage.Props["SiteURL"] = siteURL 174 bodyPage.Props["Title"] = T("api.templates.password_change_body.title") 175 bodyPage.Html["Info"] = utils.TranslateAsHtml(T, "api.templates.password_change_body.info", 176 map[string]interface{}{"TeamDisplayName": a.Config().TeamSettings.SiteName, "TeamURL": siteURL, "Method": method}) 177 178 if err := a.SendMail(email, subject, bodyPage.Render()); err != nil { 179 return model.NewAppError("SendPasswordChangeEmail", "api.user.send_password_change_email_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 180 } 181 182 return nil 183 } 184 185 func (a *App) SendUserAccessTokenAddedEmail(email, locale string) *model.AppError { 186 T := utils.GetUserTranslations(locale) 187 188 subject := T("api.templates.user_access_token_subject", 189 map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"]}) 190 191 bodyPage := a.NewEmailTemplate("password_change_body", locale) 192 bodyPage.Props["Title"] = T("api.templates.user_access_token_body.title") 193 bodyPage.Html["Info"] = utils.TranslateAsHtml(T, "api.templates.user_access_token_body.info", 194 map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"], "SiteURL": a.GetSiteURL()}) 195 196 if err := a.SendMail(email, subject, bodyPage.Render()); err != nil { 197 return model.NewAppError("SendUserAccessTokenAddedEmail", "api.user.send_user_access_token.error", nil, err.Error(), http.StatusInternalServerError) 198 } 199 200 return nil 201 } 202 203 func (a *App) SendPasswordResetEmail(email string, token *model.Token, locale, siteURL string) (bool, *model.AppError) { 204 205 T := utils.GetUserTranslations(locale) 206 207 link := fmt.Sprintf("%s/reset_password_complete?token=%s", siteURL, url.QueryEscape(token.Token)) 208 209 subject := T("api.templates.reset_subject", 210 map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"]}) 211 212 bodyPage := a.NewEmailTemplate("reset_body", locale) 213 bodyPage.Props["SiteURL"] = siteURL 214 bodyPage.Props["Title"] = T("api.templates.reset_body.title") 215 bodyPage.Html["Info"] = utils.TranslateAsHtml(T, "api.templates.reset_body.info", nil) 216 bodyPage.Props["ResetUrl"] = link 217 bodyPage.Props["Button"] = T("api.templates.reset_body.button") 218 219 if err := a.SendMail(email, subject, bodyPage.Render()); err != nil { 220 return false, model.NewAppError("SendPasswordReset", "api.user.send_password_reset.send.app_error", nil, "err="+err.Message, http.StatusInternalServerError) 221 } 222 223 return true, nil 224 } 225 226 func (a *App) SendMfaChangeEmail(email string, activated bool, locale, siteURL string) *model.AppError { 227 T := utils.GetUserTranslations(locale) 228 229 subject := T("api.templates.mfa_change_subject", 230 map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"]}) 231 232 bodyPage := a.NewEmailTemplate("mfa_change_body", locale) 233 bodyPage.Props["SiteURL"] = siteURL 234 235 bodyText := "" 236 if activated { 237 bodyText = "api.templates.mfa_activated_body.info" 238 bodyPage.Props["Title"] = T("api.templates.mfa_activated_body.title") 239 } else { 240 bodyText = "api.templates.mfa_deactivated_body.info" 241 bodyPage.Props["Title"] = T("api.templates.mfa_deactivated_body.title") 242 } 243 244 bodyPage.Html["Info"] = utils.TranslateAsHtml(T, bodyText, map[string]interface{}{"SiteURL": siteURL}) 245 246 if err := a.SendMail(email, subject, bodyPage.Render()); err != nil { 247 return model.NewAppError("SendMfaChangeEmail", "api.user.send_mfa_change_email.error", nil, err.Error(), http.StatusInternalServerError) 248 } 249 250 return nil 251 } 252 253 func (a *App) SendInviteEmails(team *model.Team, senderName string, invites []string, siteURL string) { 254 for _, invite := range invites { 255 if len(invite) > 0 { 256 senderRole := utils.T("api.team.invite_members.member") 257 258 subject := utils.T("api.templates.invite_subject", 259 map[string]interface{}{"SenderName": senderName, 260 "TeamDisplayName": team.DisplayName, 261 "SiteName": a.ClientConfig()["SiteName"]}) 262 263 bodyPage := a.NewEmailTemplate("invite_body", model.DEFAULT_LOCALE) 264 bodyPage.Props["SiteURL"] = siteURL 265 bodyPage.Props["Title"] = utils.T("api.templates.invite_body.title") 266 bodyPage.Html["Info"] = utils.TranslateAsHtml(utils.T, "api.templates.invite_body.info", 267 map[string]interface{}{"SenderStatus": senderRole, "SenderName": senderName, "TeamDisplayName": team.DisplayName}) 268 bodyPage.Props["Info"] = map[string]interface{}{} 269 bodyPage.Props["Button"] = utils.T("api.templates.invite_body.button") 270 bodyPage.Html["ExtraInfo"] = utils.TranslateAsHtml(utils.T, "api.templates.invite_body.extra_info", 271 map[string]interface{}{"TeamDisplayName": team.DisplayName, "TeamURL": siteURL + "/" + team.Name}) 272 273 token := model.NewToken( 274 TOKEN_TYPE_TEAM_INVITATION, 275 model.MapToJson(map[string]string{"teamId": team.Id, "email": invite}), 276 ) 277 278 props := make(map[string]string) 279 props["email"] = invite 280 props["display_name"] = team.DisplayName 281 props["name"] = team.Name 282 data := model.MapToJson(props) 283 284 if result := <-a.Srv.Store.Token().Save(token); result.Err != nil { 285 mlog.Error(fmt.Sprintf("Failed to send invite email successfully err=%v", result.Err)) 286 continue 287 } 288 bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_user_complete/?d=%s&t=%s", siteURL, url.QueryEscape(data), url.QueryEscape(token.Token)) 289 290 if !a.Config().EmailSettings.SendEmailNotifications { 291 mlog.Info(fmt.Sprintf("sending invitation to %v %v", invite, bodyPage.Props["Link"])) 292 } 293 294 if err := a.SendMail(invite, subject, bodyPage.Render()); err != nil { 295 mlog.Error(fmt.Sprintf("Failed to send invite email successfully err=%v", err)) 296 } 297 } 298 } 299 } 300 301 func (a *App) NewEmailTemplate(name, locale string) *utils.HTMLTemplate { 302 t := utils.NewHTMLTemplate(a.HTMLTemplates(), name) 303 304 var localT i18n.TranslateFunc 305 if locale != "" { 306 localT = utils.GetUserTranslations(locale) 307 } else { 308 localT = utils.T 309 } 310 311 t.Props["Footer"] = localT("api.templates.email_footer") 312 313 if *a.Config().EmailSettings.FeedbackOrganization != "" { 314 t.Props["Organization"] = localT("api.templates.email_organization") + *a.Config().EmailSettings.FeedbackOrganization 315 } else { 316 t.Props["Organization"] = "" 317 } 318 319 t.Html["EmailInfo"] = utils.TranslateAsHtml(localT, "api.templates.email_info", 320 map[string]interface{}{"SupportEmail": *a.Config().SupportSettings.SupportEmail, "SiteName": a.Config().TeamSettings.SiteName}) 321 322 return t 323 } 324 325 func (a *App) SendMail(to, subject, htmlBody string) *model.AppError { 326 license := a.License() 327 return utils.SendMailUsingConfig(to, subject, htmlBody, a.Config(), license != nil && *license.Features.Compliance) 328 }