Skip to content
This repository was archived by the owner on Jul 12, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

Click the link below to verify your email address for {{.RealmName}} on the COVID-19 exposure notifications verification server:

{{safeHTML .VerifyLink}}
{{.VerifyLink}}

If you did not request verification of this email, please disregard this message.
{{end}}
2 changes: 1 addition & 1 deletion pkg/render/email.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (r *Renderer) RenderEmail(tmpl string, data interface{}) ([]byte, error) {
defer r.rendererPool.Put(b)

// Render into the renderer
if err := r.templates.ExecuteTemplate(b, tmpl, data); err != nil {
if err := r.textTemplates.ExecuteTemplate(b, tmpl, data); err != nil {
return nil, fmt.Errorf("error executing email template %v", err)
}
return b.Bytes(), nil
Expand Down
34 changes: 21 additions & 13 deletions pkg/render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,20 @@ import (
"bytes"
"context"
"fmt"
"html/template"
htmltemplate "html/template"
"os"
"path/filepath"
"strings"
"sync"
texttemplate "text/template"

"github.com/google/exposure-notifications-server/pkg/logging"

"go.uber.org/zap"
)

// allowedResponseCodes are the list of allowed response codes. This is
// primarily here to catch if someone, in the future, accidentially includes a
// primarily here to catch if someone, in the future, accidentally includes a
// bad status code.
var allowedResponseCodes = map[int]struct{}{
200: {},
Expand Down Expand Up @@ -62,7 +63,8 @@ type Renderer struct {
// templates is the actually collection of templates. templatesLoader is a
// function for (re)loading templates. templatesLock is a mutex to prevent
// concurrent modification of the templates field.
templates *template.Template
templates *htmltemplate.Template
textTemplates *texttemplate.Template
templatesRoot string
}

Expand Down Expand Up @@ -95,18 +97,20 @@ func (r *Renderer) loadTemplates() error {
return nil
}

tmpl := template.New("").
tmpl := htmltemplate.New("").
Option("missingkey=zero").
Funcs(templateFuncs())
if err := loadTemplates(tmpl, r.templatesRoot); err != nil {
txttmpl := texttemplate.New("")
if err := loadTemplates(tmpl, txttmpl, r.templatesRoot); err != nil {
return fmt.Errorf("failed to load templates: %w", err)
}

r.templates = tmpl
r.textTemplates = txttmpl
return nil
}

func loadTemplates(tmpl *template.Template, root string) error {
func loadTemplates(tmpl *htmltemplate.Template, txttmpl *texttemplate.Template, root string) error {
return filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
Expand All @@ -116,24 +120,28 @@ func loadTemplates(tmpl *template.Template, root string) error {
return nil
}

if !strings.HasSuffix(info.Name(), ".html") {
return nil
if strings.HasSuffix(info.Name(), ".html") {
if _, err := tmpl.ParseFiles(path); err != nil {
return fmt.Errorf("failed to parse %s: %w", path, err)
}
}

if _, err := tmpl.ParseFiles(path); err != nil {
return fmt.Errorf("failed to parse %s: %w", path, err)
if strings.HasSuffix(info.Name(), ".txt") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clever

if _, err := txttmpl.ParseFiles(path); err != nil {
return fmt.Errorf("failed to parse %s: %w", path, err)
}
}

return nil
})
}

// safeHTML un-escapes known safe html.
func safeHTML(s string) template.HTML {
return template.HTML(s)
func safeHTML(s string) htmltemplate.HTML {
return htmltemplate.HTML(s)
}

func templateFuncs() template.FuncMap {
func templateFuncs() htmltemplate.FuncMap {
return map[string]interface{}{
"joinStrings": strings.Join,
"trimSpace": strings.TrimSpace,
Expand Down