mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-10 04:36:43 +00:00
GODT-2119: Only show supported label IDs to clients
This commit is contained in:
@ -28,7 +28,6 @@ import (
|
|||||||
"github.com/ProtonMail/proton-bridge/v2/internal/logging"
|
"github.com/ProtonMail/proton-bridge/v2/internal/logging"
|
||||||
"github.com/ProtonMail/proton-bridge/v2/internal/safe"
|
"github.com/ProtonMail/proton-bridge/v2/internal/safe"
|
||||||
"github.com/ProtonMail/proton-bridge/v2/internal/vault"
|
"github.com/ProtonMail/proton-bridge/v2/internal/vault"
|
||||||
"github.com/bradenaw/juniper/xslices"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"gitlab.protontech.ch/go/liteapi"
|
"gitlab.protontech.ch/go/liteapi"
|
||||||
)
|
)
|
||||||
@ -437,7 +436,7 @@ func (user *User) handleCreateMessageEvent(ctx context.Context, event liteapi.Me
|
|||||||
}).Info("Handling message created event")
|
}).Info("Handling message created event")
|
||||||
|
|
||||||
return withAddrKR(user.apiUser, user.apiAddrs[event.Message.AddressID], user.vault.KeyPass(), func(_, addrKR *crypto.KeyRing) error {
|
return withAddrKR(user.apiUser, user.apiAddrs[event.Message.AddressID], user.vault.KeyPass(), func(_, addrKR *crypto.KeyRing) error {
|
||||||
buildRes, err := buildRFC822(full, addrKR)
|
buildRes, err := buildRFC822(user.apiLabels, full, addrKR)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to build RFC822 message: %w", err)
|
return fmt.Errorf("failed to build RFC822 message: %w", err)
|
||||||
}
|
}
|
||||||
@ -446,7 +445,7 @@ func (user *User) handleCreateMessageEvent(ctx context.Context, event liteapi.Me
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}, user.apiUserLock, user.apiAddrsLock, user.updateChLock)
|
}, user.apiUserLock, user.apiAddrsLock, user.apiLabelsLock, user.updateChLock)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) handleUpdateMessageEvent(ctx context.Context, event liteapi.MessageEvent) error { //nolint:unparam
|
func (user *User) handleUpdateMessageEvent(ctx context.Context, event liteapi.MessageEvent) error { //nolint:unparam
|
||||||
@ -458,13 +457,13 @@ func (user *User) handleUpdateMessageEvent(ctx context.Context, event liteapi.Me
|
|||||||
|
|
||||||
user.updateCh[event.Message.AddressID].Enqueue(imap.NewMessageMailboxesUpdated(
|
user.updateCh[event.Message.AddressID].Enqueue(imap.NewMessageMailboxesUpdated(
|
||||||
imap.MessageID(event.ID),
|
imap.MessageID(event.ID),
|
||||||
mapTo[string, imap.MailboxID](xslices.Filter(event.Message.LabelIDs, wantLabelID)),
|
mapTo[string, imap.MailboxID](wantLabels(user.apiLabels, event.Message.LabelIDs)),
|
||||||
event.Message.Seen(),
|
event.Message.Seen(),
|
||||||
event.Message.Starred(),
|
event.Message.Starred(),
|
||||||
))
|
))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}, user.updateChLock)
|
}, user.apiLabelsLock, user.updateChLock)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) handleDeleteMessageEvent(ctx context.Context, event liteapi.MessageEvent) error { //nolint:unparam
|
func (user *User) handleDeleteMessageEvent(ctx context.Context, event liteapi.MessageEvent) error { //nolint:unparam
|
||||||
@ -492,7 +491,7 @@ func (user *User) handleUpdateDraftEvent(ctx context.Context, event liteapi.Mess
|
|||||||
}
|
}
|
||||||
|
|
||||||
return withAddrKR(user.apiUser, user.apiAddrs[event.Message.AddressID], user.vault.KeyPass(), func(_, addrKR *crypto.KeyRing) error {
|
return withAddrKR(user.apiUser, user.apiAddrs[event.Message.AddressID], user.vault.KeyPass(), func(_, addrKR *crypto.KeyRing) error {
|
||||||
buildRes, err := buildRFC822(full, addrKR)
|
buildRes, err := buildRFC822(user.apiLabels, full, addrKR)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to build RFC822 draft: %w", err)
|
return fmt.Errorf("failed to build RFC822 draft: %w", err)
|
||||||
}
|
}
|
||||||
@ -506,7 +505,7 @@ func (user *User) handleUpdateDraftEvent(ctx context.Context, event liteapi.Mess
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}, user.apiUserLock, user.apiAddrsLock, user.updateChLock)
|
}, user.apiUserLock, user.apiAddrsLock, user.apiLabelsLock, user.updateChLock)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getMailboxName(label liteapi.Label) []string {
|
func getMailboxName(label liteapi.Label) []string {
|
||||||
|
|||||||
@ -113,6 +113,7 @@ func (user *User) sync(ctx context.Context) error {
|
|||||||
user.ID(),
|
user.ID(),
|
||||||
user.client,
|
user.client,
|
||||||
user.vault,
|
user.vault,
|
||||||
|
user.apiLabels,
|
||||||
addrKRs,
|
addrKRs,
|
||||||
user.updateCh,
|
user.updateCh,
|
||||||
user.eventCh,
|
user.eventCh,
|
||||||
@ -147,12 +148,14 @@ func syncLabels(ctx context.Context, apiLabels map[string]liteapi.Label, updateC
|
|||||||
|
|
||||||
// Sync the user's labels.
|
// Sync the user's labels.
|
||||||
for labelID, label := range apiLabels {
|
for labelID, label := range apiLabels {
|
||||||
|
if !wantLabel(label) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
switch label.Type {
|
switch label.Type {
|
||||||
case liteapi.LabelTypeSystem:
|
case liteapi.LabelTypeSystem:
|
||||||
if wantLabelID(labelID) {
|
for _, updateCh := range updateCh {
|
||||||
for _, updateCh := range updateCh {
|
updateCh.Enqueue(newSystemMailboxCreatedUpdate(imap.MailboxID(label.ID), label.Name))
|
||||||
updateCh.Enqueue(newSystemMailboxCreatedUpdate(imap.MailboxID(label.ID), label.Name))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case liteapi.LabelTypeFolder, liteapi.LabelTypeLabel:
|
case liteapi.LabelTypeFolder, liteapi.LabelTypeLabel:
|
||||||
@ -181,6 +184,7 @@ func syncMessages( //nolint:funlen
|
|||||||
userID string,
|
userID string,
|
||||||
client *liteapi.Client,
|
client *liteapi.Client,
|
||||||
vault *vault.User,
|
vault *vault.User,
|
||||||
|
apiLabels map[string]liteapi.Label,
|
||||||
addrKRs map[string]*crypto.KeyRing,
|
addrKRs map[string]*crypto.KeyRing,
|
||||||
updateCh map[string]*queue.QueuedChannel[imap.Update],
|
updateCh map[string]*queue.QueuedChannel[imap.Update],
|
||||||
eventCh *queue.QueuedChannel[events.Event],
|
eventCh *queue.QueuedChannel[events.Event],
|
||||||
@ -196,7 +200,7 @@ func syncMessages( //nolint:funlen
|
|||||||
buildCh := stream.Map(
|
buildCh := stream.Map(
|
||||||
client.GetFullMessages(ctx, syncWorkers, syncBuffer, messageIDs...),
|
client.GetFullMessages(ctx, syncWorkers, syncBuffer, messageIDs...),
|
||||||
func(_ context.Context, full liteapi.FullMessage) (*buildRes, error) {
|
func(_ context.Context, full liteapi.FullMessage) (*buildRes, error) {
|
||||||
return buildRFC822(full, addrKRs[full.AddressID])
|
return buildRFC822(apiLabels, full, addrKRs[full.AddressID])
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -293,14 +297,46 @@ func newMailboxCreatedUpdate(labelID imap.MailboxID, labelName []string) *imap.M
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func wantLabelID(labelID string) bool {
|
func wantLabel(label liteapi.Label) bool {
|
||||||
switch labelID {
|
if label.Type != liteapi.LabelTypeSystem {
|
||||||
case liteapi.AllDraftsLabel, liteapi.AllSentLabel, liteapi.OutboxLabel:
|
|
||||||
return false
|
|
||||||
|
|
||||||
default:
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nolint:exhaustive
|
||||||
|
switch label.ID {
|
||||||
|
case liteapi.InboxLabel:
|
||||||
|
return true
|
||||||
|
|
||||||
|
case liteapi.TrashLabel:
|
||||||
|
return true
|
||||||
|
|
||||||
|
case liteapi.SpamLabel:
|
||||||
|
return true
|
||||||
|
|
||||||
|
case liteapi.AllMailLabel:
|
||||||
|
return true
|
||||||
|
|
||||||
|
case liteapi.ArchiveLabel:
|
||||||
|
return true
|
||||||
|
|
||||||
|
case liteapi.SentLabel:
|
||||||
|
return true
|
||||||
|
|
||||||
|
case liteapi.DraftsLabel:
|
||||||
|
return true
|
||||||
|
|
||||||
|
case liteapi.StarredLabel:
|
||||||
|
return true
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func wantLabels(apiLabels map[string]liteapi.Label, labelIDs []string) []string {
|
||||||
|
return xslices.Filter(labelIDs, func(labelID string) bool {
|
||||||
|
return wantLabel(apiLabels[labelID])
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func forEach[T any](ctx context.Context, streamer stream.Stream[T], fn func(T) error) error {
|
func forEach[T any](ctx context.Context, streamer stream.Stream[T], fn func(T) error) error {
|
||||||
|
|||||||
@ -23,7 +23,6 @@ import (
|
|||||||
"github.com/ProtonMail/gluon/imap"
|
"github.com/ProtonMail/gluon/imap"
|
||||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||||
"github.com/ProtonMail/proton-bridge/v2/pkg/message"
|
"github.com/ProtonMail/proton-bridge/v2/pkg/message"
|
||||||
"github.com/bradenaw/juniper/xslices"
|
|
||||||
"gitlab.protontech.ch/go/liteapi"
|
"gitlab.protontech.ch/go/liteapi"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -44,13 +43,13 @@ func defaultJobOpts() message.JobOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildRFC822(full liteapi.FullMessage, addrKR *crypto.KeyRing) (*buildRes, error) {
|
func buildRFC822(apiLabels map[string]liteapi.Label, full liteapi.FullMessage, addrKR *crypto.KeyRing) (*buildRes, error) {
|
||||||
literal, err := message.BuildRFC822(addrKR, full.Message, full.AttData, defaultJobOpts())
|
literal, err := message.BuildRFC822(addrKR, full.Message, full.AttData, defaultJobOpts())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to build message %s: %w", full.ID, err)
|
return nil, fmt.Errorf("failed to build message %s: %w", full.ID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
update, err := newMessageCreatedUpdate(full.MessageMetadata, literal)
|
update, err := newMessageCreatedUpdate(apiLabels, full.MessageMetadata, literal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create IMAP update for message %s: %w", full.ID, err)
|
return nil, fmt.Errorf("failed to create IMAP update for message %s: %w", full.ID, err)
|
||||||
}
|
}
|
||||||
@ -62,7 +61,11 @@ func buildRFC822(full liteapi.FullMessage, addrKR *crypto.KeyRing) (*buildRes, e
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMessageCreatedUpdate(message liteapi.MessageMetadata, literal []byte) (*imap.MessageCreated, error) {
|
func newMessageCreatedUpdate(
|
||||||
|
apiLabels map[string]liteapi.Label,
|
||||||
|
message liteapi.MessageMetadata,
|
||||||
|
literal []byte,
|
||||||
|
) (*imap.MessageCreated, error) {
|
||||||
parsedMessage, err := imap.NewParsedMessage(literal)
|
parsedMessage, err := imap.NewParsedMessage(literal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -71,7 +74,7 @@ func newMessageCreatedUpdate(message liteapi.MessageMetadata, literal []byte) (*
|
|||||||
return &imap.MessageCreated{
|
return &imap.MessageCreated{
|
||||||
Message: toIMAPMessage(message),
|
Message: toIMAPMessage(message),
|
||||||
Literal: literal,
|
Literal: literal,
|
||||||
MailboxIDs: mapTo[string, imap.MailboxID](xslices.Filter(message.LabelIDs, wantLabelID)),
|
MailboxIDs: mapTo[string, imap.MailboxID](wantLabels(apiLabels, message.LabelIDs)),
|
||||||
ParsedMessage: parsedMessage,
|
ParsedMessage: parsedMessage,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user