diff --git a/emails/templates/invited_to_org.mjml b/emails/templates/invited_to_org.mjml index d85a011dbc5..f1f8a0c8273 100644 --- a/emails/templates/invited_to_org.mjml +++ b/emails/templates/invited_to_org.mjml @@ -2,7 +2,7 @@ - {{ Subject .Subject "{{ .InvitedBy }} has added you to the {{ .OrgName }} organization" }} + {{ Subject .Subject .TemplateData "{{ .InvitedBy }} has added you to the {{ .OrgName }} organization" }} diff --git a/emails/templates/invited_to_org.txt b/emails/templates/invited_to_org.txt index b2ae9e8a1ac..56bcf80318e 100644 --- a/emails/templates/invited_to_org.txt +++ b/emails/templates/invited_to_org.txt @@ -1,4 +1,4 @@ -[[Subject .Subject "[[.InvitedBy]] has added you to the [[.OrgName]] organization"]] +[[HiddenSubject .Subject "[[.InvitedBy]] has added you to the [[.OrgName]] organization"]] You have been added to [[.OrgName]] diff --git a/emails/templates/new_user_invite.mjml b/emails/templates/new_user_invite.mjml index 66c28de9454..d965d329ce9 100644 --- a/emails/templates/new_user_invite.mjml +++ b/emails/templates/new_user_invite.mjml @@ -2,7 +2,7 @@ - {{ Subject .Subject "{{ .InvitedBy }} has invited you to join Grafana" }} + {{ Subject .Subject .TemplateData "{{ .InvitedBy }} has invited you to join Grafana" }} diff --git a/emails/templates/new_user_invite.txt b/emails/templates/new_user_invite.txt index bfb0cb15cee..2c73c5e9c44 100644 --- a/emails/templates/new_user_invite.txt +++ b/emails/templates/new_user_invite.txt @@ -1,4 +1,4 @@ -[[Subject .Subject "[[.InvitedBy]] has invited you to join Grafana"]] +[[HiddenSubject .Subject "[[.InvitedBy]] has invited you to join Grafana"]] You're invited to join [[.OrgName]] diff --git a/emails/templates/ng_alert_notification.mjml b/emails/templates/ng_alert_notification.mjml index f5ff61069c4..4e919458666 100644 --- a/emails/templates/ng_alert_notification.mjml +++ b/emails/templates/ng_alert_notification.mjml @@ -2,7 +2,7 @@ - {{ Subject .Subject "{{ .Title }}" }} + {{ Subject .Subject .TemplateData "{{ .Title }}" }} diff --git a/emails/templates/ng_alert_notification.txt b/emails/templates/ng_alert_notification.txt index b387748b3f7..758beb49afe 100644 --- a/emails/templates/ng_alert_notification.txt +++ b/emails/templates/ng_alert_notification.txt @@ -1,4 +1,4 @@ -[[Subject .Subject "[[.Title]]"]] +[[HiddenSubject .Subject "[[.Title]]"]] [[.Title]] ---------------- diff --git a/emails/templates/reset_password.mjml b/emails/templates/reset_password.mjml index f1face73715..c3e8713a865 100644 --- a/emails/templates/reset_password.mjml +++ b/emails/templates/reset_password.mjml @@ -2,7 +2,7 @@ - {{ Subject .Subject "Reset your Grafana password - {{.Name}}" }} + {{ Subject .Subject .TemplateData "Reset your Grafana password - {{.Name}}" }} diff --git a/emails/templates/reset_password.txt b/emails/templates/reset_password.txt index a983a44c825..a33edbb0295 100644 --- a/emails/templates/reset_password.txt +++ b/emails/templates/reset_password.txt @@ -1,4 +1,4 @@ -[[Subject .Subject "Reset your Grafana password - [[.Name]]"]] +[[HiddenSubject .Subject "Reset your Grafana password - [[.Name]]"]] Hi [[.Name]], diff --git a/emails/templates/signup_started.mjml b/emails/templates/signup_started.mjml index 98b85a6e955..21ba7299b85 100644 --- a/emails/templates/signup_started.mjml +++ b/emails/templates/signup_started.mjml @@ -2,7 +2,7 @@ - {{ Subject .Subject "Welcome to Grafana, please complete your sign up!" }} + {{ Subject .Subject .TemplateData "Welcome to Grafana, please complete your sign up!" }} diff --git a/emails/templates/signup_started.txt b/emails/templates/signup_started.txt index 12aa0d87fd7..4ab7342da15 100644 --- a/emails/templates/signup_started.txt +++ b/emails/templates/signup_started.txt @@ -1,4 +1,4 @@ -[[Subject .Subject "Welcome to Grafana, please complete your sign up!"]] +[[HiddenSubject .Subject "Welcome to Grafana, please complete your sign up!"]] Complete the signup diff --git a/emails/templates/welcome_on_signup.mjml b/emails/templates/welcome_on_signup.mjml index 642496c3762..e54fdd798c4 100644 --- a/emails/templates/welcome_on_signup.mjml +++ b/emails/templates/welcome_on_signup.mjml @@ -2,7 +2,7 @@ - {{ Subject .Subject "Welcome to Grafana" }} + {{ Subject .Subject .TemplateData "Welcome to Grafana" }} diff --git a/emails/templates/welcome_on_signup.txt b/emails/templates/welcome_on_signup.txt index 6df3c15d205..78ca607fd2a 100644 --- a/emails/templates/welcome_on_signup.txt +++ b/emails/templates/welcome_on_signup.txt @@ -1,4 +1,4 @@ -[[Subject .Subject "Welcome to Grafana"]] +[[HiddenSubject .Subject "Welcome to Grafana"]] Hi [[.Name]], diff --git a/pkg/services/notifications/email.go b/pkg/services/notifications/email.go index 120ca0d729a..1077d0c19a4 100644 --- a/pkg/services/notifications/email.go +++ b/pkg/services/notifications/email.go @@ -33,4 +33,9 @@ func setDefaultTemplateData(cfg *setting.Cfg, data map[string]interface{}, u *us if u != nil { data["Name"] = u.NameOrFallback() } + dataCopy := map[string]interface{}{} + for k, v := range data { + dataCopy[k] = v + } + data["TemplateData"] = dataCopy } diff --git a/pkg/services/notifications/mailer.go b/pkg/services/notifications/mailer.go index 827e2f4973e..4552a494c72 100644 --- a/pkg/services/notifications/mailer.go +++ b/pkg/services/notifications/mailer.go @@ -82,26 +82,31 @@ func (ns *NotificationService) buildEmailMessage(cmd *SendEmailCommand) (*Messag subject := cmd.Subject if cmd.Subject == "" { - var subjectText interface{} subjectData := data["Subject"].(map[string]interface{}) - subjectText, hasSubject := subjectData["value"] + subjectText, hasSubject := subjectData["executed_template"].(string) + if hasSubject { + // first check to see if the template has already been executed in a template func + subject = subjectText + } else { + subjectTemplate, hasSubject := subjectData["value"] - if !hasSubject { - return nil, fmt.Errorf("missing subject in template %s", cmd.Template) + if !hasSubject { + return nil, fmt.Errorf("missing subject in template %s", cmd.Template) + } + + subjectTmpl, err := template.New("subject").Parse(subjectTemplate.(string)) + if err != nil { + return nil, err + } + + var subjectBuffer bytes.Buffer + err = subjectTmpl.ExecuteTemplate(&subjectBuffer, "subject", data) + if err != nil { + return nil, err + } + + subject = subjectBuffer.String() } - - subjectTmpl, err := template.New("subject").Parse(subjectText.(string)) - if err != nil { - return nil, err - } - - var subjectBuffer bytes.Buffer - err = subjectTmpl.ExecuteTemplate(&subjectBuffer, "subject", data) - if err != nil { - return nil, err - } - - subject = subjectBuffer.String() } addr := mail.Address{Name: ns.Cfg.Smtp.FromName, Address: ns.Cfg.Smtp.FromAddress} diff --git a/pkg/services/notifications/notifications.go b/pkg/services/notifications/notifications.go index f481f8b355d..e81897ef5a0 100644 --- a/pkg/services/notifications/notifications.go +++ b/pkg/services/notifications/notifications.go @@ -1,6 +1,7 @@ package notifications import ( + "bytes" "context" "errors" "fmt" @@ -53,7 +54,8 @@ func ProvideService(bus bus.Bus, cfg *setting.Cfg, mailer Mailer, store TempUser mailTemplates = template.New("name") mailTemplates.Funcs(template.FuncMap{ - "Subject": subjectTemplateFunc, + "Subject": subjectTemplateFunc, + "HiddenSubject": hiddenSubjectTemplateFunc, }) mailTemplates.Funcs(sprig.FuncMap()) @@ -143,11 +145,35 @@ func (ns *NotificationService) SendWebhookSync(ctx context.Context, cmd *SendWeb }) } -func subjectTemplateFunc(obj map[string]interface{}, value string) string { +// hiddenSubjectTemplateFunc sets the subject template (value) on the map represented by `.Subject.` (obj) so that it can be compiled and executed later. +// It returns a blank string, so there will be no resulting value left in place of the template. +func hiddenSubjectTemplateFunc(obj map[string]interface{}, value string) string { obj["value"] = value return "" } +// subjectTemplateFunc does the same thing has hiddenSubjectTemplateFunc, but in addition it executes and returns the subject template using the data represented in `.TemplateData` (data) +// This results in the template being replaced by the subject string. +func subjectTemplateFunc(obj map[string]interface{}, data map[string]interface{}, value string) string { + obj["value"] = value + + titleTmpl, err := template.New("title").Parse(value) + if err != nil { + return "" + } + + var buf bytes.Buffer + err = titleTmpl.ExecuteTemplate(&buf, "title", data) + if err != nil { + return "" + } + + subj := buf.String() + // Since we have already executed the template, save it to subject data so we don't have to do it again later on + obj["executed_template"] = subj + return subj +} + func (ns *NotificationService) SendEmailCommandHandlerSync(ctx context.Context, cmd *SendEmailCommandSync) error { message, err := ns.buildEmailMessage(&SendEmailCommand{ Data: cmd.Data, diff --git a/pkg/services/notifications/send_email_integration_test.go b/pkg/services/notifications/send_email_integration_test.go index 482848f03b5..90e9631937e 100644 --- a/pkg/services/notifications/send_email_integration_test.go +++ b/pkg/services/notifications/send_email_integration_test.go @@ -12,19 +12,17 @@ import ( func TestEmailIntegrationTest(t *testing.T) { t.Run("Given the notifications service", func(t *testing.T) { - t.Skip() - - setting.StaticRootPath = "../../../public/" setting.BuildVersion = "4.0.0" - ns := &NotificationService{} - ns.Bus = newBus(t) - ns.Cfg = setting.NewCfg() - ns.Cfg.Smtp.Enabled = true - ns.Cfg.Smtp.TemplatesPatterns = []string{"emails/*.html", "emails/*.txt"} - ns.Cfg.Smtp.FromAddress = "from@address.com" - ns.Cfg.Smtp.FromName = "Grafana Admin" - ns.Cfg.Smtp.ContentTypes = []string{"text/html", "text/plain"} + cfg := setting.NewCfg() + cfg.Smtp.Enabled = true + cfg.StaticRootPath = "../../../public/" + cfg.Smtp.TemplatesPatterns = []string{"emails/*.html", "emails/*.txt"} + cfg.Smtp.FromAddress = "from@address.com" + cfg.Smtp.FromName = "Grafana Admin" + cfg.Smtp.ContentTypes = []string{"text/html", "text/plain"} + ns, err := ProvideService(newBus(t), cfg, NewFakeMailer(), nil) + require.NoError(t, err) t.Run("When sending reset email password", func(t *testing.T) { cmd := &SendEmailCommand{ @@ -59,11 +57,19 @@ func TestEmailIntegrationTest(t *testing.T) { require.NoError(t, err) sentMsg := <-ns.mailQueue - require.Equal(t, sentMsg.From, "Grafana Admin ") - require.Equal(t, sentMsg.To[0], "asdf@asdf.com") - err = os.WriteFile("../../../tmp/test_email.html", []byte(sentMsg.Body["text/html"]), 0777) + require.Equal(t, "\"Grafana Admin\" ", sentMsg.From) + require.Equal(t, "asdf@asdf.com", sentMsg.To[0]) + require.Equal(t, "[CRITICAL] Imaginary timeseries alert", sentMsg.Subject) + require.Contains(t, sentMsg.Body["text/html"], "[CRITICAL] Imaginary timeseries alert") + + path, err := os.MkdirTemp("../../..", "tmp") require.NoError(t, err) - err = os.WriteFile("../../../tmp/test_email.txt", []byte(sentMsg.Body["text/plain"]), 0777) + t.Cleanup(func() { + _ = os.RemoveAll(path) + }) + err = os.WriteFile(path+"/test_email.html", []byte(sentMsg.Body["text/html"]), 0777) + require.NoError(t, err) + err = os.WriteFile(path+"/test_email.txt", []byte(sentMsg.Body["text/plain"]), 0777) require.NoError(t, err) }) }) diff --git a/public/emails/alert_notification.html b/public/emails/alert_notification.html index 15e1c36dd43..4408da8d916 100644 --- a/public/emails/alert_notification.html +++ b/public/emails/alert_notification.html @@ -1,6 +1,7 @@ + {{Subject .Subject .TemplateData "{{.Title}}"}} @@ -204,7 +205,6 @@ text-decoration: underline; - {{Subject .Subject "{{.Title}}"}} diff --git a/public/emails/alert_notification.txt b/public/emails/alert_notification.txt index 9e16ea5574f..bd2942b356f 100644 --- a/public/emails/alert_notification.txt +++ b/public/emails/alert_notification.txt @@ -1,4 +1,4 @@ -{{Subject .Subject "{{.Title}}"}} +{{HiddenSubject .Subject "{{.Title}}"}} {{.Title}} ---------------- diff --git a/public/emails/invited_to_org.html b/public/emails/invited_to_org.html index edbab072a83..ad3f5f57a6b 100644 --- a/public/emails/invited_to_org.html +++ b/public/emails/invited_to_org.html @@ -3,7 +3,7 @@ - {{ Subject .Subject "{{ .InvitedBy }} has added you to the {{ .OrgName }} organization" }} + {{ Subject .Subject .TemplateData "{{ .InvitedBy }} has added you to the {{ .OrgName }} organization" }} diff --git a/public/emails/invited_to_org.txt b/public/emails/invited_to_org.txt index 61982198bef..c0dd496f6f9 100644 --- a/public/emails/invited_to_org.txt +++ b/public/emails/invited_to_org.txt @@ -1,4 +1,4 @@ -{{Subject .Subject "{{.InvitedBy}} has added you to the {{.OrgName}} organization"}} +{{HiddenSubject .Subject "{{.InvitedBy}} has added you to the {{.OrgName}} organization"}} You have been added to {{.OrgName}} diff --git a/public/emails/new_user_invite.html b/public/emails/new_user_invite.html index dd70e3d50f7..00f98c59305 100644 --- a/public/emails/new_user_invite.html +++ b/public/emails/new_user_invite.html @@ -3,7 +3,7 @@ - {{ Subject .Subject "{{ .InvitedBy }} has invited you to join Grafana" }} + {{ Subject .Subject .TemplateData "{{ .InvitedBy }} has invited you to join Grafana" }} diff --git a/public/emails/new_user_invite.txt b/public/emails/new_user_invite.txt index 2cc475a1052..ba52605d432 100644 --- a/public/emails/new_user_invite.txt +++ b/public/emails/new_user_invite.txt @@ -1,4 +1,4 @@ -{{Subject .Subject "{{.InvitedBy}} has invited you to join Grafana"}} +{{HiddenSubject .Subject "{{.InvitedBy}} has invited you to join Grafana"}} You're invited to join {{.OrgName}} diff --git a/public/emails/ng_alert_notification.html b/public/emails/ng_alert_notification.html index d4858b482f9..91b5b7a0131 100644 --- a/public/emails/ng_alert_notification.html +++ b/public/emails/ng_alert_notification.html @@ -3,7 +3,7 @@ - {{ Subject .Subject "{{ .Title }}" }} + {{ Subject .Subject .TemplateData "{{ .Title }}" }} @@ -238,8 +238,7 @@
-
- +
{{ range $line := (splitList "\n" .Message) }} {{ $line }}
@@ -469,8 +468,7 @@
-
- +
{{ range $line := (splitList "\n" .Annotations.description) }} {{ $line }}
@@ -532,8 +530,7 @@
-
- +
{{ range $refID, $value := .Values }} {{ $refID }}={{ $value }}  @@ -978,8 +975,7 @@
-
- +
{{ range $line := (splitList "\n" .Annotations.description) }} {{ $line }}
@@ -1041,8 +1037,7 @@
-
- +
{{ range $refID, $value := .Values }} {{ $refID }}={{ $value }}  diff --git a/public/emails/ng_alert_notification.txt b/public/emails/ng_alert_notification.txt index be157396c17..c002c21809a 100644 --- a/public/emails/ng_alert_notification.txt +++ b/public/emails/ng_alert_notification.txt @@ -1,4 +1,4 @@ -{{Subject .Subject "{{.Title}}"}} +{{HiddenSubject .Subject "{{.Title}}"}} {{.Title}} ---------------- diff --git a/public/emails/reset_password.html b/public/emails/reset_password.html index b064b21c180..351b56c8e81 100644 --- a/public/emails/reset_password.html +++ b/public/emails/reset_password.html @@ -3,7 +3,7 @@ - {{ Subject .Subject "Reset your Grafana password - {{.Name}}" }} + {{ Subject .Subject .TemplateData "Reset your Grafana password - {{.Name}}" }} diff --git a/public/emails/reset_password.txt b/public/emails/reset_password.txt index 0b15365f391..b8bf248c1a5 100644 --- a/public/emails/reset_password.txt +++ b/public/emails/reset_password.txt @@ -1,4 +1,4 @@ -{{Subject .Subject "Reset your Grafana password - {{.Name}}"}} +{{HiddenSubject .Subject "Reset your Grafana password - {{.Name}}"}} Hi {{.Name}}, diff --git a/public/emails/signup_started.html b/public/emails/signup_started.html index 48d4c6236df..a65fcffb719 100644 --- a/public/emails/signup_started.html +++ b/public/emails/signup_started.html @@ -3,7 +3,7 @@ - {{ Subject .Subject "Welcome to Grafana, please complete your sign up!" }} + {{ Subject .Subject .TemplateData "Welcome to Grafana, please complete your sign up!" }} diff --git a/public/emails/signup_started.txt b/public/emails/signup_started.txt index a40e7403ecd..d3ef663dcd5 100644 --- a/public/emails/signup_started.txt +++ b/public/emails/signup_started.txt @@ -1,4 +1,4 @@ -{{Subject .Subject "Welcome to Grafana, please complete your sign up!"}} +{{HiddenSubject .Subject "Welcome to Grafana, please complete your sign up!"}} Complete the signup diff --git a/public/emails/welcome_on_signup.html b/public/emails/welcome_on_signup.html index a532fc8a58a..3957a2b3702 100644 --- a/public/emails/welcome_on_signup.html +++ b/public/emails/welcome_on_signup.html @@ -3,7 +3,7 @@ - {{ Subject .Subject "Welcome to Grafana" }} + {{ Subject .Subject .TemplateData "Welcome to Grafana" }} diff --git a/public/emails/welcome_on_signup.txt b/public/emails/welcome_on_signup.txt index 4608fa9e82e..7cb76f788dd 100644 --- a/public/emails/welcome_on_signup.txt +++ b/public/emails/welcome_on_signup.txt @@ -1,4 +1,4 @@ -{{Subject .Subject "Welcome to Grafana"}} +{{HiddenSubject .Subject "Welcome to Grafana"}} Hi {{.Name}},