diff --git a/README.md b/README.md
index bd474df..39d9fb8 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,5 @@ A temporary email service
## TODO
- Do not store the raw mail data in the DB, maybe use block storage (the provider can be a disk provider at first)
- - Use `bluemonday` to sanitize the mail html before rendering
- Cache subject parsed from email. Then when listing the email it is not necessary to parse all mails and retrieve them.
- Cache in general?
diff --git a/go.mod b/go.mod
index e5ebe38..8a091d7 100644
--- a/go.mod
+++ b/go.mod
@@ -10,7 +10,7 @@ require (
github.com/go-chi/chi v1.5.5 // indirect
github.com/gorilla/css v1.0.1 // indirect
github.com/mattn/go-sqlite3 v1.14.22 // indirect
- github.com/microcosm-cc/bluemonday v1.0.26 // indirect
+ github.com/microcosm-cc/bluemonday v1.0.27 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
- golang.org/x/net v0.22.0 // indirect
+ golang.org/x/net v0.26.0 // indirect
)
diff --git a/go.sum b/go.sum
index e801284..a844e4e 100644
--- a/go.sum
+++ b/go.sum
@@ -16,7 +16,11 @@ github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58=
github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs=
+github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=
+github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
+golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
+golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
diff --git a/pkg/web_server/mail.templ b/pkg/web_server/mail.templ
index 106eb52..fe3f2bb 100644
--- a/pkg/web_server/mail.templ
+++ b/pkg/web_server/mail.templ
@@ -2,10 +2,11 @@ package web_server
import (
"github.com/russross/blackfriday/v2"
+ "github.com/microcosm-cc/bluemonday"
"github.com/GRFreire/nthmail/pkg/mail_utils"
)
-templ mail_body_comp(rcpt_addr string, m mail_utils.Mail_obj) {
+templ mail_body_comp(rcpt_addr string, m mail_utils.Mail_obj, policy *bluemonday.Policy) {
@@ -32,16 +33,16 @@ templ mail_body_comp(rcpt_addr string, m mail_utils.Mail_obj) {
- @mime_type(m.Body[m.PreferedBodyIndex])
+ @mime_type(m.Body[m.PreferedBodyIndex], policy)
}
-templ mime_type(b mail_utils.Mail_body) {
+templ mime_type(b mail_utils.Mail_body, policy *bluemonday.Policy) {
switch b.MimeType {
case mail_utils.Html:
- @body_html(b.Data)
+ @body_html(b.Data, policy)
case mail_utils.Markdown:
@body_markdown(b.Data)
case mail_utils.PlainText:
@@ -59,9 +60,9 @@ templ body_plain(s string) {
}
-templ body_html(s string) {
+templ body_html(s string, policy *bluemonday.Policy) {
- @templ.Raw(s)
+ @templ.Raw(policy.Sanitize(s))
}
diff --git a/pkg/web_server/main.go b/pkg/web_server/main.go
index 6058f37..34532bb 100644
--- a/pkg/web_server/main.go
+++ b/pkg/web_server/main.go
@@ -14,11 +14,15 @@ import (
"github.com/GRFreire/nthmail/pkg/rig"
"github.com/go-chi/chi"
_ "github.com/mattn/go-sqlite3"
+ "github.com/microcosm-cc/bluemonday"
)
func Start(db *sql.DB) error {
server := &ServerResouces{}
- server.db = db
+ server.db = db
+
+ server.policy = bluemonday.UGCPolicy()
+ server.policy.AllowAttrs("style").Globally()
domain, exists := os.LookupEnv("MAIL_SERVER_DOMAIN")
if !exists {
@@ -27,7 +31,7 @@ func Start(db *sql.DB) error {
server.domain = domain
var port int
- var err error
+ var err error
port_str, exists := os.LookupEnv("WEB_SERVER_PORT")
if exists {
port, err = strconv.Atoi(port_str)
@@ -46,11 +50,12 @@ func Start(db *sql.DB) error {
return err
}
- return nil
+ return nil
}
type ServerResouces struct {
db *sql.DB
+ policy *bluemonday.Policy
domain string
}
@@ -98,7 +103,7 @@ func (sr ServerResouces) handleInbox(res http.ResponseWriter, req *http.Request)
log.Println("could not begin db transaction")
return
}
- defer tx.Commit()
+ defer tx.Commit()
stmt, err := tx.Prepare("SELECT mails.id, mails.arrived_at, mails.rcpt_addr, mails.from_addr, mails.data FROM mails WHERE mails.rcpt_addr = ?")
if err != nil {
@@ -133,7 +138,7 @@ func (sr ServerResouces) handleInbox(res http.ResponseWriter, req *http.Request)
}
mail_obj, err := mail_utils.Parse_mail(m.Data, true)
- mail_obj.Date = time.Unix(m.Arrived_at, 0)
+ mail_obj.Date = time.Unix(m.Arrived_at, 0)
mail_obj.Id = m.Id
if err != nil {
res.WriteHeader(500)
@@ -174,7 +179,7 @@ func (sr ServerResouces) handleMail(res http.ResponseWriter, req *http.Request)
log.Println("could not begin db transaction")
return
}
- defer tx.Commit()
+ defer tx.Commit()
stmt, err := tx.Prepare("SELECT mails.id, mails.arrived_at, mails.rcpt_addr, mails.from_addr, mails.data FROM mails WHERE mails.rcpt_addr = ? AND mails.id = ?")
if err != nil {
@@ -200,7 +205,7 @@ func (sr ServerResouces) handleMail(res http.ResponseWriter, req *http.Request)
}
mail_obj, err := mail_utils.Parse_mail(m.Data, false)
- mail_obj.Date = time.Unix(m.Arrived_at, 0)
+ mail_obj.Date = time.Unix(m.Arrived_at, 0)
mail_obj.Id = m.Id
if err != nil {
res.WriteHeader(500)
@@ -213,6 +218,6 @@ func (sr ServerResouces) handleMail(res http.ResponseWriter, req *http.Request)
mail_obj = mail_utils.Set_format_index(mail_obj, format, f_pref)
- body := mail_body_comp(rcpt_addr, mail_obj)
+ body := mail_body_comp(rcpt_addr, mail_obj, sr.policy)
body.Render(req.Context(), res)
}