diff --git a/go.mod b/go.mod index 2f90961b7..038fde270 100644 --- a/go.mod +++ b/go.mod @@ -87,4 +87,4 @@ replace ( gopkg.in/fsnotify.v1 => github.com/kolaente/fsnotify v1.4.10-0.20200411160148-1bc3c8ff4048 // See https://github.com/fsnotify/fsnotify/issues/328 and https://github.com/golang/go/issues/26904 ) -go 1.15 +go 1.16 diff --git a/pkg/mail/send_mail.go b/pkg/mail/send_mail.go index 7324110a6..a693e798e 100644 --- a/pkg/mail/send_mail.go +++ b/pkg/mail/send_mail.go @@ -20,6 +20,7 @@ import ( "code.vikunja.io/api/pkg/config" "code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/version" + "io" "github.com/wneessen/go-mail" ) @@ -34,6 +35,7 @@ type Opts struct { ContentType ContentType Boundary string Headers []*header + Embeds map[string]io.Reader } // ContentType represents mail content types @@ -78,10 +80,15 @@ func getMessage(opts *Opts) *mail.Msg { _ = m.From(opts.From) _ = m.To(opts.To) m.Subject(opts.Subject) + for _, h := range opts.Headers { m.SetHeader(h.Field, h.Content) } + for name, content := range opts.Embeds { + m.EmbedReader(name, content) + } + switch opts.ContentType { case ContentTypePlain: m.SetBodyString("text/plain", opts.Message) diff --git a/pkg/modules/migration/trello/trello.go b/pkg/modules/migration/trello/trello.go index c443d3c6c..81be17586 100644 --- a/pkg/modules/migration/trello/trello.go +++ b/pkg/modules/migration/trello/trello.go @@ -242,12 +242,12 @@ func convertTrelloDataToVikunja(trelloData []*trello.Board, token string) (fullV log.Debugf("[Trello Migration] Converted label %s from card %s", label.ID, card.ID) } - // Attachments + // Embeds if len(card.Attachments) > 0 { log.Debugf("[Trello Migration] Downloading %d card attachments from card %s", len(card.Attachments), card.ID) } for _, attachment := range card.Attachments { - if attachment.MimeType == "" { // Attachments can also be not downloadable - the mime type is empty in that case. + if attachment.MimeType == "" { // Embeds can also be not downloadable - the mime type is empty in that case. log.Debugf("[Trello Migration] Attachment %s does not have a mime type, not downloading", attachment.ID) continue } diff --git a/pkg/modules/migration/wunderlist/wunderlist.go b/pkg/modules/migration/wunderlist/wunderlist.go index fea6722e0..7a1a9d16b 100644 --- a/pkg/modules/migration/wunderlist/wunderlist.go +++ b/pkg/modules/migration/wunderlist/wunderlist.go @@ -181,7 +181,7 @@ func convertListForFolder(listID int, list *list, content *wunderlistContents) ( } } - // Attachments + // Embeds for _, f := range content.files { if f.TaskID == t.ID { // Download the attachment and put it in the file diff --git a/pkg/notifications/logo.png b/pkg/notifications/logo.png new file mode 100644 index 000000000..0b62ea0b4 Binary files /dev/null and b/pkg/notifications/logo.png differ diff --git a/pkg/notifications/mail_render.go b/pkg/notifications/mail_render.go index 0ab72442b..997a916aa 100644 --- a/pkg/notifications/mail_render.go +++ b/pkg/notifications/mail_render.go @@ -18,7 +18,9 @@ package notifications import ( "bytes" + _ "embed" templatehtml "html/template" + "io" templatetext "text/template" "code.vikunja.io/api/pkg/config" @@ -49,7 +51,7 @@ const mailTemplateHTML = `

- Vikunja + Vikunja

@@ -84,6 +86,9 @@ const mailTemplateHTML = ` ` +//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) { @@ -155,6 +160,9 @@ func RenderMail(m *Mail) (mailOpts *mail.Opts, err error) { Message: plainContent.String(), HTMLMessage: htmlContent.String(), Boundary: boundary, + Embeds: map[string]io.Reader{ + "logo.png": bytes.NewBuffer(logo), + }, } return mailOpts, nil diff --git a/pkg/routes/api/v1/task_attachment.go b/pkg/routes/api/v1/task_attachment.go index d74357b43..982be34cb 100644 --- a/pkg/routes/api/v1/task_attachment.go +++ b/pkg/routes/api/v1/task_attachment.go @@ -36,7 +36,7 @@ import ( // @Param id path int true "Task ID" // @Param files formData string true "The file, as multipart form file. You can pass multiple." // @Security JWTKeyAuth -// @Success 200 {object} models.Message "Attachments were uploaded successfully." +// @Success 200 {object} models.Message "Embeds were uploaded successfully." // @Failure 403 {object} models.Message "No access to the task." // @Failure 404 {object} models.Message "The task does not exist." // @Failure 500 {object} models.Message "Internal error" diff --git a/pkg/swagger/docs.go b/pkg/swagger/docs.go index d7a0e6b32..d8237b495 100644 --- a/pkg/swagger/docs.go +++ b/pkg/swagger/docs.go @@ -4791,7 +4791,7 @@ const docTemplate = `{ ], "responses": { "200": { - "description": "Attachments were uploaded successfully.", + "description": "Embeds were uploaded successfully.", "schema": { "$ref": "#/definitions/models.Message" }