// Vikunja is a to-do list application to facilitate your life. // Copyright 2018-2021 Vikunja and contributors. All rights reserved. // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public Licensee as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public Licensee for more details. // // You should have received a copy of the GNU Affero General Public Licensee // along with this program. If not, see . package notifications import ( "bytes" _ "embed" templatehtml "html/template" "io" templatetext "text/template" "code.vikunja.io/api/pkg/config" "code.vikunja.io/api/pkg/mail" "code.vikunja.io/api/pkg/utils" "github.com/yuin/goldmark" ) const mailTemplatePlain = ` {{ .Greeting }} {{ range $line := .IntroLines}} {{ $line }} {{ end }} {{ if .ActionURL }}{{ .ActionText }}: {{ .ActionURL }}{{end}} {{ range $line := .OutroLines}} {{ $line }} {{ end }}` const mailTemplateHTML = `

Vikunja

{{ .Greeting }}

{{ range $line := .IntroLinesHTML}} {{ $line }} {{ end }} {{ if .ActionURL }} {{ .ActionText }} {{end}} {{ range $line := .OutroLinesHTML}} {{ $line }} {{ end }} {{ if .ActionURL }}

If the button above doesn't work, copy the url below and paste it in your browsers address bar:
{{ .ActionURL }}

{{ end }}
` //go:embed logo.png var logo []byte // RenderMail takes a precomposed mail message and renders it into a ready to send mail.Opts object func RenderMail(m *Mail) (mailOpts *mail.Opts, err error) { var htmlContent bytes.Buffer var plainContent bytes.Buffer plain, err := templatetext.New("mail-plain").Parse(mailTemplatePlain) if err != nil { return nil, err } html, err := templatehtml.New("mail-plain").Parse(mailTemplateHTML) if err != nil { return nil, err } boundary := "np" + utils.MakeRandomString(13) data := make(map[string]interface{}) data["Greeting"] = m.greeting data["IntroLines"] = m.introLines data["OutroLines"] = m.outroLines data["ActionText"] = m.actionText data["ActionURL"] = m.actionURL data["Boundary"] = boundary data["FrontendURL"] = config.ServiceFrontendurl.GetString() var introLinesHTML []templatehtml.HTML for _, line := range m.introLines { md := []byte(templatehtml.HTMLEscapeString(line)) var buf bytes.Buffer err = goldmark.Convert(md, &buf) if err != nil { return nil, err } //#nosec - the html is escaped few lines before introLinesHTML = append(introLinesHTML, templatehtml.HTML(buf.String())) } data["IntroLinesHTML"] = introLinesHTML var outroLinesHTML []templatehtml.HTML for _, line := range m.outroLines { md := []byte(templatehtml.HTMLEscapeString(line)) var buf bytes.Buffer err = goldmark.Convert(md, &buf) if err != nil { return nil, err } //#nosec - the html is escaped few lines before outroLinesHTML = append(outroLinesHTML, templatehtml.HTML(buf.String())) } data["OutroLinesHTML"] = outroLinesHTML err = plain.Execute(&plainContent, data) if err != nil { return nil, err } err = html.Execute(&htmlContent, data) if err != nil { return nil, err } mailOpts = &mail.Opts{ From: m.from, To: m.to, Subject: m.subject, ContentType: mail.ContentTypeMultipart, Message: plainContent.String(), HTMLMessage: htmlContent.String(), Boundary: boundary, Embeds: map[string]io.Reader{ "logo.png": bytes.NewBuffer(logo), }, } return mailOpts, nil }