@@ -10,13 +10,13 @@ | |||
<form method="post" action="/compose"> | |||
<p>From:</p> | |||
<input type="text" name="from"> | |||
<input type="email" name="from" value="{{.Message.From}}"> | |||
<p>To:</p> | |||
<input type="text" name="to"> | |||
<input type="email" name="to" multiple> | |||
<p>Subject:</p> | |||
<input type="text" name="subject"> | |||
<input type="text" name="subject" value="{{.Message.Subject}}"> | |||
<p>Body:</p> | |||
<textarea name="text" cols="80" rows="20"></textarea> | |||
<textarea name="text" cols="80" rows="20">{{.Message.Text}}</textarea> | |||
<br><br> | |||
<input type="submit" value="Send"> | |||
</form> | |||
@@ -202,6 +202,11 @@ func handleGetPart(ctx *context, raw bool) error { | |||
func handleCompose(ectx echo.Context) error { | |||
ctx := ectx.(*context) | |||
var msg OutgoingMessage | |||
if strings.ContainsRune(ctx.session.username, '@') { | |||
msg.From = ctx.session.username | |||
} | |||
if ctx.Request().Method == http.MethodPost { | |||
// TODO: parse address lists | |||
from := ctx.FormValue("from") | |||
@@ -220,12 +225,11 @@ func handleCompose(ectx echo.Context) error { | |||
return echo.NewHTTPError(http.StatusForbidden, err) | |||
} | |||
msg := OutgoingMessage{ | |||
from: from, | |||
to: []string{to}, | |||
subject: subject, | |||
text: text, | |||
} | |||
msg.From = from | |||
msg.To = []string{to} | |||
msg.Subject = subject | |||
msg.Text = text | |||
if err := sendMessage(c, &msg); err != nil { | |||
return err | |||
} | |||
@@ -239,7 +243,9 @@ func handleCompose(ectx echo.Context) error { | |||
return ctx.Redirect(http.StatusFound, "/mailbox/INBOX") | |||
} | |||
return ctx.Render(http.StatusOK, "compose.html", nil) | |||
return ctx.Render(http.StatusOK, "compose.html", map[string]interface{}{ | |||
"Message": &msg, | |||
}) | |||
} | |||
func New(imapURL, smtpURL string) *echo.Echo { | |||
@@ -34,17 +34,17 @@ func (s *Server) connectSMTP() (*smtp.Client, error) { | |||
} | |||
type OutgoingMessage struct { | |||
from string | |||
to []string | |||
subject string | |||
text string | |||
From string | |||
To []string | |||
Subject string | |||
Text string | |||
} | |||
func (msg *OutgoingMessage) WriteTo(w io.Writer) error { | |||
from := []*mail.Address{{"", msg.from}} | |||
from := []*mail.Address{{"", msg.From}} | |||
to := make([]*mail.Address, len(msg.to)) | |||
for i, addr := range msg.to { | |||
to := make([]*mail.Address, len(msg.To)) | |||
for i, addr := range msg.To { | |||
to[i] = &mail.Address{"", addr} | |||
} | |||
@@ -52,7 +52,9 @@ func (msg *OutgoingMessage) WriteTo(w io.Writer) error { | |||
h.SetDate(time.Now()) | |||
h.SetAddressList("From", from) | |||
h.SetAddressList("To", to) | |||
h.SetText("Subject", msg.subject) | |||
if msg.Subject != "" { | |||
h.SetText("Subject", msg.Subject) | |||
} | |||
mw, err := mail.CreateWriter(w, h) | |||
if err != nil { | |||
@@ -68,7 +70,7 @@ func (msg *OutgoingMessage) WriteTo(w io.Writer) error { | |||
} | |||
defer tw.Close() | |||
if _, err := io.WriteString(tw, msg.text); err != nil { | |||
if _, err := io.WriteString(tw, msg.Text); err != nil { | |||
return fmt.Errorf("failed to write text part: %v", err) | |||
} | |||
@@ -84,11 +86,11 @@ func (msg *OutgoingMessage) WriteTo(w io.Writer) error { | |||
} | |||
func sendMessage(c *smtp.Client, msg *OutgoingMessage) error { | |||
if err := c.Mail(msg.from, nil); err != nil { | |||
if err := c.Mail(msg.From, nil); err != nil { | |||
return fmt.Errorf("MAIL FROM failed: %v", err) | |||
} | |||
for _, to := range msg.to { | |||
for _, to := range msg.To { | |||
if err := c.Rcpt(to); err != nil { | |||
return fmt.Errorf("RCPT TO failed: %v", err) | |||
} | |||