aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/base/handlers.go8
-rw-r--r--plugins/base/public/compose.html9
-rw-r--r--plugins/base/smtp.go49
3 files changed, 57 insertions, 9 deletions
diff --git a/plugins/base/handlers.go b/plugins/base/handlers.go
index 133052c..e939cc5 100644
--- a/plugins/base/handlers.go
+++ b/plugins/base/handlers.go
@@ -270,7 +270,13 @@ func handleCompose(ectx echo.Context) error {
msg.Text = ctx.FormValue("text")
msg.InReplyTo = ctx.FormValue("in_reply_to")
- err := ctx.Session.DoSMTP(func(c *smtp.Client) error {
+ form, err := ctx.MultipartForm()
+ if err != nil {
+ return fmt.Errorf("failed to get multipart form: %v", err)
+ }
+ msg.Attachments = form.File["attachments"]
+
+ err = ctx.Session.DoSMTP(func(c *smtp.Client) error {
return sendMessage(c, &msg)
})
if err != nil {
diff --git a/plugins/base/public/compose.html b/plugins/base/public/compose.html
index 5f0b904..0e16acf 100644
--- a/plugins/base/public/compose.html
+++ b/plugins/base/public/compose.html
@@ -8,14 +8,14 @@
<h2>Compose new message</h2>
-<form method="post" action="">
+<form method="post" action="" enctype="multipart/form-data">
<input type="hidden" name="in_reply_to" value="{{.Message.InReplyTo}}">
<label for="from">From:</label>
- <input type="email" name="from" id="from" value="{{.Message.From}}">
+ <input type="email" name="from" id="from" required value="{{.Message.From}}">
<br><br>
<label for="to">To:</label>
- <input type="email" name="to" id="to" multiple value="{{.Message.ToString}}">
+ <input type="email" name="to" id="to" multiple required value="{{.Message.ToString}}">
<br><br>
<label for="subject">Subject:</label>
<input type="text" name="subject" id="subject" value="{{.Message.Subject}}">
@@ -23,6 +23,9 @@
<label for="text">Body:</label><br>
<textarea name="text" id="text" cols="80" rows="20">{{.Message.Text}}</textarea>
<br><br>
+ <label for="attachments">Attachments:</label>
+ <input type="file" name="attachments" id="attachments" multiple>
+ <br><br>
<input type="submit" value="Send">
</form>
diff --git a/plugins/base/smtp.go b/plugins/base/smtp.go
index 9ade78f..81da6ef 100644
--- a/plugins/base/smtp.go
+++ b/plugins/base/smtp.go
@@ -4,6 +4,7 @@ import (
"bufio"
"fmt"
"io"
+ "mime/multipart"
"strings"
"time"
@@ -26,17 +27,49 @@ func quote(r io.Reader) (string, error) {
}
type OutgoingMessage struct {
- From string
- To []string
- Subject string
- InReplyTo string
- Text string
+ From string
+ To []string
+ Subject string
+ InReplyTo string
+ Text string
+ Attachments []*multipart.FileHeader
}
func (msg *OutgoingMessage) ToString() string {
return strings.Join(msg.To, ", ")
}
+func writeAttachment(mw *mail.Writer, att *multipart.FileHeader) error {
+ var h mail.AttachmentHeader
+ h.Set("Content-Type", att.Header.Get("Content-Type"))
+ h.SetFilename(att.Filename)
+
+ aw, err := mw.CreateAttachment(h)
+ if err != nil {
+ return fmt.Errorf("failed to create attachment: %v", err)
+ }
+ defer aw.Close()
+
+ f, err := att.Open()
+ if err != nil {
+ return fmt.Errorf("failed to open attachment: %v", err)
+ }
+ defer f.Close()
+
+ if _, err := io.Copy(aw, f); err != nil {
+ return fmt.Errorf("failed to write attachment: %v", err)
+ }
+
+ if err := f.Close(); err != nil {
+ return fmt.Errorf("failed to close attachment: %v", err)
+ }
+ if err := aw.Close(); err != nil {
+ return fmt.Errorf("failed to close attachment writer: %v", err)
+ }
+
+ return nil
+}
+
func (msg *OutgoingMessage) WriteTo(w io.Writer) error {
from := []*mail.Address{{"", msg.From}}
@@ -78,6 +111,12 @@ func (msg *OutgoingMessage) WriteTo(w io.Writer) error {
return fmt.Errorf("failed to close text part: %v", err)
}
+ for _, att := range msg.Attachments {
+ if err := writeAttachment(mw, att); err != nil {
+ return err
+ }
+ }
+
if err := mw.Close(); err != nil {
return fmt.Errorf("failed to close mail writer: %v", err)
}