Jacopo Tessera created JAMES-4016: ------------------------------------- Summary: JMAP email keywords in mixed JMAP/IMAP usage Key: JAMES-4016 URL: https://issues.apache.org/jira/browse/JAMES-4016 Project: James Server Issue Type: Bug Components: JMAP Reporter: Jacopo Tessera Assignee: Antoine Duprat Attachments: cyrus-keyword.log, james-keyword.log
JMAP Email keywords are currently determined as the keywords of the message found in the "first" mailbox (refer to [https://github.com/apache/james-project/blob/master/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Email.scala#L508]). This approach works when using JMAP since the keywords get updated for every message during an Email/set operation. However, it leads to counterintuitive behavior when using IMAP in conjunction with JMAP (mixed JMAP/IMAP usage is a legitimate use case, see [https://jmap.io/spec-mail.html#introduction]). Consider the following scenario: * Assume an account with mailboxes "INBOX," "Foo," and "Bar," with the order of the mailboxes being "INBOX" < "Foo" < "Bar" ("INBOX" being the "first" mailbox when present, and "Foo" being the "first" mailbox when "INBOX" is not present). * Suppose there's a message in both the "Foo" and "Bar" mailboxes with keywords "foo" and "bar." The result of an Email/get call is as follows: {code:json} { ... "mailboxIds": { "<Foo_Id>": true, "<Bar_Id>": true }, "keywords": { "foo": true, "bar": true } } {code} where <Foo_Id> and <Bar_Id> represent the IDs of the "Foo" and "Bar" mailboxes, respectively. * Using IMAP, the keyword "foo" is removed from the message in the "Bar" mailbox, and the keyword "baz" is added to the message in the "Bar" mailbox. However, the result of Email/get remains unchanged: {code:json} { ... "mailboxIds": { "<Foo_Id>": true, "<Bar_Id>": true }, "keywords": { "foo": true, "bar": true } } {code} This discrepancy occurs because the flags of the message in the "Foo" mailbox remain unchanged, and "Foo" is considered the "first" mailbox. * Now, suppose the message is copied using IMAP from the "Bar" mailbox to the "INBOX" mailbox. The result of Email/get is now: {code:json} { ... "mailboxIds": { "<INBOX_Id>": true, "<Foo_Id>": true, "<Bar_Id>": true }, "keywords": { "baz": true, "bar": true } } {code} Hence, copying a message to another mailbox can entirely change the keywords of a message. This behavior is not specific to the copy operation, one can think of other scenarios where moving or deleting message on IMAP produces an unexpected result. h3. Proposed Solutions: * strategy a) The set of keywords for a JMAP message should be the intersection of the keywords of all messages across every mailbox. In other words, a JMAP message should have a keyword if and only if every message has that keyword. This ensures the stability of a JMAP message's keywords when issuing IMAP updates that do not affect the keywords. The behavior remains unchanged when using JMAP exclusively. * strategy b) The set of keywords for a JMAP message should be the union of the keywords of all messages across every mailbox. In other words, a JMAP message should have a keyword if at least a message has that keyword. The behavior remains unchanged when using JMAP exclusively. h3. What Does Cyrus Do? Based on the results in the attachments Cyrus seems to use the strategy b), but they consider the $seen flag as a special case. Their implementation can be found here [https://github.com/cyrusimap/cyrus-imapd/blob/master/imap/jmap_mail.c#L6394] h3. Extra The results of this scenario on Apache JAMES and cyrus-imapd can be found in the attachments. -- This message was sent by Atlassian Jira (v8.20.10#820010) --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org