diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/base/public/message.html | 9 | ||||
-rw-r--r-- | plugins/base/routes.go | 48 | ||||
-rw-r--r-- | plugins/base/strconv.go | 12 |
3 files changed, 53 insertions, 16 deletions
diff --git a/plugins/base/public/message.html b/plugins/base/public/message.html index b537ff0..ed2b1a2 100644 --- a/plugins/base/public/message.html +++ b/plugins/base/public/message.html @@ -16,7 +16,8 @@ {{end}} </h2> -<form method="post" action="{{.Message.URL}}/move"> +<form method="post" action="/message/{{.Mailbox.Name | pathescape}}/move"> + <input type="hidden" name="uids" value="{{.Message.Uid}}"> <label for="move-to">Move to:</label> <select name="to" id="move-to"> {{range .Mailboxes}} @@ -26,12 +27,14 @@ <input type="submit" value="Move"> </form> -<form method="post" action="{{.Message.URL}}/delete"> +<form method="post" action="/message/{{.Mailbox.Name | pathescape}}/delete"> + <input type="hidden" name="uids" value="{{.Message.Uid}}"> <input type="submit" value="Delete"> </form> {{if .Flags}} - <form method="post" action="{{.Message.URL}}/flag"> + <form method="post" action="/message/{{.Mailbox.Name | pathescape}}/flag"> + <input type="hidden" name="uids" value="{{.Message.Uid}}"> <p>Flags:</p> {{range $name, $has := .Flags}} {{if ismutableflag $name}} diff --git a/plugins/base/routes.go b/plugins/base/routes.go index 0237634..d2bfe73 100644 --- a/plugins/base/routes.go +++ b/plugins/base/routes.go @@ -53,11 +53,11 @@ func registerRoutes(p *koushin.GoPlugin) { p.GET("/message/:mbox/:uid/edit", handleEdit) p.POST("/message/:mbox/:uid/edit", handleEdit) - p.POST("/message/:mbox/:uid/move", handleMove) + p.POST("/message/:mbox/move", handleMove) - p.POST("/message/:mbox/:uid/delete", handleDelete) + p.POST("/message/:mbox/delete", handleDelete) - p.POST("/message/:mbox/:uid/flag", handleSetFlags) + p.POST("/message/:mbox/flag", handleSetFlags) p.GET("/settings", handleSettings) p.POST("/settings", handleSettings) @@ -654,7 +654,16 @@ func handleEdit(ctx *koushin.Context) error { } func handleMove(ctx *koushin.Context) error { - mboxName, uid, err := parseMboxAndUid(ctx.Param("mbox"), ctx.Param("uid")) + mboxName, err := url.PathUnescape(ctx.Param("mbox")) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, err) + } + + formParams, err := ctx.FormParams() + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, err) + } + uids, err := parseUidList(formParams["uids"]) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, err) } @@ -669,7 +678,7 @@ func handleMove(ctx *koushin.Context) error { } var seqSet imap.SeqSet - seqSet.AddNum(uid) + seqSet.AddNum(uids...) if err := mc.UidMoveWithFallback(&seqSet, to); err != nil { return fmt.Errorf("failed to move message: %v", err) } @@ -685,7 +694,16 @@ func handleMove(ctx *koushin.Context) error { } func handleDelete(ctx *koushin.Context) error { - mboxName, uid, err := parseMboxAndUid(ctx.Param("mbox"), ctx.Param("uid")) + mboxName, err := url.PathUnescape(ctx.Param("mbox")) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, err) + } + + formParams, err := ctx.FormParams() + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, err) + } + uids, err := parseUidList(formParams["uids"]) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, err) } @@ -696,7 +714,7 @@ func handleDelete(ctx *koushin.Context) error { } var seqSet imap.SeqSet - seqSet.AddNum(uid) + seqSet.AddNum(uids...) item := imap.FormatFlagsOp(imap.AddFlags, true) flags := []interface{}{imap.DeletedFlag} @@ -724,16 +742,20 @@ func handleDelete(ctx *koushin.Context) error { } func handleSetFlags(ctx *koushin.Context) error { - mboxName, uid, err := parseMboxAndUid(ctx.Param("mbox"), ctx.Param("uid")) + mboxName, err := url.PathUnescape(ctx.Param("mbox")) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, err) } - form, err := ctx.FormParams() + formParams, err := ctx.FormParams() + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, err) + } + uids, err := parseUidList(formParams["uids"]) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, err) } - flags, ok := form["flags"] + flags, ok := formParams["flags"] if !ok { return echo.NewHTTPError(http.StatusBadRequest, "missing 'flags' form values") } @@ -756,7 +778,7 @@ func handleSetFlags(ctx *koushin.Context) error { } var seqSet imap.SeqSet - seqSet.AddNum(uid) + seqSet.AddNum(uids...) storeItems := make([]interface{}, len(flags)) for i, f := range flags { @@ -774,11 +796,11 @@ func handleSetFlags(ctx *koushin.Context) error { return err } - if op == imap.RemoveFlags && len(flags) == 1 && flags[0] == "\\Seen" { + if len(uids) != 1 || (op == imap.RemoveFlags && len(flags) == 1 && flags[0] == "\\Seen") { // Redirecting to the message view would mark the message as read again return ctx.Redirect(http.StatusFound, fmt.Sprintf("/mailbox/%v", url.PathEscape(mboxName))) } - return ctx.Redirect(http.StatusFound, fmt.Sprintf("/message/%v/%v", url.PathEscape(mboxName), uid)) + return ctx.Redirect(http.StatusFound, fmt.Sprintf("/message/%v/%v", url.PathEscape(mboxName), uids[0])) } const settingsKey = "base.settings" diff --git a/plugins/base/strconv.go b/plugins/base/strconv.go index 1a32e75..9efa4cd 100644 --- a/plugins/base/strconv.go +++ b/plugins/base/strconv.go @@ -27,6 +27,18 @@ func parseMboxAndUid(mboxString, uidString string) (string, uint32, error) { return mboxName, uid, err } +func parseUidList(values []string) ([]uint32, error) { + var uids []uint32 + for _, v := range values { + uid, err := parseUid(v) + if err != nil { + return nil, err + } + uids = append(uids, uid) + } + return uids, nil +} + func parsePartPath(s string) ([]int, error) { if s == "" { return nil, nil |