mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-10 12:46:46 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b4892855d4 | |||
| 7ff67f2217 | |||
| b12873f1df | |||
| ec73170e9b |
13
Changelog.md
13
Changelog.md
@ -4,6 +4,19 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/)
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
## [Bridge 1.4.3] Forth
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
* Reverted sending IMAP updates to be not blocking again.
|
||||||
|
### Fixed
|
||||||
|
* GODT-783 Settings flags by FLAGS (not using +/-FLAGS) do not change spam state.
|
||||||
|
|
||||||
|
## [Bridge 1.4.2] Forth
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
* GODT-761 Use label.Path instead of Name to partially support subfolders for webapp beta release.
|
||||||
|
* GODT-765 Improve speed of checking whether message is deleted.
|
||||||
|
|
||||||
## [IE 1.1.1] Danube (beta 2020-09-xx) [Bridge 1.4.1] Forth (beta 2020-09-xx)
|
## [IE 1.1.1] Danube (beta 2020-09-xx) [Bridge 1.4.1] Forth (beta 2020-09-xx)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@ -15,8 +15,8 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
// Code generated by ./credits.sh at Wed Sep 16 16:48:58 CEST 2020. DO NOT EDIT.
|
// Code generated by ./credits.sh at Tue Sep 29 14:56:25 CEST 2020. DO NOT EDIT.
|
||||||
|
|
||||||
package bridge
|
package bridge
|
||||||
|
|
||||||
const Credits = "github.com/0xAX/notificator;github.com/ProtonMail/bcrypt;github.com/ProtonMail/crypto;github.com/ProtonMail/docker-credential-helpers;github.com/ProtonMail/go-appdir;github.com/ProtonMail/go-apple-mobileconfig;github.com/ProtonMail/go-autostart;github.com/ProtonMail/go-imap;github.com/ProtonMail/go-imap-id;github.com/ProtonMail/go-smtp;github.com/ProtonMail/go-vcard;github.com/ProtonMail/gopenpgp/v2;github.com/PuerkitoBio/goquery;github.com/abiosoft/ishell;github.com/abiosoft/readline;github.com/allan-simon/go-singleinstance;github.com/certifi/gocertifi;github.com/chzyer/logex;github.com/chzyer/test;github.com/cucumber/godog;github.com/docker/docker-credential-helpers;github.com/emersion/go-imap;github.com/emersion/go-imap-appendlimit;github.com/emersion/go-imap-idle;github.com/emersion/go-imap-move;github.com/emersion/go-imap-quota;github.com/emersion/go-imap-specialuse;github.com/emersion/go-imap-unselect;github.com/emersion/go-mbox;github.com/emersion/go-message;github.com/emersion/go-sasl;github.com/emersion/go-smtp;github.com/emersion/go-textwrapper;github.com/emersion/go-vcard;github.com/fatih/color;github.com/flynn-archive/go-shlex;github.com/getsentry/raven-go;github.com/go-resty/resty/v2;github.com/golang/mock;github.com/google/go-cmp;github.com/google/uuid;github.com/gopherjs/gopherjs;github.com/hashicorp/go-multierror;github.com/jameskeane/bcrypt;github.com/jaytaylor/html2text;github.com/kardianos/osext;github.com/keybase/go-keychain;github.com/logrusorgru/aurora;github.com/mattn/go-runewidth;github.com/miekg/dns;github.com/myesui/uuid;github.com/nsf/jsondiff;github.com/olekukonko/tablewriter;github.com/pkg/errors;github.com/sirupsen/logrus;github.com/skratchdot/open-golang;github.com/ssor/bom;github.com/stretchr/testify;github.com/therecipe/qt;github.com/twinj/uuid;github.com/urfave/cli;go.etcd.io/bbolt;golang.org/x/crypto;golang.org/x/net;golang.org/x/text;gopkg.in/stretchr/testify.v1;;Font Awesome 4.7.0;;Qt 5.13 by Qt group;"
|
const Credits = "github.com/0xAX/notificator;github.com/Masterminds/semver/v3;github.com/ProtonMail/bcrypt;github.com/ProtonMail/crypto;github.com/ProtonMail/docker-credential-helpers;github.com/ProtonMail/go-appdir;github.com/ProtonMail/go-apple-mobileconfig;github.com/ProtonMail/go-autostart;github.com/ProtonMail/go-imap;github.com/ProtonMail/go-imap-id;github.com/ProtonMail/go-smtp;github.com/ProtonMail/go-vcard;github.com/ProtonMail/gopenpgp/v2;github.com/ProtonMail/mbox;github.com/PuerkitoBio/goquery;github.com/abiosoft/ishell;github.com/abiosoft/readline;github.com/allan-simon/go-singleinstance;github.com/certifi/gocertifi;github.com/chzyer/logex;github.com/chzyer/test;github.com/cucumber/godog;github.com/docker/docker-credential-helpers;github.com/emersion/go-imap;github.com/emersion/go-imap-appendlimit;github.com/emersion/go-imap-idle;github.com/emersion/go-imap-move;github.com/emersion/go-imap-quota;github.com/emersion/go-imap-specialuse;github.com/emersion/go-imap-unselect;github.com/emersion/go-mbox;github.com/emersion/go-message;github.com/emersion/go-sasl;github.com/emersion/go-smtp;github.com/emersion/go-textwrapper;github.com/emersion/go-vcard;github.com/fatih/color;github.com/flynn-archive/go-shlex;github.com/getsentry/raven-go;github.com/go-resty/resty/v2;github.com/golang/mock;github.com/google/go-cmp;github.com/google/uuid;github.com/gopherjs/gopherjs;github.com/hashicorp/go-multierror;github.com/jameskeane/bcrypt;github.com/jaytaylor/html2text;github.com/kardianos/osext;github.com/keybase/go-keychain;github.com/logrusorgru/aurora;github.com/mattn/go-runewidth;github.com/miekg/dns;github.com/myesui/uuid;github.com/nsf/jsondiff;github.com/olekukonko/tablewriter;github.com/pkg/errors;github.com/sirupsen/logrus;github.com/skratchdot/open-golang;github.com/ssor/bom;github.com/stretchr/testify;github.com/therecipe/qt;github.com/twinj/uuid;github.com/urfave/cli;go.etcd.io/bbolt;golang.org/x/crypto;golang.org/x/net;golang.org/x/text;gopkg.in/stretchr/testify.v1;;Font Awesome 4.7.0;;Qt 5.13 by Qt group;"
|
||||||
|
|||||||
@ -57,6 +57,10 @@ func (im *imapMailbox) UpdateMessagesFlags(uid bool, seqSet *imap.SeqSet, operat
|
|||||||
return im.addOrRemoveFlags(operation, messageIDs, flags)
|
return im.addOrRemoveFlags(operation, messageIDs, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setFlags is used for FLAGS command (not +FLAGS or -FLAGS), which means
|
||||||
|
// to set flags passed as an argument and unset the rest. For example,
|
||||||
|
// if message is not read, is flagged and is not deleted, call FLAGS \Seen
|
||||||
|
// should flag message as read, unflagged and keep undeleted.
|
||||||
func (im *imapMailbox) setFlags(messageIDs, flags []string) error { //nolint
|
func (im *imapMailbox) setFlags(messageIDs, flags []string) error { //nolint
|
||||||
seen := false
|
seen := false
|
||||||
flagged := false
|
flagged := false
|
||||||
@ -106,16 +110,17 @@ func (im *imapMailbox) setFlags(messageIDs, flags []string) error { //nolint
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spamMailbox, err := im.storeAddress.GetMailbox("Spam")
|
// Spam should not be taken into action here as Outlook is using FLAGS
|
||||||
if err != nil {
|
// without preserving junk flag. Probably it's because junk is not standard
|
||||||
return err
|
// in the rfc3501 and thus Outlook expects calling FLAGS \Seen will not
|
||||||
}
|
// change the state of junk or other non-standard flags.
|
||||||
|
// Still, its safe to label as spam once any client sends the request.
|
||||||
if spam {
|
if spam {
|
||||||
if err := spamMailbox.LabelMessages(messageIDs); err != nil {
|
spamMailbox, err := im.storeAddress.GetMailbox("Spam")
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
if err := spamMailbox.LabelMessages(messageIDs); err != nil {
|
||||||
if err := spamMailbox.UnlabelMessages(messageIDs); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,8 +15,8 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
// Code generated by ./credits.sh at Wed Sep 23 01:34:10 PM CEST 2020. DO NOT EDIT.
|
// Code generated by ./credits.sh at Tue Sep 29 14:56:25 CEST 2020. DO NOT EDIT.
|
||||||
|
|
||||||
package importexport
|
package importexport
|
||||||
|
|
||||||
const Credits = "github.com/0xAX/notificator;github.com/abiosoft/ishell;github.com/abiosoft/readline;github.com/allan-simon/go-singleinstance;github.com/certifi/gocertifi;github.com/chzyer/logex;github.com/chzyer/test;github.com/cucumber/godog;github.com/docker/docker-credential-helpers;github.com/emersion/go-imap;github.com/emersion/go-imap-appendlimit;github.com/emersion/go-imap-idle;github.com/emersion/go-imap-move;github.com/emersion/go-imap-quota;github.com/emersion/go-imap-specialuse;github.com/emersion/go-imap-unselect;github.com/emersion/go-mbox;github.com/emersion/go-message;github.com/emersion/go-sasl;github.com/emersion/go-smtp;github.com/emersion/go-textwrapper;github.com/emersion/go-vcard;github.com/fatih/color;github.com/flynn-archive/go-shlex;github.com/getsentry/raven-go;github.com/golang/mock;github.com/google/go-cmp;github.com/google/uuid;github.com/gopherjs/gopherjs;github.com/go-resty/resty/v2;github.com/hashicorp/go-multierror;github.com/jameskeane/bcrypt;github.com/jaytaylor/html2text;github.com/kardianos/osext;github.com/keybase/go-keychain;github.com/logrusorgru/aurora;github.com/Masterminds/semver/v3;github.com/mattn/go-runewidth;github.com/miekg/dns;github.com/myesui/uuid;github.com/nsf/jsondiff;github.com/olekukonko/tablewriter;github.com/pkg/errors;github.com/ProtonMail/bcrypt;github.com/ProtonMail/crypto;github.com/ProtonMail/docker-credential-helpers;github.com/ProtonMail/go-appdir;github.com/ProtonMail/go-apple-mobileconfig;github.com/ProtonMail/go-autostart;github.com/ProtonMail/go-imap;github.com/ProtonMail/go-imap-id;github.com/ProtonMail/gopenpgp/v2;github.com/ProtonMail/go-smtp;github.com/ProtonMail/go-vcard;github.com/ProtonMail/mbox;github.com/PuerkitoBio/goquery;github.com/sirupsen/logrus;github.com/skratchdot/open-golang;github.com/ssor/bom;github.com/stretchr/testify;github.com/therecipe/qt;github.com/twinj/uuid;github.com/urfave/cli;go.etcd.io/bbolt;golang.org/x/crypto;golang.org/x/net;golang.org/x/text;gopkg.in/stretchr/testify.v1;;Font Awesome 4.7.0;;Qt 5.13 by Qt group;"
|
const Credits = "github.com/0xAX/notificator;github.com/Masterminds/semver/v3;github.com/ProtonMail/bcrypt;github.com/ProtonMail/crypto;github.com/ProtonMail/docker-credential-helpers;github.com/ProtonMail/go-appdir;github.com/ProtonMail/go-apple-mobileconfig;github.com/ProtonMail/go-autostart;github.com/ProtonMail/go-imap;github.com/ProtonMail/go-imap-id;github.com/ProtonMail/go-smtp;github.com/ProtonMail/go-vcard;github.com/ProtonMail/gopenpgp/v2;github.com/ProtonMail/mbox;github.com/PuerkitoBio/goquery;github.com/abiosoft/ishell;github.com/abiosoft/readline;github.com/allan-simon/go-singleinstance;github.com/certifi/gocertifi;github.com/chzyer/logex;github.com/chzyer/test;github.com/cucumber/godog;github.com/docker/docker-credential-helpers;github.com/emersion/go-imap;github.com/emersion/go-imap-appendlimit;github.com/emersion/go-imap-idle;github.com/emersion/go-imap-move;github.com/emersion/go-imap-quota;github.com/emersion/go-imap-specialuse;github.com/emersion/go-imap-unselect;github.com/emersion/go-mbox;github.com/emersion/go-message;github.com/emersion/go-sasl;github.com/emersion/go-smtp;github.com/emersion/go-textwrapper;github.com/emersion/go-vcard;github.com/fatih/color;github.com/flynn-archive/go-shlex;github.com/getsentry/raven-go;github.com/go-resty/resty/v2;github.com/golang/mock;github.com/google/go-cmp;github.com/google/uuid;github.com/gopherjs/gopherjs;github.com/hashicorp/go-multierror;github.com/jameskeane/bcrypt;github.com/jaytaylor/html2text;github.com/kardianos/osext;github.com/keybase/go-keychain;github.com/logrusorgru/aurora;github.com/mattn/go-runewidth;github.com/miekg/dns;github.com/myesui/uuid;github.com/nsf/jsondiff;github.com/olekukonko/tablewriter;github.com/pkg/errors;github.com/sirupsen/logrus;github.com/skratchdot/open-golang;github.com/ssor/bom;github.com/stretchr/testify;github.com/therecipe/qt;github.com/twinj/uuid;github.com/urfave/cli;go.etcd.io/bbolt;golang.org/x/crypto;golang.org/x/net;golang.org/x/text;gopkg.in/stretchr/testify.v1;;Font Awesome 4.7.0;;Qt 5.13 by Qt group;"
|
||||||
|
|||||||
@ -69,7 +69,7 @@ func (storeAddress *Address) init(foldersAndLabels []*pmapi.Label) (err error) {
|
|||||||
prefix := getLabelPrefix(label)
|
prefix := getLabelPrefix(label)
|
||||||
|
|
||||||
var mailbox *Mailbox
|
var mailbox *Mailbox
|
||||||
if mailbox, err = txNewMailbox(tx, storeAddress, label.ID, prefix, label.Name, label.Color); err != nil {
|
if mailbox, err = txNewMailbox(tx, storeAddress, label.ID, prefix, label.Path, label.Color); err != nil {
|
||||||
storeAddress.log.
|
storeAddress.log.
|
||||||
WithError(err).
|
WithError(err).
|
||||||
WithField("labelID", label.ID).
|
WithField("labelID", label.ID).
|
||||||
|
|||||||
@ -73,14 +73,14 @@ func (storeAddress *Address) createOrUpdateMailboxEvent(label *pmapi.Label) erro
|
|||||||
prefix := getLabelPrefix(label)
|
prefix := getLabelPrefix(label)
|
||||||
mailbox, ok := storeAddress.mailboxes[label.ID]
|
mailbox, ok := storeAddress.mailboxes[label.ID]
|
||||||
if !ok {
|
if !ok {
|
||||||
mailbox, err := newMailbox(storeAddress, label.ID, prefix, label.Name, label.Color)
|
mailbox, err := newMailbox(storeAddress, label.ID, prefix, label.Path, label.Color)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
storeAddress.mailboxes[label.ID] = mailbox
|
storeAddress.mailboxes[label.ID] = mailbox
|
||||||
mailbox.store.imapMailboxCreated(storeAddress.address, mailbox.labelName)
|
mailbox.store.imapMailboxCreated(storeAddress.address, mailbox.labelName)
|
||||||
} else {
|
} else {
|
||||||
mailbox.labelName = prefix + label.Name
|
mailbox.labelName = prefix + label.Path
|
||||||
mailbox.color = label.Color
|
mailbox.color = label.Color
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -122,22 +122,10 @@ func (store *Store) imapSendUpdate(update imapBackend.Update) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
done := update.Done()
|
|
||||||
go func() {
|
|
||||||
// This timeout is to not keep running many blocked goroutines.
|
|
||||||
// In case nothing listens to this channel, this thread should stop.
|
|
||||||
select {
|
|
||||||
case store.imapUpdates <- update:
|
|
||||||
case <-time.After(1 * time.Second):
|
|
||||||
store.log.Warn("IMAP update could not be sent (timeout).")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// This timeout is to not block IMAP backend by wait for IMAP client.
|
|
||||||
select {
|
select {
|
||||||
case <-done:
|
|
||||||
case <-time.After(1 * time.Second):
|
case <-time.After(1 * time.Second):
|
||||||
store.log.Warn("IMAP update could not be delivered (timeout).")
|
store.log.Warn("IMAP update could not be sent (timeout)")
|
||||||
return
|
return
|
||||||
|
case store.imapUpdates <- update:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -142,6 +142,9 @@ func initMailboxBucket(tx *bolt.Tx, bucketName []byte) error {
|
|||||||
if _, err := bucket.CreateBucketIfNotExists(apiIDsBucket); err != nil {
|
if _, err := bucket.CreateBucketIfNotExists(apiIDsBucket); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if _, err := bucket.CreateBucketIfNotExists(deletedIDsBucket); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -240,13 +243,7 @@ func (storeMailbox *Mailbox) txGetAPIIDsBucket(tx *bolt.Tx) *bolt.Bucket {
|
|||||||
|
|
||||||
// txGetDeletedIDsBucket returns the bucket with messagesID marked as deleted
|
// txGetDeletedIDsBucket returns the bucket with messagesID marked as deleted
|
||||||
func (storeMailbox *Mailbox) txGetDeletedIDsBucket(tx *bolt.Tx) *bolt.Bucket {
|
func (storeMailbox *Mailbox) txGetDeletedIDsBucket(tx *bolt.Tx) *bolt.Bucket {
|
||||||
// There should be no error since it _...returns an error if the bucket
|
return storeMailbox.txGetBucket(tx).Bucket(deletedIDsBucket)
|
||||||
// name is blank, or if the bucket name is too long._
|
|
||||||
bucket, err := storeMailbox.txGetBucket(tx).CreateBucketIfNotExists(deletedIDsBucket)
|
|
||||||
if err != nil || bucket == nil {
|
|
||||||
storeMailbox.log.WithError(err).Error("Cannot create or get bucket with deleted IDs.")
|
|
||||||
}
|
|
||||||
return bucket
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// txGetBucket returns the bucket of mailbox containing mapping buckets.
|
// txGetBucket returns the bucket of mailbox containing mapping buckets.
|
||||||
|
|||||||
@ -125,6 +125,7 @@ func (mc *mailboxCounts) getPMLabel() *pmapi.Label {
|
|||||||
return &pmapi.Label{
|
return &pmapi.Label{
|
||||||
ID: mc.LabelID,
|
ID: mc.LabelID,
|
||||||
Name: mc.LabelName,
|
Name: mc.LabelName,
|
||||||
|
Path: mc.LabelName,
|
||||||
Color: mc.Color,
|
Color: mc.Color,
|
||||||
Order: mc.Order,
|
Order: mc.Order,
|
||||||
Type: pmapi.LabelTypeMailbox,
|
Type: pmapi.LabelTypeMailbox,
|
||||||
@ -158,7 +159,7 @@ func (store *Store) createOrUpdateMailboxCountsBuckets(labels []*pmapi.Label) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update mailbox info, but dont change on-API-counts.
|
// Update mailbox info, but dont change on-API-counts.
|
||||||
mailbox.LabelName = label.Name
|
mailbox.LabelName = label.Path
|
||||||
mailbox.Color = label.Color
|
mailbox.Color = label.Color
|
||||||
mailbox.Order = label.Order
|
mailbox.Order = label.Order
|
||||||
mailbox.IsFolder = label.Exclusive == 1
|
mailbox.IsFolder = label.Exclusive == 1
|
||||||
|
|||||||
@ -66,7 +66,7 @@ func (message *Message) Message() *pmapi.Message {
|
|||||||
// mailbox
|
// mailbox
|
||||||
func (message *Message) IsMarkedDeleted() bool {
|
func (message *Message) IsMarkedDeleted() bool {
|
||||||
isMarkedAsDeleted := false
|
isMarkedAsDeleted := false
|
||||||
err := message.storeMailbox.db().Update(func(tx *bolt.Tx) error {
|
err := message.storeMailbox.db().View(func(tx *bolt.Tx) error {
|
||||||
isMarkedAsDeleted = message.storeMailbox.txGetDeletedIDsBucket(tx).Get([]byte(message.msg.ID)) != nil
|
isMarkedAsDeleted = message.storeMailbox.txGetDeletedIDsBucket(tx).Get([]byte(message.msg.ID)) != nil
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|||||||
@ -80,6 +80,7 @@ const (
|
|||||||
type Label struct {
|
type Label struct {
|
||||||
ID string
|
ID string
|
||||||
Name string
|
Name string
|
||||||
|
Path string
|
||||||
Color string
|
Color string
|
||||||
Order int `json:",omitempty"`
|
Order int `json:",omitempty"`
|
||||||
Display int // Not used for now, leave it empty.
|
Display int // Not used for now, leave it empty.
|
||||||
|
|||||||
@ -83,6 +83,9 @@ func (ctl *Controller) AddUserLabel(username string, label *pmapi.Label) error {
|
|||||||
}
|
}
|
||||||
label.ID = ctl.labelIDGenerator.next(prefix)
|
label.ID = ctl.labelIDGenerator.next(prefix)
|
||||||
label.Name = labelName
|
label.Name = labelName
|
||||||
|
if label.Path == "" {
|
||||||
|
label.Path = label.Name
|
||||||
|
}
|
||||||
ctl.labelsByUsername[username] = append(ctl.labelsByUsername[username], label)
|
ctl.labelsByUsername[username] = append(ctl.labelsByUsername[username], label)
|
||||||
ctl.resetUsers()
|
ctl.resetUsers()
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -53,6 +53,9 @@ func (api *FakePMAPI) CreateLabel(label *pmapi.Label) (*pmapi.Label, error) {
|
|||||||
prefix = "folder"
|
prefix = "folder"
|
||||||
}
|
}
|
||||||
label.ID = api.controller.labelIDGenerator.next(prefix)
|
label.ID = api.controller.labelIDGenerator.next(prefix)
|
||||||
|
if label.Path == "" {
|
||||||
|
label.Path = label.Name
|
||||||
|
}
|
||||||
api.labels = append(api.labels, label)
|
api.labels = append(api.labels, label)
|
||||||
api.addEventLabel(pmapi.EventCreate, label)
|
api.addEventLabel(pmapi.EventCreate, label)
|
||||||
return label, nil
|
return label, nil
|
||||||
@ -67,6 +70,9 @@ func (api *FakePMAPI) UpdateLabel(label *pmapi.Label) (*pmapi.Label, error) {
|
|||||||
// Request doesn't have to include all properties and these have to stay the same.
|
// Request doesn't have to include all properties and these have to stay the same.
|
||||||
label.Type = existingLabel.Type
|
label.Type = existingLabel.Type
|
||||||
label.Exclusive = existingLabel.Exclusive
|
label.Exclusive = existingLabel.Exclusive
|
||||||
|
if label.Path == "" {
|
||||||
|
label.Path = label.Name
|
||||||
|
}
|
||||||
api.labels[idx] = label
|
api.labels[idx] = label
|
||||||
api.addEventLabel(pmapi.EventUpdate, label)
|
api.addEventLabel(pmapi.EventUpdate, label)
|
||||||
return label, nil
|
return label, nil
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
Feature: IMAP list mailboxes
|
Feature: IMAP list mailboxes
|
||||||
Background:
|
Background:
|
||||||
Given there is connected user "user"
|
Given there is connected user "user"
|
||||||
And there is "user" with mailbox "Folders/mbox1"
|
|
||||||
And there is "user" with mailbox "Labels/mbox2"
|
|
||||||
And there is IMAP client logged in as "user"
|
|
||||||
|
|
||||||
Scenario: List mailboxes
|
Scenario: List mailboxes
|
||||||
|
Given there is "user" with mailbox "Folders/mbox1"
|
||||||
|
And there is "user" with mailbox "Labels/mbox2"
|
||||||
|
And there is IMAP client logged in as "user"
|
||||||
When IMAP client lists mailboxes
|
When IMAP client lists mailboxes
|
||||||
Then IMAP response contains "INBOX"
|
Then IMAP response contains "INBOX"
|
||||||
Then IMAP response contains "Sent"
|
Then IMAP response contains "Sent"
|
||||||
@ -14,3 +14,16 @@ Feature: IMAP list mailboxes
|
|||||||
Then IMAP response contains "All Mail"
|
Then IMAP response contains "All Mail"
|
||||||
Then IMAP response contains "Folders/mbox1"
|
Then IMAP response contains "Folders/mbox1"
|
||||||
Then IMAP response contains "Labels/mbox2"
|
Then IMAP response contains "Labels/mbox2"
|
||||||
|
|
||||||
|
@ignore-live
|
||||||
|
Scenario: List mailboxes with subfolders
|
||||||
|
# Escaped slash in the name contains slash in the name.
|
||||||
|
# Not-escaped slash in the name means tree structure.
|
||||||
|
# We keep escaping in an IMAP communication so each mailbox is unique and
|
||||||
|
# both mailboxes are accessible. The slash is visible in the IMAP client.
|
||||||
|
Given there is "user" with mailbox "Folders/a\/b"
|
||||||
|
And there is "user" with mailbox "Folders/a/b"
|
||||||
|
And there is IMAP client logged in as "user"
|
||||||
|
When IMAP client lists mailboxes
|
||||||
|
Then IMAP response contains "Folders/a\/b"
|
||||||
|
Then IMAP response contains "Folders/a/b"
|
||||||
|
|||||||
21
test/features/bridge/imap/message/update_spam.feature
Normal file
21
test/features/bridge/imap/message/update_spam.feature
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
Feature: IMAP update messages in Spam folder
|
||||||
|
Background:
|
||||||
|
Given there is connected user "user"
|
||||||
|
# Messages are inserted in opposite way to keep increasing ID.
|
||||||
|
# Sequence numbers are then opposite than listed above.
|
||||||
|
And there are messages in mailbox "Spam" for "user"
|
||||||
|
| from | to | subject | body | read | starred | deleted |
|
||||||
|
| john.doe@mail.com | user@pm.me | foo | hello | false | false | false |
|
||||||
|
| jane.doe@mail.com | name@pm.me | bar | world | true | true | false |
|
||||||
|
And there is IMAP client logged in as "user"
|
||||||
|
And there is IMAP client selected in "Spam"
|
||||||
|
|
||||||
|
Scenario: Mark message as read only
|
||||||
|
When IMAP client marks message "2" with "\Seen"
|
||||||
|
Then IMAP response is "OK"
|
||||||
|
And message "1" in "Spam" for "user" is marked as read
|
||||||
|
And message "1" in "Spam" for "user" is marked as unstarred
|
||||||
|
And API mailbox "Spam" for "user" has messages
|
||||||
|
| from | to | subject |
|
||||||
|
| john.doe@mail.com | user@pm.me | foo |
|
||||||
|
| jane.doe@mail.com | name@pm.me | bar |
|
||||||
Reference in New Issue
Block a user