// Copyright (c) 2021 Proton Technologies AG // // This file is part of ProtonMail Bridge. // // ProtonMail Bridge is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // ProtonMail Bridge is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with ProtonMail Bridge. If not, see . package imap import ( "errors" "time" "github.com/ProtonMail/proton-bridge/internal/store" imap "github.com/emersion/go-imap" ) // The mailbox containing all custom folders or labels. // The purpose of this mailbox is to see "Folders" and "Labels" // at the root of the mailbox tree, e.g.: // // Folders << this // Folders/Family // // Labels << this // Labels/Security // // This mailbox cannot be modified or read in any way. type imapRootMailbox struct { isFolder bool } func newFoldersRootMailbox() *imapRootMailbox { return &imapRootMailbox{isFolder: true} } func newLabelsRootMailbox() *imapRootMailbox { return &imapRootMailbox{isFolder: false} } func (m *imapRootMailbox) Name() string { if m.isFolder { return store.UserFoldersMailboxName } return store.UserLabelsMailboxName } func (m *imapRootMailbox) Info() (info *imap.MailboxInfo, err error) { info = &imap.MailboxInfo{ Attributes: []string{imap.NoSelectAttr}, Delimiter: store.PathDelimiter, } if m.isFolder { info.Name = store.UserFoldersMailboxName } else { info.Name = store.UserLabelsMailboxName } return } func (m *imapRootMailbox) Status(_ []imap.StatusItem) (*imap.MailboxStatus, error) { status := &imap.MailboxStatus{} if m.isFolder { status.Name = store.UserFoldersMailboxName } else { status.Name = store.UserLabelsMailboxName } return status, nil } func (m *imapRootMailbox) SetSubscribed(_ bool) error { return errors.New("cannot subscribe or unsubsribe to Labels or Folders mailboxes") } func (m *imapRootMailbox) Check() error { return nil } func (m *imapRootMailbox) ListMessages(uid bool, seqset *imap.SeqSet, items []imap.FetchItem, ch chan<- *imap.Message) error { close(ch) return nil } func (m *imapRootMailbox) SearchMessages(uid bool, criteria *imap.SearchCriteria) (ids []uint32, err error) { return } func (m *imapRootMailbox) CreateMessage(flags []string, t time.Time, body imap.Literal) error { return errors.New("cannot create a message in this mailbox") } func (m *imapRootMailbox) UpdateMessagesFlags(uid bool, seqset *imap.SeqSet, op imap.FlagsOp, flags []string) (err error) { return errors.New("cannot update message flags in this mailbox") } func (m *imapRootMailbox) CopyMessages(uid bool, seqset *imap.SeqSet, dest string) error { return nil } // Expunge is not used by Bridge. We delete the message once it is flagged as \Deleted. func (m *imapRootMailbox) Expunge() error { return nil }