Skip to content

Commit

Permalink
feat(GODT-2576): Forward flag support
Browse files Browse the repository at this point in the history
Add routes to mark messages as forwarded.
  • Loading branch information
LBeernaertProton committed Nov 14, 2023
1 parent fb55d3b commit 7451b85
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 3 deletions.
56 changes: 56 additions & 0 deletions message.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,62 @@ func (c *Client) MarkMessagesRead(ctx context.Context, messageIDs ...string) err
return nil
}

func (c *Client) MarkMessagesForwarded(ctx context.Context, messageIDs ...string) error {
type subResponse struct {
Response APIError
ID string
}

var response struct {
Code int
Responses []subResponse
}

for _, page := range xslices.Chunk(messageIDs, maxPageSize) {
if err := c.do(ctx, func(r *resty.Request) (*resty.Response, error) {
return r.SetBody(MessageActionReq{IDs: page}).SetResult(&response).Put("/mail/v4/messages/forward")
}); err != nil {
return err
}

for _, r := range response.Responses {
if r.Response.Code != SuccessCode {
return fmt.Errorf("failed to mark message %v as forwarded", r.ID)
}
}
}

return nil
}

func (c *Client) MarkMessagesUnForwarded(ctx context.Context, messageIDs ...string) error {
type subResponse struct {
Response APIError
ID string
}

var response struct {
Code int
Responses []subResponse
}

for _, page := range xslices.Chunk(messageIDs, maxPageSize) {
if err := c.do(ctx, func(r *resty.Request) (*resty.Response, error) {
return r.SetBody(MessageActionReq{IDs: page}).SetResult(&response).Put("/mail/v4/messages/unforward")
}); err != nil {
return err
}

for _, r := range response.Responses {
if r.Response.Code != SuccessCode {
return fmt.Errorf("failed to unmark message %v as forwarded", r.ID)
}
}
}

return nil
}

func (c *Client) MarkMessagesUnread(ctx context.Context, messageIDs ...string) error {
for _, page := range xslices.Chunk(messageIDs, maxPageSize) {
req := MessageActionReq{IDs: page}
Expand Down
24 changes: 24 additions & 0 deletions server/backend/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,30 @@ func (b *Backend) SetMessagesRead(userID string, read bool, messageIDs ...string
})
})
}

func (b *Backend) SetMessagesForwarded(userID string, forwarded bool, messageIDs ...string) error {
return b.withAcc(userID, func(acc *account) error {
return b.withMessages(func(messages map[string]*message) error {
for _, messageID := range messageIDs {
if forwarded {
messages[messageID].flags |= proton.MessageFlagForwarded
} else {
messages[messageID].flags &= ^proton.MessageFlagForwarded
}

updateID, err := b.newUpdate(&messageUpdated{messageID: messageID})
if err != nil {
return err
}

acc.updateIDs = append(acc.updateIDs, updateID)
}

return nil
})
})
}

func (b *Backend) LabelMessages(userID, labelID string, messageIDs ...string) error {
return b.labelMessages(userID, labelID, true, messageIDs...)
}
Expand Down
5 changes: 3 additions & 2 deletions server/backend/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,9 @@ func (msg *message) toMetadata(attData map[string][]byte, att map[string]*attach
ReplyTos: msg.replytos,
Size: messageSize,

Flags: msg.flags,
Unread: proton.Bool(msg.unread),
Flags: msg.flags,
Unread: proton.Bool(msg.unread),
IsForwarded: msg.flags&proton.MessageFlagForwarded != 0,

NumAttachments: len(attData),
}
Expand Down
57 changes: 57 additions & 0 deletions server/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/bradenaw/juniper/xslices"
"mime"
"net/http"
"net/mail"
Expand Down Expand Up @@ -224,6 +225,62 @@ func (s *Server) handlePutMailMessagesUnread() gin.HandlerFunc {
}
}

func (s *Server) handlePutMailMessagesForwarded() gin.HandlerFunc {
return func(c *gin.Context) {
var req proton.MessageActionReq

if err := c.BindJSON(&req); err != nil {
c.AbortWithStatus(http.StatusBadRequest)
return
}

if err := s.b.SetMessagesForwarded(c.GetString("UserID"), true, req.IDs...); err != nil {
c.AbortWithStatus(http.StatusUnprocessableEntity)
return
}

c.JSON(http.StatusOK, gin.H{
"Code": 1001,
"Responses": xslices.Map(req.IDs, func(id string) any {
return gin.H{
"ID": id,
"Response": gin.H{
"Code": 1000,
},
}
}),
})
}
}

func (s *Server) handlePutMailMessagesUnforwarded() gin.HandlerFunc {
return func(c *gin.Context) {
var req proton.MessageActionReq

if err := c.BindJSON(&req); err != nil {
c.AbortWithStatus(http.StatusBadRequest)
return
}

if err := s.b.SetMessagesForwarded(c.GetString("UserID"), false, req.IDs...); err != nil {
c.AbortWithStatus(http.StatusUnprocessableEntity)
return
}

c.JSON(http.StatusOK, gin.H{
"Code": 1001,
"Responses": xslices.Map(req.IDs, func(id string) any {
return gin.H{
"ID": id,
"Response": gin.H{
"Code": 1000,
},
}
}),
})
}
}

func (s *Server) handlePutMailMessagesLabel() gin.HandlerFunc {
return func(c *gin.Context) {
var req proton.LabelMessagesReq
Expand Down
2 changes: 2 additions & 0 deletions server/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ func initRouter(s *Server) {
messages.POST("/import", s.handlePutMailMessagesImport())
messages.PUT("/delete", s.handleDeleteMailMessages())
messages.GET("/count", s.handleMessageGroupCount())
messages.PUT("/forward", s.handlePutMailMessagesForwarded())
messages.PUT("/unforward", s.handlePutMailMessagesUnforwarded())
}

if attachments := mail.Group("/attachments"); attachments != nil {
Expand Down
4 changes: 3 additions & 1 deletion server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,8 @@ func TestServer_Events(t *testing.T) {

// Mark a message as read.
require.NoError(t, c.MarkMessagesRead(ctx, messageIDs[0]))
// Mark a message as forwarded
require.NoError(t, c.MarkMessagesForwarded(ctx, messageIDs[0]))

// The message should eventually be read.
require.Eventually(t, func() bool {
Expand All @@ -375,7 +377,7 @@ func TestServer_Events(t *testing.T) {
return false
}

return !bool(event.Messages[0].Message.Unread)
return !bool(event.Messages[0].Message.Unread) && bool(event.Messages[0].Message.IsForwarded)
}, 5*time.Second, time.Millisecond*100)

// Add another message to archive.
Expand Down

0 comments on commit 7451b85

Please sign in to comment.