aboutsummaryrefslogtreecommitdiff
path: root/server.go
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2019-12-03 18:41:23 +0100
committerSimon Ser <contact@emersion.fr>2019-12-03 18:41:23 +0100
commita103309935c4a2c72770343542493d1c285d94dd (patch)
tree8d030950cf75f4b10f1cc657b56a0079b027b7b5 /server.go
parentb386d1c2bb0efacea2484b4aa2088c769e048a9c (diff)
downloadalps-a103309935c4a2c72770343542493d1c285d94dd.tar.gz
alps-a103309935c4a2c72770343542493d1c285d94dd.zip
Add support for replying to a message
Diffstat (limited to 'server.go')
-rw-r--r--server.go64
1 files changed, 59 insertions, 5 deletions
diff --git a/server.go b/server.go
index 1de4eae..af84d4f 100644
--- a/server.go
+++ b/server.go
@@ -142,11 +142,7 @@ func handleLogin(ectx echo.Context) error {
}
func handleGetPart(ctx *context, raw bool) error {
- mboxName, err := url.PathUnescape(ctx.Param("mbox"))
- if err != nil {
- return echo.NewHTTPError(http.StatusBadRequest, err)
- }
- uid, err := parseUid(ctx.Param("uid"))
+ mboxName, uid, err := parseMboxAndUid(ctx.Param("mbox"), ctx.Param("uid"))
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err)
}
@@ -219,6 +215,61 @@ func handleCompose(ectx echo.Context) error {
msg.From = ctx.session.username
}
+ if ctx.Request().Method == http.MethodGet && ctx.Param("uid") != "" {
+ // This is a reply
+ mboxName, uid, err := parseMboxAndUid(ctx.Param("mbox"), ctx.Param("uid"))
+ if err != nil {
+ return echo.NewHTTPError(http.StatusBadRequest, err)
+ }
+ partPath, err := parsePartPath(ctx.QueryParam("part"))
+ if err != nil {
+ return echo.NewHTTPError(http.StatusBadRequest, err)
+ }
+
+ var inReplyTo *imapMessage
+ var part *message.Entity
+ err = ctx.session.Do(func(c *imapclient.Client) error {
+ var err error
+ inReplyTo, part, err = getMessagePart(c, mboxName, uid, partPath)
+ return err
+ })
+ if err != nil {
+ return err
+ }
+
+ mimeType, _, err := part.Header.ContentType()
+ if err != nil {
+ return fmt.Errorf("failed to parse part Content-Type: %v", err)
+ }
+
+ if !strings.HasPrefix(strings.ToLower(mimeType), "text/") {
+ err := fmt.Errorf("cannot reply to \"%v\" part", mimeType)
+ return echo.NewHTTPError(http.StatusBadRequest, err)
+ }
+
+ msg.Text, err = quote(part.Body)
+ if err != nil {
+ return err
+ }
+
+ msg.InReplyTo = inReplyTo.Envelope.MessageId
+ // TODO: populate From from known user addresses and inReplyTo.Envelope.To
+ replyTo := inReplyTo.Envelope.ReplyTo
+ if len(replyTo) == 0 {
+ replyTo = inReplyTo.Envelope.From
+ }
+ if len(replyTo) > 0 {
+ msg.To = make([]string, len(replyTo))
+ for i, to := range replyTo {
+ msg.To[i] = to.MailboxName + "@" + to.HostName
+ }
+ }
+ msg.Subject = inReplyTo.Envelope.Subject
+ if !strings.HasPrefix(strings.ToLower(msg.Subject), "re:") {
+ msg.Subject = "Re: " + msg.Subject
+ }
+ }
+
if ctx.Request().Method == http.MethodPost {
// TODO: parse address lists
from := ctx.FormValue("from")
@@ -374,6 +425,9 @@ func New(imapURL, smtpURL string) *echo.Echo {
e.GET("/compose", handleCompose)
e.POST("/compose", handleCompose)
+ e.GET("/message/:mbox/:uid/reply", handleCompose)
+ e.POST("/message/:mbox/:uid/reply", handleCompose)
+
e.Static("/assets", "public/assets")
return e