this repo has no description

more instructions

Changed files
+6052 -1
spec
+1 -1
AGENT.md
··· 20 20 2. DONE Add a `Jmap.Api` module to make JMAP API requests over HTTP and parse the 21 21 responses into the `Jmap.Types`. Used `Cohttp_lwt_unix` for the HTTP library. 22 22 Note: There is a compilation issue with the current ezjsonm package on the system. 23 - 3. Add an implementation of the Jmap_session handling. 23 + 3. Add a `Jmap_mail` implementation that follows `spec/rfc8621.txt`
+6051
spec/rfc8621.txt
··· 1 + 2 + 3 + 4 + 5 + 6 + 7 + Internet Engineering Task Force (IETF) N. Jenkins 8 + Request for Comments: 8621 Fastmail 9 + Updates: 5788 C. Newman 10 + Category: Standards Track Oracle 11 + ISSN: 2070-1721 August 2019 12 + 13 + 14 + The JSON Meta Application Protocol (JMAP) for Mail 15 + 16 + Abstract 17 + 18 + This document specifies a data model for synchronising email data 19 + with a server using the JSON Meta Application Protocol (JMAP). 20 + Clients can use this to efficiently search, access, organise, and 21 + send messages, and to get push notifications for fast 22 + resynchronisation when new messages are delivered or a change is made 23 + in another client. 24 + 25 + Status of This Memo 26 + 27 + This is an Internet Standards Track document. 28 + 29 + This document is a product of the Internet Engineering Task Force 30 + (IETF). It represents the consensus of the IETF community. It has 31 + received public review and has been approved for publication by the 32 + Internet Engineering Steering Group (IESG). Further information on 33 + Internet Standards is available in Section 2 of RFC 7841. 34 + 35 + Information about the current status of this document, any errata, 36 + and how to provide feedback on it may be obtained at 37 + https://www.rfc-editor.org/info/rfc8621. 38 + 39 + Copyright Notice 40 + 41 + Copyright (c) 2019 IETF Trust and the persons identified as the 42 + document authors. All rights reserved. 43 + 44 + This document is subject to BCP 78 and the IETF Trust's Legal 45 + Provisions Relating to IETF Documents 46 + (https://trustee.ietf.org/license-info) in effect on the date of 47 + publication of this document. Please review these documents 48 + carefully, as they describe your rights and restrictions with respect 49 + to this document. Code Components extracted from this document must 50 + include Simplified BSD License text as described in Section 4.e of 51 + the Trust Legal Provisions and are provided without warranty as 52 + described in the Simplified BSD License. 53 + 54 + 55 + 56 + 57 + 58 + Jenkins & Newman Standards Track [Page 1] 59 + 60 + RFC 8621 JMAP Mail August 2019 61 + 62 + 63 + Table of Contents 64 + 65 + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 66 + 1.1. Notational Conventions . . . . . . . . . . . . . . . . . 4 67 + 1.2. Terminology . . . . . . . . . . . . . . . . . . . . . . . 5 68 + 1.3. Additions to the Capabilities Object . . . . . . . . . . 5 69 + 1.3.1. urn:ietf:params:jmap:mail . . . . . . . . . . . . . . 5 70 + 1.3.2. urn:ietf:params:jmap:submission . . . . . . . . . . . 7 71 + 1.3.3. urn:ietf:params:jmap:vacationresponse . . . . . . . . 8 72 + 1.4. Data Type Support in Different Accounts . . . . . . . . . 8 73 + 1.5. Push . . . . . . . . . . . . . . . . . . . . . . . . . . 8 74 + 1.5.1. Example . . . . . . . . . . . . . . . . . . . . . . . 9 75 + 1.6. Ids . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 76 + 2. Mailboxes . . . . . . . . . . . . . . . . . . . . . . . . . . 9 77 + 2.1. Mailbox/get . . . . . . . . . . . . . . . . . . . . . . . 14 78 + 2.2. Mailbox/changes . . . . . . . . . . . . . . . . . . . . . 14 79 + 2.3. Mailbox/query . . . . . . . . . . . . . . . . . . . . . . 14 80 + 2.4. Mailbox/queryChanges . . . . . . . . . . . . . . . . . . 15 81 + 2.5. Mailbox/set . . . . . . . . . . . . . . . . . . . . . . . 16 82 + 2.6. Example . . . . . . . . . . . . . . . . . . . . . . . . . 17 83 + 3. Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 84 + 3.1. Thread/get . . . . . . . . . . . . . . . . . . . . . . . 22 85 + 3.1.1. Example . . . . . . . . . . . . . . . . . . . . . . . 22 86 + 3.2. Thread/changes . . . . . . . . . . . . . . . . . . . . . 22 87 + 4. Emails . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 88 + 4.1. Properties of the Email Object . . . . . . . . . . . . . 23 89 + 4.1.1. Metadata . . . . . . . . . . . . . . . . . . . . . . 24 90 + 4.1.2. Header Fields Parsed Forms . . . . . . . . . . . . . 26 91 + 4.1.3. Header Fields Properties . . . . . . . . . . . . . . 32 92 + 4.1.4. Body Parts . . . . . . . . . . . . . . . . . . . . . 35 93 + 4.2. Email/get . . . . . . . . . . . . . . . . . . . . . . . . 42 94 + 4.2.1. Example . . . . . . . . . . . . . . . . . . . . . . . 44 95 + 4.3. Email/changes . . . . . . . . . . . . . . . . . . . . . . 45 96 + 4.4. Email/query . . . . . . . . . . . . . . . . . . . . . . . 45 97 + 4.4.1. Filtering . . . . . . . . . . . . . . . . . . . . . . 46 98 + 4.4.2. Sorting . . . . . . . . . . . . . . . . . . . . . . . 49 99 + 4.4.3. Thread Collapsing . . . . . . . . . . . . . . . . . . 50 100 + 4.5. Email/queryChanges . . . . . . . . . . . . . . . . . . . 51 101 + 4.6. Email/set . . . . . . . . . . . . . . . . . . . . . . . . 51 102 + 4.7. Email/copy . . . . . . . . . . . . . . . . . . . . . . . 53 103 + 4.8. Email/import . . . . . . . . . . . . . . . . . . . . . . 54 104 + 4.9. Email/parse . . . . . . . . . . . . . . . . . . . . . . . 56 105 + 4.10. Examples . . . . . . . . . . . . . . . . . . . . . . . . 58 106 + 5. Search Snippets . . . . . . . . . . . . . . . . . . . . . . . 68 107 + 5.1. SearchSnippet/get . . . . . . . . . . . . . . . . . . . . 69 108 + 5.2. Example . . . . . . . . . . . . . . . . . . . . . . . . . 71 109 + 110 + 111 + 112 + 113 + 114 + Jenkins & Newman Standards Track [Page 2] 115 + 116 + RFC 8621 JMAP Mail August 2019 117 + 118 + 119 + 6. Identities . . . . . . . . . . . . . . . . . . . . . . . . . 72 120 + 6.1. Identity/get . . . . . . . . . . . . . . . . . . . . . . 73 121 + 6.2. Identity/changes . . . . . . . . . . . . . . . . . . . . 73 122 + 6.3. Identity/set . . . . . . . . . . . . . . . . . . . . . . 73 123 + 6.4. Example . . . . . . . . . . . . . . . . . . . . . . . . . 73 124 + 7. Email Submission . . . . . . . . . . . . . . . . . . . . . . 74 125 + 7.1. EmailSubmission/get . . . . . . . . . . . . . . . . . . . 80 126 + 7.2. EmailSubmission/changes . . . . . . . . . . . . . . . . . 80 127 + 7.3. EmailSubmission/query . . . . . . . . . . . . . . . . . . 80 128 + 7.4. EmailSubmission/queryChanges . . . . . . . . . . . . . . 81 129 + 7.5. EmailSubmission/set . . . . . . . . . . . . . . . . . . . 81 130 + 7.5.1. Example . . . . . . . . . . . . . . . . . . . . . . . 84 131 + 8. Vacation Response . . . . . . . . . . . . . . . . . . . . . . 86 132 + 8.1. VacationResponse/get . . . . . . . . . . . . . . . . . . 87 133 + 8.2. VacationResponse/set . . . . . . . . . . . . . . . . . . 88 134 + 9. Security Considerations . . . . . . . . . . . . . . . . . . . 88 135 + 9.1. EmailBodyPart Value . . . . . . . . . . . . . . . . . . . 88 136 + 9.2. HTML Email Display . . . . . . . . . . . . . . . . . . . 88 137 + 9.3. Multiple Part Display . . . . . . . . . . . . . . . . . . 91 138 + 9.4. Email Submission . . . . . . . . . . . . . . . . . . . . 91 139 + 9.5. Partial Account Access . . . . . . . . . . . . . . . . . 92 140 + 9.6. Permission to Send from an Address . . . . . . . . . . . 92 141 + 10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 93 142 + 10.1. JMAP Capability Registration for "mail" . . . . . . . . 93 143 + 10.2. JMAP Capability Registration for "submission" . . . . . 93 144 + 10.3. JMAP Capability Registration for "vacationresponse" . . 94 145 + 10.4. IMAP and JMAP Keywords Registry . . . . . . . . . . . . 94 146 + 10.4.1. Registration of JMAP Keyword "$draft" . . . . . . . 95 147 + 10.4.2. Registration of JMAP Keyword "$seen" . . . . . . . . 96 148 + 10.4.3. Registration of JMAP Keyword "$flagged" . . . . . . 97 149 + 10.4.4. Registration of JMAP Keyword "$answered" . . . . . . 98 150 + 10.4.5. Registration of "$recent" Keyword . . . . . . . . . 99 151 + 10.5. IMAP Mailbox Name Attributes Registry . . . . . . . . . 99 152 + 10.5.1. Registration of "inbox" Role . . . . . . . . . . . . 99 153 + 10.6. JMAP Error Codes Registry . . . . . . . . . . . . . . . 100 154 + 10.6.1. mailboxHasChild . . . . . . . . . . . . . . . . . . 100 155 + 10.6.2. mailboxHasEmail . . . . . . . . . . . . . . . . . . 100 156 + 10.6.3. blobNotFound . . . . . . . . . . . . . . . . . . . . 100 157 + 10.6.4. tooManyKeywords . . . . . . . . . . . . . . . . . . 101 158 + 10.6.5. tooManyMailboxes . . . . . . . . . . . . . . . . . . 101 159 + 10.6.6. invalidEmail . . . . . . . . . . . . . . . . . . . . 101 160 + 10.6.7. tooManyRecipients . . . . . . . . . . . . . . . . . 102 161 + 10.6.8. noRecipients . . . . . . . . . . . . . . . . . . . . 102 162 + 10.6.9. invalidRecipients . . . . . . . . . . . . . . . . . 102 163 + 10.6.10. forbiddenMailFrom . . . . . . . . . . . . . . . . . 103 164 + 10.6.11. forbiddenFrom . . . . . . . . . . . . . . . . . . . 103 165 + 10.6.12. forbiddenToSend . . . . . . . . . . . . . . . . . . 103 166 + 167 + 168 + 169 + 170 + Jenkins & Newman Standards Track [Page 3] 171 + 172 + RFC 8621 JMAP Mail August 2019 173 + 174 + 175 + 11. References . . . . . . . . . . . . . . . . . . . . . . . . . 104 176 + 11.1. Normative References . . . . . . . . . . . . . . . . . . 104 177 + 11.2. Informative References . . . . . . . . . . . . . . . . . 107 178 + Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 108 179 + 180 + 1. Introduction 181 + 182 + The JSON Meta Application Protocol (JMAP) [RFC8620] is a generic 183 + protocol for synchronising data, such as mail, calendars, or contacts 184 + between a client and a server. It is optimised for mobile and web 185 + environments and aims to provide a consistent interface to different 186 + data types. 187 + 188 + This specification defines a data model for accessing a mail store 189 + over JMAP, allowing you to query, read, organise, and submit mail for 190 + sending. 191 + 192 + The data model is designed to allow a server to provide consistent 193 + access to the same data via IMAP [RFC3501] as well as JMAP. As in 194 + IMAP, a message must belong to a mailbox; however, in JMAP, its id 195 + does not change if you move it between mailboxes, and the server may 196 + allow it to belong to multiple mailboxes simultaneously (often 197 + exposed in a user agent as labels rather than folders). 198 + 199 + As in IMAP, messages may also be assigned zero or more keywords: 200 + short arbitrary strings. These are primarily intended to store 201 + metadata to inform client display, such as unread status or whether a 202 + message has been replied to. An IANA registry allows common 203 + semantics to be shared between clients and extended easily in the 204 + future. 205 + 206 + A message and its replies are linked on the server by a common Thread 207 + id. Clients may fetch the list of messages with a particular Thread 208 + id to more easily present a threaded or conversational interface. 209 + 210 + Permissions for message access happen on a per-mailbox basis. 211 + Servers may give the user restricted permissions for certain 212 + mailboxes, for example, if another user's inbox has been shared as 213 + read-only with them. 214 + 215 + 1.1. Notational Conventions 216 + 217 + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 218 + "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 219 + "OPTIONAL" in this document are to be interpreted as described in 220 + BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all 221 + capitals, as shown here. 222 + 223 + 224 + 225 + 226 + Jenkins & Newman Standards Track [Page 4] 227 + 228 + RFC 8621 JMAP Mail August 2019 229 + 230 + 231 + Type signatures, examples, and property descriptions in this document 232 + follow the conventions established in Section 1.1 of [RFC8620]. Data 233 + types defined in the core specification are also used in this 234 + document. 235 + 236 + Servers MUST support all properties specified for the new data types 237 + defined in this document. 238 + 239 + 1.2. Terminology 240 + 241 + This document uses the same terminology as in the core JMAP 242 + specification. 243 + 244 + The terms Mailbox, Thread, Email, SearchSnippet, EmailSubmission and 245 + VacationResponse (with that specific capitalisation) are used to 246 + refer to the data types defined in this document and instances of 247 + those data types. 248 + 249 + The term message refers to a document in Internet Message Format, as 250 + described in [RFC5322]. The Email data type represents messages in 251 + the mail store and associated metadata. 252 + 253 + 1.3. Additions to the Capabilities Object 254 + 255 + The capabilities object is returned as part of the JMAP Session 256 + object; see [RFC8620], Section 2. 257 + 258 + This document defines three additional capability URIs. 259 + 260 + 1.3.1. urn:ietf:params:jmap:mail 261 + 262 + This represents support for the Mailbox, Thread, Email, and 263 + SearchSnippet data types and associated API methods. The value of 264 + this property in the JMAP session "capabilities" property is an empty 265 + object. 266 + 267 + The value of this property in an account's "accountCapabilities" 268 + property is an object that MUST contain the following information on 269 + server capabilities and permissions for that account: 270 + 271 + o maxMailboxesPerEmail: "UnsignedInt|null" 272 + 273 + The maximum number of Mailboxes (see Section 2) that can be can 274 + assigned to a single Email object (see Section 4). This MUST be 275 + an integer >= 1, or null for no limit (or rather, the limit is 276 + always the number of Mailboxes in the account). 277 + 278 + 279 + 280 + 281 + 282 + Jenkins & Newman Standards Track [Page 5] 283 + 284 + RFC 8621 JMAP Mail August 2019 285 + 286 + 287 + o maxMailboxDepth: "UnsignedInt|null" 288 + 289 + The maximum depth of the Mailbox hierarchy (i.e., one more than 290 + the maximum number of ancestors a Mailbox may have), or null for 291 + no limit. 292 + 293 + o maxSizeMailboxName: "UnsignedInt" 294 + 295 + The maximum length, in (UTF-8) octets, allowed for the name of a 296 + Mailbox. This MUST be at least 100, although it is recommended 297 + servers allow more. 298 + 299 + o maxSizeAttachmentsPerEmail: "UnsignedInt" 300 + 301 + The maximum total size of attachments, in octets, allowed for a 302 + single Email object. A server MAY still reject the import or 303 + creation of an Email with a lower attachment size total (for 304 + example, if the body includes several megabytes of text, causing 305 + the size of the encoded MIME structure to be over some server- 306 + defined limit). 307 + 308 + Note that this limit is for the sum of unencoded attachment sizes. 309 + Users are generally not knowledgeable about encoding overhead, 310 + etc., nor should they need to be, so marketing and help materials 311 + normally tell them the "max size attachments". This is the 312 + unencoded size they see on their hard drive, so this capability 313 + matches that and allows the client to consistently enforce what 314 + the user understands as the limit. 315 + 316 + The server may separately have a limit for the total size of the 317 + message [RFC5322], created by combining the attachments (often 318 + base64 encoded) with the message headers and bodies. For example, 319 + suppose the server advertises "maxSizeAttachmentsPerEmail: 320 + 50000000" (50 MB). The enforced server limit may be for a message 321 + size of 70000000 octets. Even with base64 encoding and a 2 MB 322 + HTML body, 50 MB attachments would fit under this limit. 323 + 324 + o emailQuerySortOptions: "String[]" 325 + 326 + A list of all the values the server supports for the "property" 327 + field of the Comparator object in an "Email/query" sort (see 328 + Section 4.4.2). This MAY include properties the client does not 329 + recognise (for example, custom properties specified in a vendor 330 + extension). Clients MUST ignore any unknown properties in the 331 + list. 332 + 333 + 334 + 335 + 336 + 337 + 338 + Jenkins & Newman Standards Track [Page 6] 339 + 340 + RFC 8621 JMAP Mail August 2019 341 + 342 + 343 + o mayCreateTopLevelMailbox: "Boolean" 344 + 345 + If true, the user may create a Mailbox (see Section 2) in this 346 + account with a null parentId. (Permission for creating a child of 347 + an existing Mailbox is given by the "myRights" property on that 348 + Mailbox.) 349 + 350 + 1.3.2. urn:ietf:params:jmap:submission 351 + 352 + This represents support for the Identity and EmailSubmission data 353 + types and associated API methods. The value of this property in the 354 + JMAP session "capabilities" property is an empty object. 355 + 356 + The value of this property in an account's "accountCapabilities" 357 + property is an object that MUST contain the following information on 358 + server capabilities and permissions for that account: 359 + 360 + o maxDelayedSend: "UnsignedInt" 361 + 362 + The number in seconds of the maximum delay the server supports in 363 + sending (see the EmailSubmission object description). This is 0 364 + if the server does not support delayed send. 365 + 366 + o submissionExtensions: "String[String[]]" 367 + 368 + The set of SMTP submission extensions supported by the server, 369 + which the client may use when creating an EmailSubmission object 370 + (see Section 7). Each key in the object is the "ehlo-name", and 371 + the value is a list of "ehlo-args". 372 + 373 + A JMAP implementation that talks to a submission server [RFC6409] 374 + SHOULD have a configuration setting that allows an administrator 375 + to modify the set of submission EHLO capabilities it may expose on 376 + this property. This allows a JMAP server to easily add access to 377 + a new submission extension without code changes. By default, the 378 + JMAP server should hide EHLO capabilities that have to do with the 379 + transport mechanism and thus are only relevant to the JMAP server 380 + (for example, PIPELINING, CHUNKING, or STARTTLS). 381 + 382 + Examples of Submission extensions to include: 383 + 384 + * FUTURERELEASE [RFC4865] 385 + 386 + * SIZE [RFC1870] 387 + 388 + * DSN [RFC3461] 389 + 390 + * DELIVERYBY [RFC2852] 391 + 392 + 393 + 394 + Jenkins & Newman Standards Track [Page 7] 395 + 396 + RFC 8621 JMAP Mail August 2019 397 + 398 + 399 + * MT-PRIORITY [RFC6710] 400 + 401 + A JMAP server MAY advertise an extension and implement the 402 + semantics of that extension locally on the JMAP server even if a 403 + submission server used by JMAP doesn't implement it. 404 + 405 + The full IANA registry of submission extensions can be found at 406 + <https://www.iana.org/assignments/mail-parameters>. 407 + 408 + 1.3.3. urn:ietf:params:jmap:vacationresponse 409 + 410 + This represents support for the VacationResponse data type and 411 + associated API methods. The value of this property is an empty 412 + object in both the JMAP session "capabilities" property and an 413 + account's "accountCapabilities" property. 414 + 415 + 1.4. Data Type Support in Different Accounts 416 + 417 + The server MUST include the appropriate capability strings as keys in 418 + the "accountCapabilities" property of any account with which the user 419 + may use the data types represented by that URI. Supported data types 420 + may differ between accounts the user has access to. For example, in 421 + the user's personal account, they may have access to all three sets 422 + of data, but in a shared account, they may only have data for 423 + "urn:ietf:params:jmap:mail". This means they can access 424 + Mailbox/Thread/Email data in the shared account but are not allowed 425 + to send as that account (and so do not have access to Identity/ 426 + EmailSubmission objects) or view/set its VacationResponse. 427 + 428 + 1.5. Push 429 + 430 + Servers MUST support the JMAP push mechanisms, as specified in 431 + [RFC8620], Section 7, to receive notifications when the state changes 432 + for any of the types defined in this specification. 433 + 434 + In addition, servers that implement the "urn:ietf:params:jmap:mail" 435 + capability MUST support pushing state changes for a type called 436 + "EmailDelivery". There are no methods to act on this type; it only 437 + exists as part of the push mechanism. The state string for this MUST 438 + change whenever a new Email is added to the store, but it SHOULD NOT 439 + change upon any other change to the Email objects, for example, if 440 + one is marked as read or deleted. 441 + 442 + Clients in battery-constrained environments may wish to delay 443 + fetching changes initiated by the user but fetch new Emails 444 + immediately so they can notify the user. To do this, they can 445 + register for pushes for the EmailDelivery type rather than the Email 446 + type (as defined in Section 4). 447 + 448 + 449 + 450 + Jenkins & Newman Standards Track [Page 8] 451 + 452 + RFC 8621 JMAP Mail August 2019 453 + 454 + 455 + 1.5.1. Example 456 + 457 + The client has registered for push notifications (see [RFC8620]) just 458 + for the EmailDelivery type. The user marks an Email as read on 459 + another device, causing the state string for the Email type to 460 + change; however, as nothing new was added to the store, the 461 + EmailDelivery state does not change and nothing is pushed to the 462 + client. A new message arrives in the user's inbox, again causing the 463 + Email state to change. This time, the EmailDelivery state also 464 + changes, and a StateChange object is pushed to the client with the 465 + new state string. The client may then resync to fetch the new Email 466 + immediately. 467 + 468 + 1.6. Ids 469 + 470 + If a JMAP Mail server also provides an IMAP interface to the data and 471 + supports IMAP Extension for Object Identifiers [RFC8474], the ids 472 + SHOULD be the same for Mailbox, Thread, and Email objects in JMAP. 473 + 474 + 2. Mailboxes 475 + 476 + A Mailbox represents a named set of Email objects. This is the 477 + primary mechanism for organising messages within an account. It is 478 + analogous to a folder or a label in other systems. A Mailbox may 479 + perform a certain role in the system; see below for more details. 480 + 481 + For compatibility with IMAP, an Email MUST belong to one or more 482 + Mailboxes. The Email id does not change if the Email changes 483 + Mailboxes. 484 + 485 + A *Mailbox* object has the following properties: 486 + 487 + o id: "Id" (immutable; server-set) 488 + 489 + The id of the Mailbox. 490 + 491 + o name: "String" 492 + 493 + User-visible name for the Mailbox, e.g., "Inbox". This MUST be a 494 + Net-Unicode string [RFC5198] of at least 1 character in length, 495 + subject to the maximum size given in the capability object. There 496 + MUST NOT be two sibling Mailboxes with both the same parent and 497 + the same name. Servers MAY reject names that violate server 498 + policy (e.g., names containing a slash (/) or control characters). 499 + 500 + 501 + 502 + 503 + 504 + 505 + 506 + Jenkins & Newman Standards Track [Page 9] 507 + 508 + RFC 8621 JMAP Mail August 2019 509 + 510 + 511 + o parentId: "Id|null" (default: null) 512 + 513 + The Mailbox id for the parent of this Mailbox, or null if this 514 + Mailbox is at the top level. Mailboxes form acyclic graphs 515 + (forests) directed by the child-to-parent relationship. There 516 + MUST NOT be a loop. 517 + 518 + o role: "String|null" (default: null) 519 + 520 + Identifies Mailboxes that have a particular common purpose (e.g., 521 + the "inbox"), regardless of the "name" property (which may be 522 + localised). 523 + 524 + This value is shared with IMAP (exposed in IMAP via the SPECIAL- 525 + USE extension [RFC6154]). However, unlike in IMAP, a Mailbox MUST 526 + only have a single role, and there MUST NOT be two Mailboxes in 527 + the same account with the same role. Servers providing IMAP 528 + access to the same data are encouraged to enforce these extra 529 + restrictions in IMAP as well. Otherwise, modifying the IMAP 530 + attributes to ensure compliance when exposing the data over JMAP 531 + is implementation dependent. 532 + 533 + The value MUST be one of the Mailbox attribute names listed in the 534 + IANA "IMAP Mailbox Name Attributes" registry at 535 + <https://www.iana.org/assignments/imap-mailbox-name-attributes/>, 536 + as established in [RFC8457], converted to lowercase. New roles 537 + may be established here in the future. 538 + 539 + An account is not required to have Mailboxes with any particular 540 + roles. 541 + 542 + o sortOrder: "UnsignedInt" (default: 0) 543 + 544 + Defines the sort order of Mailboxes when presented in the client's 545 + UI, so it is consistent between devices. The number MUST be an 546 + integer in the range 0 <= sortOrder < 2^31. 547 + 548 + A Mailbox with a lower order should be displayed before a Mailbox 549 + with a higher order (that has the same parent) in any Mailbox 550 + listing in the client's UI. Mailboxes with equal order SHOULD be 551 + sorted in alphabetical order by name. The sorting should take 552 + into account locale-specific character order convention. 553 + 554 + o totalEmails: "UnsignedInt" (server-set) 555 + 556 + The number of Emails in this Mailbox. 557 + 558 + 559 + 560 + 561 + 562 + Jenkins & Newman Standards Track [Page 10] 563 + 564 + RFC 8621 JMAP Mail August 2019 565 + 566 + 567 + o unreadEmails: "UnsignedInt" (server-set) 568 + 569 + The number of Emails in this Mailbox that have neither the "$seen" 570 + keyword nor the "$draft" keyword. 571 + 572 + o totalThreads: "UnsignedInt" (server-set) 573 + 574 + The number of Threads where at least one Email in the Thread is in 575 + this Mailbox. 576 + 577 + o unreadThreads: "UnsignedInt" (server-set) 578 + 579 + An indication of the number of "unread" Threads in the Mailbox. 580 + 581 + For compatibility with existing implementations, the way "unread 582 + Threads" is determined is not mandated in this document. The 583 + simplest solution to implement is simply the number of Threads 584 + where at least one Email in the Thread is both in this Mailbox and 585 + has neither the "$seen" nor "$draft" keywords. 586 + 587 + However, a quality implementation will return the number of unread 588 + items the user would see if they opened that Mailbox. A Thread is 589 + shown as unread if it contains any unread Emails that will be 590 + displayed when the Thread is opened. Therefore, "unreadThreads" 591 + should be the number of Threads where at least one Email in the 592 + Thread has neither the "$seen" nor the "$draft" keyword AND at 593 + least one Email in the Thread is in this Mailbox. Note that the 594 + unread Email does not need to be the one in this Mailbox. In 595 + addition, the trash Mailbox (that is, a Mailbox whose "role" is 596 + "trash") requires special treatment: 597 + 598 + 1. Emails that are *only* in the trash (and no other Mailbox) are 599 + ignored when calculating the "unreadThreads" count of other 600 + Mailboxes. 601 + 602 + 2. Emails that are *not* in the trash are ignored when 603 + calculating the "unreadThreads" count for the trash Mailbox. 604 + 605 + The result of this is that Emails in the trash are treated as 606 + though they are in a separate Thread for the purposes of unread 607 + counts. It is expected that clients will hide Emails in the trash 608 + when viewing a Thread in another Mailbox, and vice versa. This 609 + allows you to delete a single Email to the trash out of a Thread. 610 + 611 + For example, suppose you have an account where the entire contents 612 + is a single Thread with 2 Emails: an unread Email in the trash and 613 + a read Email in the inbox. The "unreadThreads" count would be 1 614 + for the trash and 0 for the inbox. 615 + 616 + 617 + 618 + Jenkins & Newman Standards Track [Page 11] 619 + 620 + RFC 8621 JMAP Mail August 2019 621 + 622 + 623 + o myRights: "MailboxRights" (server-set) 624 + 625 + The set of rights (Access Control Lists (ACLs)) the user has in 626 + relation to this Mailbox. These are backwards compatible with 627 + IMAP ACLs, as defined in [RFC4314]. A *MailboxRights* object has 628 + the following properties: 629 + 630 + * mayReadItems: "Boolean" 631 + 632 + If true, the user may use this Mailbox as part of a filter in 633 + an "Email/query" call, and the Mailbox may be included in the 634 + "mailboxIds" property of Email objects. Email objects may be 635 + fetched if they are in *at least one* Mailbox with this 636 + permission. If a sub-Mailbox is shared but not the parent 637 + Mailbox, this may be false. Corresponds to IMAP ACLs "lr" (if 638 + mapping from IMAP, both are required for this to be true). 639 + 640 + * mayAddItems: "Boolean" 641 + 642 + The user may add mail to this Mailbox (by either creating a new 643 + Email or moving an existing one). Corresponds to IMAP ACL "i". 644 + 645 + * mayRemoveItems: "Boolean" 646 + 647 + The user may remove mail from this Mailbox (by either changing 648 + the Mailboxes of an Email or destroying the Email). 649 + Corresponds to IMAP ACLs "te" (if mapping from IMAP, both are 650 + required for this to be true). 651 + 652 + * maySetSeen: "Boolean" 653 + 654 + The user may add or remove the "$seen" keyword to/from an 655 + Email. If an Email belongs to multiple Mailboxes, the user may 656 + only modify "$seen" if they have this permission for *all* of 657 + the Mailboxes. Corresponds to IMAP ACL "s". 658 + 659 + * maySetKeywords: "Boolean" 660 + 661 + The user may add or remove any keyword other than "$seen" to/ 662 + from an Email. If an Email belongs to multiple Mailboxes, the 663 + user may only modify keywords if they have this permission for 664 + *all* of the Mailboxes. Corresponds to IMAP ACL "w". 665 + 666 + * mayCreateChild: "Boolean" 667 + 668 + The user may create a Mailbox with this Mailbox as its parent. 669 + Corresponds to IMAP ACL "k". 670 + 671 + 672 + 673 + 674 + Jenkins & Newman Standards Track [Page 12] 675 + 676 + RFC 8621 JMAP Mail August 2019 677 + 678 + 679 + * mayRename: "Boolean" 680 + 681 + The user may rename the Mailbox or make it a child of another 682 + Mailbox. Corresponds to IMAP ACL "x" (although this covers 683 + both rename and delete permissions). 684 + 685 + * mayDelete: "Boolean" 686 + 687 + The user may delete the Mailbox itself. Corresponds to IMAP 688 + ACL "x" (although this covers both rename and delete 689 + permissions). 690 + 691 + * maySubmit: "Boolean" 692 + 693 + Messages may be submitted directly to this Mailbox. 694 + Corresponds to IMAP ACL "p". 695 + 696 + o isSubscribed: "Boolean" 697 + 698 + Has the user indicated they wish to see this Mailbox in their 699 + client? This SHOULD default to false for Mailboxes in shared 700 + accounts the user has access to and true for any new Mailboxes 701 + created by the user themself. This MUST be stored separately per 702 + user where multiple users have access to a shared Mailbox. 703 + 704 + A user may have permission to access a large number of shared 705 + accounts, or a shared account with a very large set of Mailboxes, 706 + but only be interested in the contents of a few of these. Clients 707 + may choose to only display Mailboxes where the "isSubscribed" 708 + property is set to true, and offer a separate UI to allow the user 709 + to see and subscribe/unsubscribe from the full set of Mailboxes. 710 + However, clients MAY choose to ignore this property, either 711 + entirely for ease of implementation or just for an account where 712 + "isPersonal" is true (indicating it is the user's own rather than 713 + a shared account). 714 + 715 + This property corresponds to IMAP [RFC3501] mailbox subscriptions. 716 + 717 + For IMAP compatibility, an Email in both the trash and another 718 + Mailbox SHOULD be treated by the client as existing in both places 719 + (i.e., when emptying the trash, the client should just remove it from 720 + the trash Mailbox and leave it in the other Mailbox). 721 + 722 + The following JMAP methods are supported. 723 + 724 + 725 + 726 + 727 + 728 + 729 + 730 + Jenkins & Newman Standards Track [Page 13] 731 + 732 + RFC 8621 JMAP Mail August 2019 733 + 734 + 735 + 2.1. Mailbox/get 736 + 737 + This is a standard "/get" method as described in [RFC8620], 738 + Section 5.1. The "ids" argument may be "null" to fetch all at once. 739 + 740 + 2.2. Mailbox/changes 741 + 742 + This is a standard "/changes" method as described in [RFC8620], 743 + Section 5.2 but with one extra argument to the response: 744 + 745 + o updatedProperties: "String[]|null" 746 + 747 + If only the "totalEmails", "unreadEmails", "totalThreads", and/or 748 + "unreadThreads" Mailbox properties have changed since the old 749 + state, this will be the list of properties that may have changed. 750 + If the server is unable to tell if only counts have changed, it 751 + MUST just be null. 752 + 753 + Since counts frequently change but other properties are generally 754 + only changed rarely, the server can help the client optimise data 755 + transfer by keeping track of changes to Email/Thread counts separate 756 + from other state changes. The "updatedProperties" array may be used 757 + directly via a back-reference in a subsequent "Mailbox/get" call in 758 + the same request, so only these properties are returned if nothing 759 + else has changed. 760 + 761 + 2.3. Mailbox/query 762 + 763 + This is a standard "/query" method as described in [RFC8620], 764 + Section 5.5 but with the following additional request argument: 765 + 766 + o sortAsTree: "Boolean" (default: false) 767 + 768 + If true, when sorting the query results and comparing Mailboxes A 769 + and B: 770 + 771 + * If A is an ancestor of B, it always comes first regardless of 772 + the sort comparators. Similarly, if A is descendant of B, then 773 + B always comes first. 774 + 775 + * Otherwise, if A and B do not share a "parentId", find the 776 + nearest ancestors of each that do have the same "parentId" and 777 + compare the sort properties on those Mailboxes instead. 778 + 779 + The result of this is that the Mailboxes are sorted as a tree 780 + according to the parentId properties, with each set of children 781 + with a common parent sorted according to the standard sort 782 + comparators. 783 + 784 + 785 + 786 + Jenkins & Newman Standards Track [Page 14] 787 + 788 + RFC 8621 JMAP Mail August 2019 789 + 790 + 791 + o filterAsTree: "Boolean" (default: false) 792 + 793 + If true, a Mailbox is only included in the query if all its 794 + ancestors are also included in the query according to the filter. 795 + 796 + A *FilterCondition* object has the following properties, any of which 797 + may be omitted: 798 + 799 + o parentId: "Id|null" 800 + 801 + The Mailbox "parentId" property must match the given value 802 + exactly. 803 + 804 + o name: "String" 805 + 806 + The Mailbox "name" property contains the given string. 807 + 808 + o role: "String|null" 809 + 810 + The Mailbox "role" property must match the given value exactly. 811 + 812 + o hasAnyRole: "Boolean" 813 + 814 + If true, a Mailbox matches if it has any non-null value for its 815 + "role" property. 816 + 817 + o isSubscribed: "Boolean" 818 + 819 + The "isSubscribed" property of the Mailbox must be identical to 820 + the value given to match the condition. 821 + 822 + A Mailbox object matches the FilterCondition if and only if all of 823 + the given conditions match. If zero properties are specified, it is 824 + automatically true for all objects. 825 + 826 + The following Mailbox properties MUST be supported for sorting: 827 + 828 + o "sortOrder" 829 + 830 + o "name" 831 + 832 + 2.4. Mailbox/queryChanges 833 + 834 + This is a standard "/queryChanges" method as described in [RFC8620], 835 + Section 5.6. 836 + 837 + 838 + 839 + 840 + 841 + 842 + Jenkins & Newman Standards Track [Page 15] 843 + 844 + RFC 8621 JMAP Mail August 2019 845 + 846 + 847 + 2.5. Mailbox/set 848 + 849 + This is a standard "/set" method as described in [RFC8620], 850 + Section 5.3 but with the following additional request argument: 851 + 852 + o onDestroyRemoveEmails: "Boolean" (default: false) 853 + 854 + If false, any attempt to destroy a Mailbox that still has Emails 855 + in it will be rejected with a "mailboxHasEmail" SetError. If 856 + true, any Emails that were in the Mailbox will be removed from it, 857 + and if in no other Mailboxes, they will be destroyed when the 858 + Mailbox is destroyed. 859 + 860 + The following extra SetError types are defined: 861 + 862 + For "destroy": 863 + 864 + o "mailboxHasChild": The Mailbox still has at least one child 865 + Mailbox. The client MUST remove these before it can delete the 866 + parent Mailbox. 867 + 868 + o "mailboxHasEmail": The Mailbox has at least one Email assigned to 869 + it, and the "onDestroyRemoveEmails" argument was false. 870 + 871 + 872 + 873 + 874 + 875 + 876 + 877 + 878 + 879 + 880 + 881 + 882 + 883 + 884 + 885 + 886 + 887 + 888 + 889 + 890 + 891 + 892 + 893 + 894 + 895 + 896 + 897 + 898 + Jenkins & Newman Standards Track [Page 16] 899 + 900 + RFC 8621 JMAP Mail August 2019 901 + 902 + 903 + 2.6. Example 904 + 905 + Fetching all Mailboxes in an account: 906 + 907 + [[ "Mailbox/get", { 908 + "accountId": "u33084183", 909 + "ids": null 910 + }, "0" ]] 911 + 912 + And the response: 913 + 914 + [[ "Mailbox/get", { 915 + "accountId": "u33084183", 916 + "state": "78540", 917 + "list": [{ 918 + "id": "MB23cfa8094c0f41e6", 919 + "name": "Inbox", 920 + "parentId": null, 921 + "role": "inbox", 922 + "sortOrder": 10, 923 + "totalEmails": 16307, 924 + "unreadEmails": 13905, 925 + "totalThreads": 5833, 926 + "unreadThreads": 5128, 927 + "myRights": { 928 + "mayAddItems": true, 929 + "mayRename": false, 930 + "maySubmit": true, 931 + "mayDelete": false, 932 + "maySetKeywords": true, 933 + "mayRemoveItems": true, 934 + "mayCreateChild": true, 935 + "maySetSeen": true, 936 + "mayReadItems": true 937 + }, 938 + "isSubscribed": true 939 + }, { 940 + "id": "MB674cc24095db49ce", 941 + "name": "Important mail", 942 + ... 943 + }, ... ], 944 + "notFound": [] 945 + }, "0" ]] 946 + 947 + 948 + 949 + 950 + 951 + 952 + 953 + 954 + Jenkins & Newman Standards Track [Page 17] 955 + 956 + RFC 8621 JMAP Mail August 2019 957 + 958 + 959 + Now suppose an Email is marked read, and we get a push update that 960 + the Mailbox state has changed. You might fetch the updates like 961 + this: 962 + 963 + [[ "Mailbox/changes", { 964 + "accountId": "u33084183", 965 + "sinceState": "78540" 966 + }, "0" ], 967 + [ "Mailbox/get", { 968 + "accountId": "u33084183", 969 + "#ids": { 970 + "resultOf": "0", 971 + "name": "Mailbox/changes", 972 + "path": "/created" 973 + } 974 + }, "1" ], 975 + [ "Mailbox/get", { 976 + "accountId": "u33084183", 977 + "#ids": { 978 + "resultOf": "0", 979 + "name": "Mailbox/changes", 980 + "path": "/updated" 981 + }, 982 + "#properties": { 983 + "resultOf": "0", 984 + "name": "Mailbox/changes", 985 + "path": "/updatedProperties" 986 + } 987 + }, "2" ]] 988 + 989 + 990 + 991 + 992 + 993 + 994 + 995 + 996 + 997 + 998 + 999 + 1000 + 1001 + 1002 + 1003 + 1004 + 1005 + 1006 + 1007 + 1008 + 1009 + 1010 + Jenkins & Newman Standards Track [Page 18] 1011 + 1012 + RFC 8621 JMAP Mail August 2019 1013 + 1014 + 1015 + This fetches the list of ids for created/updated/destroyed Mailboxes, 1016 + then using back-references, it fetches the data for just the created/ 1017 + updated Mailboxes in the same request. The response may look 1018 + something like this: 1019 + 1020 + [[ "Mailbox/changes", { 1021 + "accountId": "u33084183", 1022 + "oldState": "78541", 1023 + "newState": "78542", 1024 + "hasMoreChanges": false, 1025 + "updatedProperties": [ 1026 + "totalEmails", "unreadEmails", 1027 + "totalThreads", "unreadThreads" 1028 + ], 1029 + "created": [], 1030 + "updated": ["MB23cfa8094c0f41e6"], 1031 + "destroyed": [] 1032 + }, "0" ], 1033 + [ "Mailbox/get", { 1034 + "accountId": "u33084183", 1035 + "state": "78542", 1036 + "list": [], 1037 + "notFound": [] 1038 + }, "1" ], 1039 + [ "Mailbox/get", { 1040 + "accountId": "u33084183", 1041 + "state": "78542", 1042 + "list": [{ 1043 + "id": "MB23cfa8094c0f41e6", 1044 + "totalEmails": 16307, 1045 + "unreadEmails": 13903, 1046 + "totalThreads": 5833, 1047 + "unreadThreads": 5127 1048 + }], 1049 + "notFound": [] 1050 + }, "2" ]] 1051 + 1052 + 1053 + 1054 + 1055 + 1056 + 1057 + 1058 + 1059 + 1060 + 1061 + 1062 + 1063 + 1064 + 1065 + 1066 + Jenkins & Newman Standards Track [Page 19] 1067 + 1068 + RFC 8621 JMAP Mail August 2019 1069 + 1070 + 1071 + Here's an example where we try to rename one Mailbox and destroy 1072 + another: 1073 + 1074 + [[ "Mailbox/set", { 1075 + "accountId": "u33084183", 1076 + "ifInState": "78542", 1077 + "update": { 1078 + "MB674cc24095db49ce": { 1079 + "name": "Maybe important mail" 1080 + } 1081 + }, 1082 + "destroy": [ "MB23cfa8094c0f41e6" ] 1083 + }, "0" ]] 1084 + 1085 + Suppose the rename succeeds, but we don't have permission to destroy 1086 + the Mailbox we tried to destroy; we might get back: 1087 + 1088 + [[ "Mailbox/set", { 1089 + "accountId": "u33084183", 1090 + "oldState": "78542", 1091 + "newState": "78549", 1092 + "updated": { 1093 + "MB674cc24095db49ce": null 1094 + }, 1095 + "notDestroyed": { 1096 + "MB23cfa8094c0f41e6": { 1097 + "type": "forbidden" 1098 + } 1099 + } 1100 + }, "0" ]] 1101 + 1102 + 3. Threads 1103 + 1104 + Replies are grouped together with the original message to form a 1105 + Thread. In JMAP, a Thread is simply a flat list of Emails, ordered 1106 + by date. Every Email MUST belong to a Thread, even if it is the only 1107 + Email in the Thread. 1108 + 1109 + The exact algorithm for determining whether two Emails belong to the 1110 + same Thread is not mandated in this spec to allow for compatibility 1111 + with different existing systems. For new implementations, it is 1112 + suggested that two messages belong in the same Thread if both of the 1113 + following conditions apply: 1114 + 1115 + 1. An identical message id [RFC5322] appears in both messages in any 1116 + of the Message-Id, In-Reply-To, and References header fields. 1117 + 1118 + 1119 + 1120 + 1121 + 1122 + Jenkins & Newman Standards Track [Page 20] 1123 + 1124 + RFC 8621 JMAP Mail August 2019 1125 + 1126 + 1127 + 2. After stripping automatically added prefixes such as "Fwd:", 1128 + "Re:", "[List-Tag]", etc., and ignoring white space, the subjects 1129 + are the same. This avoids the situation where a person replies 1130 + to an old message as a convenient way of finding the right 1131 + recipient to send to but changes the subject and starts a new 1132 + conversation. 1133 + 1134 + If messages are delivered out of order for some reason, a user may 1135 + have two Emails in the same Thread but without headers that associate 1136 + them with each other. The arrival of a third Email may provide the 1137 + missing references to join them all together into a single Thread. 1138 + Since the "threadId" of an Email is immutable, if the server wishes 1139 + to merge the Threads, it MUST handle this by deleting and reinserting 1140 + (with a new Email id) the Emails that change "threadId". 1141 + 1142 + A *Thread* object has the following properties: 1143 + 1144 + o id: "Id" (immutable; server-set) 1145 + 1146 + 1147 + The id of the Thread. 1148 + 1149 + o emailIds: "Id[]" (server-set) 1150 + 1151 + The ids of the Emails in the Thread, sorted by the "receivedAt" 1152 + date of the Email, oldest first. If two Emails have an identical 1153 + date, the sort is server dependent but MUST be stable (sorting by 1154 + id is recommended). 1155 + 1156 + The following JMAP methods are supported. 1157 + 1158 + 1159 + 1160 + 1161 + 1162 + 1163 + 1164 + 1165 + 1166 + 1167 + 1168 + 1169 + 1170 + 1171 + 1172 + 1173 + 1174 + 1175 + 1176 + 1177 + 1178 + Jenkins & Newman Standards Track [Page 21] 1179 + 1180 + RFC 8621 JMAP Mail August 2019 1181 + 1182 + 1183 + 3.1. Thread/get 1184 + 1185 + This is a standard "/get" method as described in [RFC8620], 1186 + Section 5.1. 1187 + 1188 + 3.1.1. Example 1189 + 1190 + Request: 1191 + 1192 + [[ "Thread/get", { 1193 + "accountId": "acme", 1194 + "ids": ["f123u4", "f41u44"] 1195 + }, "#1" ]] 1196 + 1197 + with response: 1198 + 1199 + [[ "Thread/get", { 1200 + "accountId": "acme", 1201 + "state": "f6a7e214", 1202 + "list": [ 1203 + { 1204 + "id": "f123u4", 1205 + "emailIds": [ "eaa623", "f782cbb"] 1206 + }, 1207 + { 1208 + "id": "f41u44", 1209 + "emailIds": [ "82cf7bb" ] 1210 + } 1211 + ], 1212 + "notFound": [] 1213 + }, "#1" ]] 1214 + 1215 + 3.2. Thread/changes 1216 + 1217 + This is a standard "/changes" method as described in [RFC8620], 1218 + Section 5.2. 1219 + 1220 + 4. Emails 1221 + 1222 + An *Email* object is a representation of a message [RFC5322], which 1223 + allows clients to avoid the complexities of MIME parsing, transfer 1224 + encoding, and character encoding. 1225 + 1226 + 1227 + 1228 + 1229 + 1230 + 1231 + 1232 + 1233 + 1234 + Jenkins & Newman Standards Track [Page 22] 1235 + 1236 + RFC 8621 JMAP Mail August 2019 1237 + 1238 + 1239 + 4.1. Properties of the Email Object 1240 + 1241 + Broadly, a message consists of two parts: a list of header fields and 1242 + then a body. The Email data type provides a way to access the full 1243 + structure or to use simplified properties and avoid some complexity 1244 + if this is sufficient for the client application. 1245 + 1246 + While raw headers can be fetched and set, the vast majority of 1247 + clients should use an appropriate parsed form for each of the header 1248 + fields it wants to process, as this allows it to avoid the 1249 + complexities of various encodings that are required in a valid 1250 + message per RFC 5322. 1251 + 1252 + The body of a message is normally a MIME-encoded set of documents in 1253 + a tree structure. This may be arbitrarily nested, but the majority 1254 + of email clients present a flat model of a message body (normally 1255 + plaintext or HTML) with a set of attachments. Flattening the MIME 1256 + structure to form this model can be difficult and causes 1257 + inconsistency between clients. Therefore, in addition to the 1258 + "bodyStructure" property, which gives the full tree, the Email object 1259 + contains 3 alternate properties with flat lists of body parts: 1260 + 1261 + o "textBody"/"htmlBody": These provide a list of parts that should 1262 + be rendered sequentially as the "body" of the message. This is a 1263 + list rather than a single part as messages may have headers and/or 1264 + footers appended/prepended as separate parts when they are 1265 + transmitted, and some clients send text and images intended to be 1266 + displayed inline in the body (or even videos and sound clips) as 1267 + multiple parts rather than a single HTML part with referenced 1268 + images. 1269 + 1270 + Because MIME allows for multiple representations of the same data 1271 + (using "multipart/alternative"), there is a "textBody" property 1272 + (which prefers a plaintext representation) and an "htmlBody" 1273 + property (which prefers an HTML representation) to accommodate the 1274 + two most common client requirements. The same part may appear in 1275 + both lists where there is no alternative between the two. 1276 + 1277 + o "attachments": This provides a list of parts that should be 1278 + presented as "attachments" to the message. Some images may be 1279 + solely there for embedding within an HTML body part; clients may 1280 + wish to not present these as attachments in the user interface if 1281 + they are displaying the HTML with the embedded images directly. 1282 + Some parts may also be in htmlBody/textBody; again, clients may 1283 + wish to not present these as attachments in the user interface if 1284 + rendered as part of the body. 1285 + 1286 + 1287 + 1288 + 1289 + 1290 + Jenkins & Newman Standards Track [Page 23] 1291 + 1292 + RFC 8621 JMAP Mail August 2019 1293 + 1294 + 1295 + The "bodyValues" property allows for clients to fetch the value of 1296 + text parts directly without having to do a second request for the 1297 + blob and to have the server handle decoding the charset into unicode. 1298 + This data is in a separate property rather than on the EmailBodyPart 1299 + object to avoid duplication of large amounts of data, as the same 1300 + part may be included twice if the client fetches more than one of 1301 + bodyStructure, textBody, and htmlBody. 1302 + 1303 + In the following subsections, the common notational convention for 1304 + wildcards has been adopted for content types, so "foo/*" means any 1305 + content type that starts with "foo/". 1306 + 1307 + Due to the number of properties involved, the set of Email properties 1308 + is specified over the following four subsections. This is purely for 1309 + readability; all properties are top-level peers. 1310 + 1311 + 4.1.1. Metadata 1312 + 1313 + These properties represent metadata about the message in the mail 1314 + store and are not derived from parsing the message itself. 1315 + 1316 + o id: "Id" (immutable; server-set) 1317 + 1318 + The id of the Email object. Note that this is the JMAP object id, 1319 + NOT the Message-ID header field value of the message [RFC5322]. 1320 + 1321 + o blobId: "Id" (immutable; server-set) 1322 + 1323 + The id representing the raw octets of the message [RFC5322] for 1324 + this Email. This may be used to download the raw original message 1325 + or to attach it directly to another Email, etc. 1326 + 1327 + o threadId: "Id" (immutable; server-set) 1328 + 1329 + The id of the Thread to which this Email belongs. 1330 + 1331 + o mailboxIds: "Id[Boolean]" 1332 + 1333 + The set of Mailbox ids this Email belongs to. An Email in the 1334 + mail store MUST belong to one or more Mailboxes at all times 1335 + (until it is destroyed). The set is represented as an object, 1336 + with each key being a Mailbox id. The value for each key in the 1337 + object MUST be true. 1338 + 1339 + 1340 + 1341 + 1342 + 1343 + 1344 + 1345 + 1346 + Jenkins & Newman Standards Track [Page 24] 1347 + 1348 + RFC 8621 JMAP Mail August 2019 1349 + 1350 + 1351 + o keywords: "String[Boolean]" (default: {}) 1352 + 1353 + A set of keywords that apply to the Email. The set is represented 1354 + as an object, with the keys being the keywords. The value for 1355 + each key in the object MUST be true. 1356 + 1357 + Keywords are shared with IMAP. The six system keywords from IMAP 1358 + get special treatment. The following four keywords have their 1359 + first character changed from "\" in IMAP to "$" in JMAP and have 1360 + particular semantic meaning: 1361 + 1362 + * "$draft": The Email is a draft the user is composing. 1363 + 1364 + * "$seen": The Email has been read. 1365 + 1366 + * "$flagged": The Email has been flagged for urgent/special 1367 + attention. 1368 + 1369 + * "$answered": The Email has been replied to. 1370 + 1371 + The IMAP "\Recent" keyword is not exposed via JMAP. The IMAP 1372 + "\Deleted" keyword is also not present: IMAP uses a delete+expunge 1373 + model, which JMAP does not. Any message with the "\Deleted" 1374 + keyword MUST NOT be visible via JMAP (and so are not counted in 1375 + the "totalEmails", "unreadEmails", "totalThreads", and 1376 + "unreadThreads" Mailbox properties). 1377 + 1378 + Users may add arbitrary keywords to an Email. For compatibility 1379 + with IMAP, a keyword is a case-insensitive string of 1-255 1380 + characters in the ASCII subset %x21-%x7e (excludes control chars 1381 + and space), and it MUST NOT include any of these characters: 1382 + 1383 + ( ) { ] % * " \ 1384 + 1385 + Because JSON is case sensitive, servers MUST return keywords in 1386 + lowercase. 1387 + 1388 + The IANA "IMAP and JMAP Keywords" registry at 1389 + <https://www.iana.org/assignments/imap-jmap-keywords/> as 1390 + established in [RFC5788] assigns semantic meaning to some other 1391 + keywords in common use. New keywords may be established here in 1392 + the future. In particular, note: 1393 + 1394 + * "$forwarded": The Email has been forwarded. 1395 + 1396 + * "$phishing": The Email is highly likely to be phishing. 1397 + Clients SHOULD warn users to take care when viewing this Email 1398 + and disable links and attachments. 1399 + 1400 + 1401 + 1402 + Jenkins & Newman Standards Track [Page 25] 1403 + 1404 + RFC 8621 JMAP Mail August 2019 1405 + 1406 + 1407 + * "$junk": The Email is definitely spam. Clients SHOULD set this 1408 + flag when users report spam to help train automated spam- 1409 + detection systems. 1410 + 1411 + * "$notjunk": The Email is definitely not spam. Clients SHOULD 1412 + set this flag when users indicate an Email is legitimate, to 1413 + help train automated spam-detection systems. 1414 + 1415 + o size: "UnsignedInt" (immutable; server-set) 1416 + 1417 + The size, in octets, of the raw data for the message [RFC5322] (as 1418 + referenced by the "blobId", i.e., the number of octets in the file 1419 + the user would download). 1420 + 1421 + o receivedAt: "UTCDate" (immutable; default: time of creation on 1422 + server) 1423 + 1424 + The date the Email was received by the message store. This is the 1425 + "internal date" in IMAP [RFC3501]. 1426 + 1427 + 4.1.2. Header Fields Parsed Forms 1428 + 1429 + Header field properties are derived from the message header fields 1430 + [RFC5322] [RFC6532]. All header fields may be fetched in a raw form. 1431 + Some header fields may also be fetched in a parsed form. The 1432 + structured form that may be fetched depends on the header. The forms 1433 + are defined in the subsections that follow. 1434 + 1435 + 4.1.2.1. Raw 1436 + 1437 + Type: "String" 1438 + 1439 + The raw octets of the header field value from the first octet 1440 + following the header field name terminating colon, up to but 1441 + excluding the header field terminating CRLF. Any standards-compliant 1442 + message MUST be either ASCII (RFC 5322) or UTF-8 (RFC 6532); however, 1443 + other encodings exist in the wild. A server SHOULD replace any octet 1444 + or octet run with the high bit set that violates UTF-8 syntax with 1445 + the unicode replacement character (U+FFFD). Any NUL octet MUST be 1446 + dropped. 1447 + 1448 + This form will typically have a leading space, as most generated 1449 + messages insert a space after the colon that terminates the header 1450 + field name. 1451 + 1452 + 1453 + 1454 + 1455 + 1456 + 1457 + 1458 + Jenkins & Newman Standards Track [Page 26] 1459 + 1460 + RFC 8621 JMAP Mail August 2019 1461 + 1462 + 1463 + 4.1.2.2. Text 1464 + 1465 + Type: "String" 1466 + 1467 + The header field value with: 1468 + 1469 + 1. White space unfolded (as defined in [RFC5322], Section 2.2.3). 1470 + 1471 + 2. The terminating CRLF at the end of the value removed. 1472 + 1473 + 3. Any SP characters at the beginning of the value removed. 1474 + 1475 + 4. Any syntactically correct encoded sections [RFC2047] with a known 1476 + character set decoded. Any NUL octets or control characters 1477 + encoded per [RFC2047] are dropped from the decoded value. Any 1478 + text that looks like syntax per [RFC2047] but violates placement 1479 + or white space rules per [RFC2047] MUST NOT be decoded. 1480 + 1481 + 5. The resulting unicode converted to Normalization Form C (NFC) 1482 + form. 1483 + 1484 + If any decodings fail, the parser SHOULD insert a unicode replacement 1485 + character (U+FFFD) and attempt to continue as much as possible. 1486 + 1487 + To prevent obviously nonsense behaviour, which can lead to 1488 + interoperability issues, this form may only be fetched or set for the 1489 + following header fields: 1490 + 1491 + o Subject 1492 + 1493 + o Comments 1494 + 1495 + o Keywords 1496 + 1497 + o List-Id 1498 + 1499 + o Any header field not defined in [RFC5322] or [RFC2369] 1500 + 1501 + 4.1.2.3. Addresses 1502 + 1503 + Type: "EmailAddress[]" 1504 + 1505 + The header field is parsed as an "address-list" value, as specified 1506 + in [RFC5322], Section 3.4, into the "EmailAddress[]" type. There is 1507 + an EmailAddress item for each "mailbox" parsed from the "address- 1508 + list". Group and comment information is discarded. 1509 + 1510 + 1511 + 1512 + 1513 + 1514 + Jenkins & Newman Standards Track [Page 27] 1515 + 1516 + RFC 8621 JMAP Mail August 2019 1517 + 1518 + 1519 + An *EmailAddress* object has the following properties: 1520 + 1521 + o name: "String|null" 1522 + 1523 + The "display-name" of the "mailbox" [RFC5322]. If this is a 1524 + "quoted-string": 1525 + 1526 + 1. The surrounding DQUOTE characters are removed. 1527 + 1528 + 2. Any "quoted-pair" is decoded. 1529 + 1530 + 3. White space is unfolded, and then any leading and trailing 1531 + white space is removed. 1532 + 1533 + If there is no "display-name" but there is a "comment" immediately 1534 + following the "addr-spec", the value of this SHOULD be used 1535 + instead. Otherwise, this property is null. 1536 + 1537 + o email: "String" 1538 + 1539 + The "addr-spec" of the "mailbox" [RFC5322]. 1540 + 1541 + Any syntactically correct encoded sections [RFC2047] with a known 1542 + encoding MUST be decoded, following the same rules as for the Text 1543 + form (see Section 4.1.2.2). 1544 + 1545 + Parsing SHOULD be best effort in the face of invalid structure to 1546 + accommodate invalid messages and semi-complete drafts. EmailAddress 1547 + objects MAY have an "email" property that does not conform to the 1548 + "addr-spec" form (for example, may not contain an @ symbol). 1549 + 1550 + For example, the following "address-list" string: 1551 + 1552 + " James Smythe" <james@example.com>, Friends: 1553 + jane@example.com, =?UTF-8?Q?John_Sm=C3=AEth?= 1554 + <john@example.com>; 1555 + 1556 + would be parsed as: 1557 + 1558 + [ 1559 + { "name": "James Smythe", "email": "james@example.com" }, 1560 + { "name": null, "email": "jane@example.com" }, 1561 + { "name": "John Smith", "email": "john@example.com" } 1562 + ] 1563 + 1564 + 1565 + 1566 + 1567 + 1568 + 1569 + 1570 + Jenkins & Newman Standards Track [Page 28] 1571 + 1572 + RFC 8621 JMAP Mail August 2019 1573 + 1574 + 1575 + To prevent obviously nonsense behaviour, which can lead to 1576 + interoperability issues, this form may only be fetched or set for the 1577 + following header fields: 1578 + 1579 + o From 1580 + 1581 + o Sender 1582 + 1583 + o Reply-To 1584 + 1585 + o To 1586 + 1587 + o Cc 1588 + 1589 + o Bcc 1590 + 1591 + o Resent-From 1592 + 1593 + o Resent-Sender 1594 + 1595 + o Resent-Reply-To 1596 + 1597 + o Resent-To 1598 + 1599 + o Resent-Cc 1600 + 1601 + o Resent-Bcc 1602 + 1603 + o Any header field not defined in [RFC5322] or [RFC2369] 1604 + 1605 + 4.1.2.4. GroupedAddresses 1606 + 1607 + Type: "EmailAddressGroup[]" 1608 + 1609 + This is similar to the Addresses form but preserves group 1610 + information. The header field is parsed as an "address-list" value, 1611 + as specified in [RFC5322], Section 3.4, into the "GroupedAddresses[]" 1612 + type. Consecutive "mailbox" values that are not part of a group are 1613 + still collected under an EmailAddressGroup object to provide a 1614 + uniform type. 1615 + 1616 + 1617 + 1618 + 1619 + 1620 + 1621 + 1622 + 1623 + 1624 + 1625 + 1626 + Jenkins & Newman Standards Track [Page 29] 1627 + 1628 + RFC 8621 JMAP Mail August 2019 1629 + 1630 + 1631 + An *EmailAddressGroup* object has the following properties: 1632 + 1633 + o name: "String|null" 1634 + 1635 + The "display-name" of the "group" [RFC5322], or null if the 1636 + addresses are not part of a group. If this is a "quoted-string", 1637 + it is processed the same as the "name" in the EmailAddress type. 1638 + 1639 + o addresses: "EmailAddress[]" 1640 + 1641 + The "mailbox" values that belong to this group, represented as 1642 + EmailAddress objects. 1643 + 1644 + Any syntactically correct encoded sections [RFC2047] with a known 1645 + encoding MUST be decoded, following the same rules as for the Text 1646 + form (see Section 4.1.2.2). 1647 + 1648 + Parsing SHOULD be best effort in the face of invalid structure to 1649 + accommodate invalid messages and semi-complete drafts. 1650 + 1651 + For example, the following "address-list" string: 1652 + 1653 + " James Smythe" <james@example.com>, Friends: 1654 + jane@example.com, =?UTF-8?Q?John_Sm=C3=AEth?= 1655 + <john@example.com>; 1656 + 1657 + would be parsed as: 1658 + 1659 + [ 1660 + { "name": null, "addresses": [ 1661 + { "name": "James Smythe", "email": "james@example.com" } 1662 + ]}, 1663 + { "name": "Friends", "addresses": [ 1664 + { "name": null, "email": "jane@example.com" }, 1665 + { "name": "John Smith", "email": "john@example.com" } 1666 + ]} 1667 + ] 1668 + 1669 + To prevent obviously nonsense behaviour, which can lead to 1670 + interoperability issues, this form may only be fetched or set for the 1671 + same header fields as the Addresses form (see Section 4.1.2.3). 1672 + 1673 + 1674 + 1675 + 1676 + 1677 + 1678 + 1679 + 1680 + 1681 + 1682 + Jenkins & Newman Standards Track [Page 30] 1683 + 1684 + RFC 8621 JMAP Mail August 2019 1685 + 1686 + 1687 + 4.1.2.5. MessageIds 1688 + 1689 + Type: "String[]|null" 1690 + 1691 + The header field is parsed as a list of "msg-id" values, as specified 1692 + in [RFC5322], Section 3.6.4, into the "String[]" type. Comments and/ 1693 + or folding white space (CFWS) and surrounding angle brackets ("<>") 1694 + are removed. If parsing fails, the value is null. 1695 + 1696 + To prevent obviously nonsense behaviour, which can lead to 1697 + interoperability issues, this form may only be fetched or set for the 1698 + following header fields: 1699 + 1700 + o Message-ID 1701 + 1702 + o In-Reply-To 1703 + 1704 + o References 1705 + 1706 + o Resent-Message-ID 1707 + 1708 + o Any header field not defined in [RFC5322] or [RFC2369] 1709 + 1710 + 4.1.2.6. Date 1711 + 1712 + Type: "Date|null" 1713 + 1714 + The header field is parsed as a "date-time" value, as specified in 1715 + [RFC5322], Section 3.3, into the "Date" type. If parsing fails, the 1716 + value is null. 1717 + 1718 + To prevent obviously nonsense behaviour, which can lead to 1719 + interoperability issues, this form may only be fetched or set for the 1720 + following header fields: 1721 + 1722 + o Date 1723 + 1724 + o Resent-Date 1725 + 1726 + o Any header field not defined in [RFC5322] or [RFC2369] 1727 + 1728 + 1729 + 1730 + 1731 + 1732 + 1733 + 1734 + 1735 + 1736 + 1737 + 1738 + Jenkins & Newman Standards Track [Page 31] 1739 + 1740 + RFC 8621 JMAP Mail August 2019 1741 + 1742 + 1743 + 4.1.2.7. URLs 1744 + 1745 + Type: "String[]|null" 1746 + 1747 + The header field is parsed as a list of URLs, as described in 1748 + [RFC2369], into the "String[]" type. Values do not include the 1749 + surrounding angle brackets or any comments in the header field with 1750 + the URLs. If parsing fails, the value is null. 1751 + 1752 + To prevent obviously nonsense behaviour, which can lead to 1753 + interoperability issues, this form may only be fetched or set for the 1754 + following header fields: 1755 + 1756 + o List-Help 1757 + 1758 + o List-Unsubscribe 1759 + 1760 + o List-Subscribe 1761 + 1762 + o List-Post 1763 + 1764 + o List-Owner 1765 + 1766 + o List-Archive 1767 + 1768 + o Any header field not defined in [RFC5322] or [RFC2369] 1769 + 1770 + 4.1.3. Header Fields Properties 1771 + 1772 + The following low-level Email property is specified for complete 1773 + access to the header data of the message: 1774 + 1775 + o headers: "EmailHeader[]" (immutable) 1776 + 1777 + This is a list of all header fields [RFC5322], in the same order 1778 + they appear in the message. An *EmailHeader* object has the 1779 + following properties: 1780 + 1781 + * name: "String" 1782 + 1783 + The header "field name" as defined in [RFC5322], with the same 1784 + capitalization that it has in the message. 1785 + 1786 + * value: "String" 1787 + 1788 + The header "field value" as defined in [RFC5322], in Raw form. 1789 + 1790 + 1791 + 1792 + 1793 + 1794 + Jenkins & Newman Standards Track [Page 32] 1795 + 1796 + RFC 8621 JMAP Mail August 2019 1797 + 1798 + 1799 + In addition, the client may request/send properties representing 1800 + individual header fields of the form: 1801 + 1802 + header:{header-field-name} 1803 + 1804 + Where "{header-field-name}" means any series of one or more printable 1805 + ASCII characters (i.e., characters that have values between 33 and 1806 + 126, inclusive), except for colon (:). The property may also have 1807 + the following suffixes: 1808 + 1809 + o :as{header-form} 1810 + 1811 + This means the value is in a parsed form, where "{header-form}" is 1812 + one of the parsed-form names specified above. If not given, the 1813 + value is in Raw form. 1814 + 1815 + o :all 1816 + 1817 + This means the value is an array, with the items corresponding to 1818 + each instance of the header field, in the order they appear in the 1819 + message. If this suffix is not used, the result is the value of 1820 + the *last* instance of the header field (i.e., identical to the 1821 + last item in the array if :all is used), or null if none. 1822 + 1823 + If both suffixes are used, they MUST be specified in the order above. 1824 + Header field names are matched case insensitively. The value is 1825 + typed according to the requested form or to an array of that type if 1826 + :all is used. If no header fields exist in the message with the 1827 + requested name, the value is null if fetching a single instance or an 1828 + empty array if requesting :all. 1829 + 1830 + As a simple example, if the client requests a property called 1831 + "header:subject", this means find the *last* header field in the 1832 + message named "subject" (matched case insensitively) and return the 1833 + value in Raw form, or null if no header field of this name is found. 1834 + 1835 + For a more complex example, consider the client requesting a property 1836 + called "header:Resent-To:asAddresses:all". This means: 1837 + 1838 + 1. Find *all* header fields named Resent-To (matched case 1839 + insensitively). 1840 + 1841 + 2. For each instance, parse the header field value in the Addresses 1842 + form. 1843 + 1844 + 3. The result is of type "EmailAddress[][]" -- each item in the 1845 + array corresponds to the parsed value (which is itself an array) 1846 + of the Resent-To header field instance. 1847 + 1848 + 1849 + 1850 + Jenkins & Newman Standards Track [Page 33] 1851 + 1852 + RFC 8621 JMAP Mail August 2019 1853 + 1854 + 1855 + The following convenience properties are also specified for the Email 1856 + object: 1857 + 1858 + o messageId: "String[]|null" (immutable) 1859 + 1860 + The value is identical to the value of "header:Message- 1861 + ID:asMessageIds". For messages conforming to RFC 5322, this will 1862 + be an array with a single entry. 1863 + 1864 + o inReplyTo: "String[]|null" (immutable) 1865 + 1866 + The value is identical to the value of "header:In-Reply- 1867 + To:asMessageIds". 1868 + 1869 + o references: "String[]|null" (immutable) 1870 + 1871 + The value is identical to the value of 1872 + "header:References:asMessageIds". 1873 + 1874 + o sender: "EmailAddress[]|null" (immutable) 1875 + 1876 + The value is identical to the value of 1877 + "header:Sender:asAddresses". 1878 + 1879 + o from: "EmailAddress[]|null" (immutable) 1880 + 1881 + The value is identical to the value of "header:From:asAddresses". 1882 + 1883 + o to: "EmailAddress[]|null" (immutable) 1884 + 1885 + The value is identical to the value of "header:To:asAddresses". 1886 + 1887 + o cc: "EmailAddress[]|null" (immutable) 1888 + 1889 + The value is identical to the value of "header:Cc:asAddresses". 1890 + 1891 + o bcc: "EmailAddress[]|null" (immutable) 1892 + 1893 + The value is identical to the value of "header:Bcc:asAddresses". 1894 + 1895 + o replyTo: "EmailAddress[]|null" (immutable) 1896 + 1897 + The value is identical to the value of "header:Reply- 1898 + To:asAddresses". 1899 + 1900 + o subject: "String|null" (immutable) 1901 + 1902 + The value is identical to the value of "header:Subject:asText". 1903 + 1904 + 1905 + 1906 + Jenkins & Newman Standards Track [Page 34] 1907 + 1908 + RFC 8621 JMAP Mail August 2019 1909 + 1910 + 1911 + o sentAt: "Date|null" (immutable; default on creation: current 1912 + server time) 1913 + 1914 + The value is identical to the value of "header:Date:asDate". 1915 + 1916 + 4.1.4. Body Parts 1917 + 1918 + These properties are derived from the message body [RFC5322] and its 1919 + MIME entities [RFC2045]. 1920 + 1921 + An *EmailBodyPart* object has the following properties: 1922 + 1923 + o partId: "String|null" 1924 + 1925 + Identifies this part uniquely within the Email. This is scoped to 1926 + the "emailId" and has no meaning outside of the JMAP Email object 1927 + representation. This is null if, and only if, the part is of type 1928 + "multipart/*". 1929 + 1930 + o blobId: "Id|null" 1931 + 1932 + The id representing the raw octets of the contents of the part, 1933 + after decoding any known Content-Transfer-Encoding (as defined in 1934 + [RFC2045]), or null if, and only if, the part is of type 1935 + "multipart/*". Note that two parts may be transfer-encoded 1936 + differently but have the same blob id if their decoded octets are 1937 + identical and the server is using a secure hash of the data for 1938 + the blob id. If the transfer encoding is unknown, it is treated 1939 + as though it had no transfer encoding. 1940 + 1941 + o size: "UnsignedInt" 1942 + 1943 + The size, in octets, of the raw data after content transfer 1944 + decoding (as referenced by the "blobId", i.e., the number of 1945 + octets in the file the user would download). 1946 + 1947 + o headers: "EmailHeader[]" 1948 + 1949 + This is a list of all header fields in the part, in the order they 1950 + appear in the message. The values are in Raw form. 1951 + 1952 + o name: "String|null" 1953 + 1954 + This is the decoded "filename" parameter of the Content- 1955 + Disposition header field per [RFC2231], or (for compatibility with 1956 + existing systems) if not present, then it's the decoded "name" 1957 + parameter of the Content-Type header field per [RFC2047]. 1958 + 1959 + 1960 + 1961 + 1962 + Jenkins & Newman Standards Track [Page 35] 1963 + 1964 + RFC 8621 JMAP Mail August 2019 1965 + 1966 + 1967 + o type: "String" 1968 + 1969 + The value of the Content-Type header field of the part, if 1970 + present; otherwise, the implicit type as per the MIME standard 1971 + ("text/plain" or "message/rfc822" if inside a "multipart/digest"). 1972 + CFWS is removed and any parameters are stripped. 1973 + 1974 + o charset: "String|null" 1975 + 1976 + The value of the charset parameter of the Content-Type header 1977 + field, if present, or null if the header field is present but not 1978 + of type "text/*". If there is no Content-Type header field, or it 1979 + exists and is of type "text/*" but has no charset parameter, this 1980 + is the implicit charset as per the MIME standard: "us-ascii". 1981 + 1982 + o disposition: "String|null" 1983 + 1984 + The value of the Content-Disposition header field of the part, if 1985 + present; otherwise, it's null. CFWS is removed and any parameters 1986 + are stripped. 1987 + 1988 + o cid: "String|null" 1989 + 1990 + The value of the Content-Id header field of the part, if present; 1991 + otherwise, it's null. CFWS and surrounding angle brackets ("<>") 1992 + are removed. This may be used to reference the content from 1993 + within a "text/html" body part [HTML] using the "cid:" protocol, 1994 + as defined in [RFC2392]. 1995 + 1996 + o language: "String[]|null" 1997 + 1998 + The list of language tags, as defined in [RFC3282], in the 1999 + Content-Language header field of the part, if present. 2000 + 2001 + o location: "String|null" 2002 + 2003 + The URI, as defined in [RFC2557], in the Content-Location header 2004 + field of the part, if present. 2005 + 2006 + o subParts: "EmailBodyPart[]|null" 2007 + 2008 + If the type is "multipart/*", this contains the body parts of each 2009 + child. 2010 + 2011 + In addition, the client may request/send EmailBodyPart properties 2012 + representing individual header fields, following the same syntax and 2013 + semantics as for the Email object, e.g., "header:Content-Type". 2014 + 2015 + 2016 + 2017 + 2018 + Jenkins & Newman Standards Track [Page 36] 2019 + 2020 + RFC 8621 JMAP Mail August 2019 2021 + 2022 + 2023 + The following Email properties are specified for access to the body 2024 + data of the message: 2025 + 2026 + o bodyStructure: "EmailBodyPart" (immutable) 2027 + 2028 + This is the full MIME structure of the message body, without 2029 + recursing into "message/rfc822" or "message/global" parts. Note 2030 + that EmailBodyParts may have subParts if they are of type 2031 + "multipart/*". 2032 + 2033 + o bodyValues: "String[EmailBodyValue]" (immutable) 2034 + 2035 + This is a map of "partId" to an EmailBodyValue object for none, 2036 + some, or all "text/*" parts. Which parts are included and whether 2037 + the value is truncated is determined by various arguments to 2038 + "Email/get" and "Email/parse". An *EmailBodyValue* object has the 2039 + following properties: 2040 + 2041 + * value: "String" 2042 + 2043 + The value of the body part after decoding Content-Transfer- 2044 + Encoding and the Content-Type charset, if both known to the 2045 + server, and with any CRLF replaced with a single LF. The 2046 + server MAY use heuristics to determine the charset to use for 2047 + decoding if the charset is unknown, no charset is given, or it 2048 + believes the charset given is incorrect. Decoding is best 2049 + effort; the server SHOULD insert the unicode replacement 2050 + character (U+FFFD) and continue when a malformed section is 2051 + encountered. 2052 + 2053 + Note that due to the charset decoding and line ending 2054 + normalisation, the length of this string will probably not be 2055 + exactly the same as the "size" property on the corresponding 2056 + EmailBodyPart. 2057 + 2058 + * isEncodingProblem: "Boolean" (default: false) 2059 + 2060 + This is true if malformed sections were found while decoding 2061 + the charset, the charset was unknown, or the content-transfer- 2062 + encoding was unknown. 2063 + 2064 + * isTruncated: "Boolean" (default: false) 2065 + 2066 + This is true if the "value" has been truncated. 2067 + 2068 + See the Security Considerations section for issues related to 2069 + truncation and heuristic determination of the content-type and 2070 + charset. 2071 + 2072 + 2073 + 2074 + Jenkins & Newman Standards Track [Page 37] 2075 + 2076 + RFC 8621 JMAP Mail August 2019 2077 + 2078 + 2079 + o textBody: "EmailBodyPart[]" (immutable) 2080 + 2081 + A list of "text/plain", "text/html", "image/*", "audio/*", and/or 2082 + "video/*" parts to display (sequentially) as the message body, 2083 + with a preference for "text/plain" when alternative versions are 2084 + available. 2085 + 2086 + o htmlBody: "EmailBodyPart[]" (immutable) 2087 + 2088 + A list of "text/plain", "text/html", "image/*", "audio/*", and/or 2089 + "video/*" parts to display (sequentially) as the message body, 2090 + with a preference for "text/html" when alternative versions are 2091 + available. 2092 + 2093 + o attachments: "EmailBodyPart[]" (immutable) 2094 + 2095 + A list, traversing depth-first, of all parts in "bodyStructure" 2096 + that satisfy either of the following conditions: 2097 + 2098 + * not of type "multipart/*" and not included in "textBody" or 2099 + "htmlBody" 2100 + 2101 + * of type "image/*", "audio/*", or "video/*" and not in both 2102 + "textBody" and "htmlBody" 2103 + 2104 + None of these parts include subParts, including "message/*" types. 2105 + Attached messages may be fetched using the "Email/parse" method 2106 + and the "blobId". 2107 + 2108 + Note that a "text/html" body part [HTML] may reference image parts 2109 + in attachments by using "cid:" links to reference the Content-Id, 2110 + as defined in [RFC2392], or by referencing the Content-Location. 2111 + 2112 + o hasAttachment: "Boolean" (immutable; server-set) 2113 + 2114 + This is true if there are one or more parts in the message that a 2115 + client UI should offer as downloadable. A server SHOULD set 2116 + hasAttachment to true if the "attachments" list contains at least 2117 + one item that does not have "Content-Disposition: inline". The 2118 + server MAY ignore parts in this list that are processed 2119 + automatically in some way or are referenced as embedded images in 2120 + one of the "text/html" parts of the message. 2121 + 2122 + The server MAY set hasAttachment based on implementation-defined 2123 + or site-configurable heuristics. 2124 + 2125 + 2126 + 2127 + 2128 + 2129 + 2130 + Jenkins & Newman Standards Track [Page 38] 2131 + 2132 + RFC 8621 JMAP Mail August 2019 2133 + 2134 + 2135 + o preview: "String" (immutable; server-set) 2136 + 2137 + A plaintext fragment of the message body. This is intended to be 2138 + shown as a preview line when listing messages in the mail store 2139 + and may be truncated when shown. The server may choose which part 2140 + of the message to include in the preview; skipping quoted sections 2141 + and salutations and collapsing white space can result in a more 2142 + useful preview. 2143 + 2144 + This MUST NOT be more than 256 characters in length. 2145 + 2146 + As this is derived from the message content by the server, and the 2147 + algorithm for doing so could change over time, fetching this for 2148 + an Email a second time MAY return a different result. However, 2149 + the previous value is not considered incorrect, and the change 2150 + SHOULD NOT cause the Email object to be considered as changed by 2151 + the server. 2152 + 2153 + The exact algorithm for decomposing bodyStructure into textBody, 2154 + htmlBody, and attachments part lists is not mandated, as this is a 2155 + quality-of-service implementation issue and likely to require 2156 + workarounds for malformed content discovered over time. However, the 2157 + following algorithm (expressed here in JavaScript) is suggested as a 2158 + starting point, based on real-world experience: 2159 + 2160 + function isInlineMediaType ( type ) { 2161 + return type.startsWith( 'image/' ) || 2162 + type.startsWith( 'audio/' ) || 2163 + type.startsWith( 'video/' ); 2164 + } 2165 + 2166 + function parseStructure ( parts, multipartType, inAlternative, 2167 + htmlBody, textBody, attachments ) { 2168 + 2169 + // For multipartType == alternative 2170 + let textLength = textBody ? textBody.length : -1; 2171 + let htmlLength = htmlBody ? htmlBody.length : -1; 2172 + 2173 + for ( let i = 0; i < parts.length; i += 1 ) { 2174 + let part = parts[i]; 2175 + let isMultipart = part.type.startsWith( 'multipart/' ); 2176 + // Is this a body part rather than an attachment 2177 + let isInline = part.disposition != "attachment" && 2178 + // Must be one of the allowed body types 2179 + ( part.type == "text/plain" || 2180 + part.type == "text/html" || 2181 + isInlineMediaType( part.type ) ) && 2182 + 2183 + 2184 + 2185 + 2186 + Jenkins & Newman Standards Track [Page 39] 2187 + 2188 + RFC 8621 JMAP Mail August 2019 2189 + 2190 + 2191 + // If multipart/related, only the first part can be inline 2192 + // If a text part with a filename, and not the first item 2193 + // in the multipart, assume it is an attachment 2194 + ( i === 0 || 2195 + ( multipartType != "related" && 2196 + ( isInlineMediaType( part.type ) || !part.name ) ) ); 2197 + 2198 + if ( isMultipart ) { 2199 + let subMultiType = part.type.split( '/' )[1]; 2200 + parseStructure( part.subParts, subMultiType, 2201 + inAlternative || ( subMultiType == 'alternative' ), 2202 + htmlBody, textBody, attachments ); 2203 + } else if ( isInline ) { 2204 + if ( multipartType == 'alternative' ) { 2205 + switch ( part.type ) { 2206 + case 'text/plain': 2207 + textBody.push( part ); 2208 + break; 2209 + case 'text/html': 2210 + htmlBody.push( part ); 2211 + break; 2212 + default: 2213 + attachments.push( part ); 2214 + break; 2215 + } 2216 + continue; 2217 + } else if ( inAlternative ) { 2218 + if ( part.type == 'text/plain' ) { 2219 + htmlBody = null; 2220 + } 2221 + if ( part.type == 'text/html' ) { 2222 + textBody = null; 2223 + } 2224 + } 2225 + if ( textBody ) { 2226 + textBody.push( part ); 2227 + } 2228 + if ( htmlBody ) { 2229 + htmlBody.push( part ); 2230 + } 2231 + if ( ( !textBody || !htmlBody ) && 2232 + isInlineMediaType( part.type ) ) { 2233 + attachments.push( part ); 2234 + } 2235 + } else { 2236 + attachments.push( part ); 2237 + } 2238 + } 2239 + 2240 + 2241 + 2242 + Jenkins & Newman Standards Track [Page 40] 2243 + 2244 + RFC 8621 JMAP Mail August 2019 2245 + 2246 + 2247 + if ( multipartType == 'alternative' && textBody && htmlBody ) { 2248 + // Found HTML part only 2249 + if ( textLength == textBody.length && 2250 + htmlLength != htmlBody.length ) { 2251 + for ( let i = htmlLength; i < htmlBody.length; i += 1 ) { 2252 + textBody.push( htmlBody[i] ); 2253 + } 2254 + } 2255 + // Found plaintext part only 2256 + if ( htmlLength == htmlBody.length && 2257 + textLength != textBody.length ) { 2258 + for ( let i = textLength; i < textBody.length; i += 1 ) { 2259 + htmlBody.push( textBody[i] ); 2260 + } 2261 + } 2262 + } 2263 + } 2264 + 2265 + // Usage: 2266 + let htmlBody = []; 2267 + let textBody = []; 2268 + let attachments = []; 2269 + 2270 + parseStructure( [ bodyStructure ], 'mixed', false, 2271 + htmlBody, textBody, attachments ); 2272 + 2273 + For instance, consider a message with both text and HTML versions 2274 + that has gone through a list software manager that attaches a header 2275 + and footer. It might have a MIME structure something like: 2276 + 2277 + multipart/mixed 2278 + text/plain, content-disposition=inline - A 2279 + multipart/mixed 2280 + multipart/alternative 2281 + multipart/mixed 2282 + text/plain, content-disposition=inline - B 2283 + image/jpeg, content-disposition=inline - C 2284 + text/plain, content-disposition=inline - D 2285 + multipart/related 2286 + text/html - E 2287 + image/jpeg - F 2288 + image/jpeg, content-disposition=attachment - G 2289 + application/x-excel - H 2290 + message/rfc822 - J 2291 + text/plain, content-disposition=inline - K 2292 + 2293 + 2294 + 2295 + 2296 + 2297 + 2298 + Jenkins & Newman Standards Track [Page 41] 2299 + 2300 + RFC 8621 JMAP Mail August 2019 2301 + 2302 + 2303 + In this case, the above algorithm would decompose this to: 2304 + 2305 + textBody => [ A, B, C, D, K ] 2306 + htmlBody => [ A, E, K ] 2307 + attachments => [ C, F, G, H, J ] 2308 + 2309 + 4.2. Email/get 2310 + 2311 + This is a standard "/get" method as described in [RFC8620], 2312 + Section 5.1 with the following additional request arguments: 2313 + 2314 + o bodyProperties: "String[]" 2315 + 2316 + A list of properties to fetch for each EmailBodyPart returned. If 2317 + omitted, this defaults to: 2318 + 2319 + [ "partId", "blobId", "size", "name", "type", "charset", 2320 + "disposition", "cid", "language", "location" ] 2321 + 2322 + o fetchTextBodyValues: "Boolean" (default: false) 2323 + 2324 + If true, the "bodyValues" property includes any "text/*" part in 2325 + the "textBody" property. 2326 + 2327 + o fetchHTMLBodyValues: "Boolean" (default: false) 2328 + 2329 + If true, the "bodyValues" property includes any "text/*" part in 2330 + the "htmlBody" property. 2331 + 2332 + o fetchAllBodyValues: "Boolean" (default: false) 2333 + 2334 + If true, the "bodyValues" property includes any "text/*" part in 2335 + the "bodyStructure" property. 2336 + 2337 + o maxBodyValueBytes: "UnsignedInt" (default: 0) 2338 + 2339 + If greater than zero, the "value" property of any EmailBodyValue 2340 + object returned in "bodyValues" MUST be truncated if necessary so 2341 + it does not exceed this number of octets in size. If 0 (the 2342 + default), no truncation occurs. 2343 + 2344 + The server MUST ensure the truncation results in valid UTF-8 and 2345 + does not occur mid-codepoint. If the part is of type "text/html", 2346 + the server SHOULD NOT truncate inside an HTML tag, e.g., in the 2347 + middle of "<a href="https://example.com">". There is no 2348 + requirement for the truncated form to be a balanced tree or valid 2349 + HTML (indeed, the original source may well be neither of these 2350 + things). 2351 + 2352 + 2353 + 2354 + Jenkins & Newman Standards Track [Page 42] 2355 + 2356 + RFC 8621 JMAP Mail August 2019 2357 + 2358 + 2359 + If the standard "properties" argument is omitted or null, the 2360 + following default MUST be used instead of "all" properties: 2361 + 2362 + [ "id", "blobId", "threadId", "mailboxIds", "keywords", "size", 2363 + "receivedAt", "messageId", "inReplyTo", "references", "sender", "from", 2364 + "to", "cc", "bcc", "replyTo", "subject", "sentAt", "hasAttachment", 2365 + "preview", "bodyValues", "textBody", "htmlBody", "attachments" ] 2366 + 2367 + The following properties are expected to be fast to fetch in a 2368 + quality implementation: 2369 + 2370 + o id 2371 + 2372 + o blobId 2373 + 2374 + o threadId 2375 + 2376 + o mailboxIds 2377 + 2378 + o keywords 2379 + 2380 + o size 2381 + 2382 + o receivedAt 2383 + 2384 + o messageId 2385 + 2386 + o inReplyTo 2387 + 2388 + o sender 2389 + 2390 + o from 2391 + 2392 + o to 2393 + 2394 + o cc 2395 + 2396 + o bcc 2397 + 2398 + o replyTo 2399 + 2400 + o subject 2401 + 2402 + o sentAt 2403 + 2404 + o hasAttachment 2405 + 2406 + o preview 2407 + 2408 + 2409 + 2410 + Jenkins & Newman Standards Track [Page 43] 2411 + 2412 + RFC 8621 JMAP Mail August 2019 2413 + 2414 + 2415 + Clients SHOULD take care when fetching any other properties, as there 2416 + may be significantly longer latency in fetching and returning the 2417 + data. 2418 + 2419 + As specified above, parsed forms of headers may only be used on 2420 + appropriate header fields. Attempting to fetch a form that is 2421 + forbidden (e.g., "header:From:asDate") MUST result in the method call 2422 + being rejected with an "invalidArguments" error. 2423 + 2424 + Where a specific header field is requested as a property, the 2425 + capitalization of the property name in the response MUST be identical 2426 + to that used in the request. 2427 + 2428 + 4.2.1. Example 2429 + 2430 + Request: 2431 + 2432 + [[ "Email/get", { 2433 + "ids": [ "f123u456", "f123u457" ], 2434 + "properties": [ "threadId", "mailboxIds", "from", "subject", 2435 + "receivedAt", "header:List-POST:asURLs", 2436 + "htmlBody", "bodyValues" ], 2437 + "bodyProperties": [ "partId", "blobId", "size", "type" ], 2438 + "fetchHTMLBodyValues": true, 2439 + "maxBodyValueBytes": 256 2440 + }, "#1" ]] 2441 + 2442 + and response: 2443 + 2444 + [[ "Email/get", { 2445 + "accountId": "abc", 2446 + "state": "41234123231", 2447 + "list": [ 2448 + { 2449 + "id": "f123u457", 2450 + "threadId": "ef1314a", 2451 + "mailboxIds": { "f123": true }, 2452 + "from": [{ "name": "Joe Bloggs", "email": "joe@example.com" }], 2453 + "subject": "Dinner on Thursday?", 2454 + "receivedAt": "2013-10-13T14:12:00Z", 2455 + "header:List-POST:asURLs": [ 2456 + "mailto:partytime@lists.example.com" 2457 + ], 2458 + "htmlBody": [{ 2459 + "partId": "1", 2460 + "blobId": "B841623871", 2461 + "size": 283331, 2462 + "type": "text/html" 2463 + 2464 + 2465 + 2466 + Jenkins & Newman Standards Track [Page 44] 2467 + 2468 + RFC 8621 JMAP Mail August 2019 2469 + 2470 + 2471 + }, { 2472 + "partId": "2", 2473 + "blobId": "B319437193", 2474 + "size": 10343, 2475 + "type": "text/plain" 2476 + }], 2477 + "bodyValues": { 2478 + "1": { 2479 + "isEncodingProblem": false, 2480 + "isTruncated": true, 2481 + "value": "<html><body><p>Hello ..." 2482 + }, 2483 + "2": { 2484 + "isEncodingProblem": false, 2485 + "isTruncated": false, 2486 + "value": "-- Sent by your friendly mailing list ..." 2487 + } 2488 + } 2489 + } 2490 + ], 2491 + "notFound": [ "f123u456" ] 2492 + }, "#1" ]] 2493 + 2494 + 4.3. Email/changes 2495 + 2496 + This is a standard "/changes" method as described in [RFC8620], 2497 + Section 5.2. If generating intermediate states for a large set of 2498 + changes, it is recommended that newer changes be returned first, as 2499 + these are generally of more interest to users. 2500 + 2501 + 4.4. Email/query 2502 + 2503 + This is a standard "/query" method as described in [RFC8620], 2504 + Section 5.5 but with the following additional request arguments: 2505 + 2506 + o collapseThreads: "Boolean" (default: false) 2507 + 2508 + If true, Emails in the same Thread as a previous Email in the list 2509 + (given the filter and sort order) will be removed from the list. 2510 + This means only one Email at most will be included in the list for 2511 + any given Thread. 2512 + 2513 + In quality implementations, the query "total" property is expected to 2514 + be fast to calculate when the filter consists solely of a single 2515 + "inMailbox" property, as it is the same as the totalEmails or 2516 + totalThreads properties (depending on whether collapseThreads is 2517 + true) of the associated Mailbox object. 2518 + 2519 + 2520 + 2521 + 2522 + Jenkins & Newman Standards Track [Page 45] 2523 + 2524 + RFC 8621 JMAP Mail August 2019 2525 + 2526 + 2527 + 4.4.1. Filtering 2528 + 2529 + A *FilterCondition* object has the following properties, any of which 2530 + may be omitted: 2531 + 2532 + o inMailbox: "Id" 2533 + 2534 + A Mailbox id. An Email must be in this Mailbox to match the 2535 + condition. 2536 + 2537 + o inMailboxOtherThan: "Id[]" 2538 + 2539 + A list of Mailbox ids. An Email must be in at least one Mailbox 2540 + not in this list to match the condition. This is to allow 2541 + messages solely in trash/spam to be easily excluded from a search. 2542 + 2543 + o before: "UTCDate" 2544 + 2545 + The "receivedAt" date-time of the Email must be before this date- 2546 + time to match the condition. 2547 + 2548 + o after: "UTCDate" 2549 + 2550 + The "receivedAt" date-time of the Email must be the same or after 2551 + this date-time to match the condition. 2552 + 2553 + o minSize: "UnsignedInt" 2554 + 2555 + The "size" property of the Email must be equal to or greater than 2556 + this number to match the condition. 2557 + 2558 + o maxSize: "UnsignedInt" 2559 + 2560 + The "size" property of the Email must be less than this number to 2561 + match the condition. 2562 + 2563 + o allInThreadHaveKeyword: "String" 2564 + 2565 + All Emails (including this one) in the same Thread as this Email 2566 + must have the given keyword to match the condition. 2567 + 2568 + o someInThreadHaveKeyword: "String" 2569 + 2570 + At least one Email (possibly this one) in the same Thread as this 2571 + Email must have the given keyword to match the condition. 2572 + 2573 + 2574 + 2575 + 2576 + 2577 + 2578 + Jenkins & Newman Standards Track [Page 46] 2579 + 2580 + RFC 8621 JMAP Mail August 2019 2581 + 2582 + 2583 + o noneInThreadHaveKeyword: "String" 2584 + 2585 + All Emails (including this one) in the same Thread as this Email 2586 + must *not* have the given keyword to match the condition. 2587 + 2588 + o hasKeyword: "String" 2589 + 2590 + This Email must have the given keyword to match the condition. 2591 + 2592 + o notKeyword: "String" 2593 + 2594 + This Email must not have the given keyword to match the condition. 2595 + 2596 + o hasAttachment: "Boolean" 2597 + 2598 + The "hasAttachment" property of the Email must be identical to the 2599 + value given to match the condition. 2600 + 2601 + o text: "String" 2602 + 2603 + Looks for the text in Emails. The server MUST look up text in the 2604 + From, To, Cc, Bcc, and Subject header fields of the message and 2605 + SHOULD look inside any "text/*" or other body parts that may be 2606 + converted to text by the server. The server MAY extend the search 2607 + to any additional textual property. 2608 + 2609 + o from: "String" 2610 + 2611 + Looks for the text in the From header field of the message. 2612 + 2613 + o to: "String" 2614 + 2615 + Looks for the text in the To header field of the message. 2616 + 2617 + o cc: "String" 2618 + 2619 + Looks for the text in the Cc header field of the message. 2620 + 2621 + o bcc: "String" 2622 + 2623 + Looks for the text in the Bcc header field of the message. 2624 + 2625 + o subject: "String" 2626 + 2627 + Looks for the text in the Subject header field of the message. 2628 + 2629 + 2630 + 2631 + 2632 + 2633 + 2634 + Jenkins & Newman Standards Track [Page 47] 2635 + 2636 + RFC 8621 JMAP Mail August 2019 2637 + 2638 + 2639 + o body: "String" 2640 + 2641 + Looks for the text in one of the body parts of the message. The 2642 + server MAY exclude MIME body parts with content media types other 2643 + than "text/*" and "message/*" from consideration in search 2644 + matching. Care should be taken to match based on the text content 2645 + actually presented to an end user by viewers for that media type 2646 + or otherwise identified as appropriate for search indexing. 2647 + Matching document metadata uninteresting to an end user (e.g., 2648 + markup tag and attribute names) is undesirable. 2649 + 2650 + o header: "String[]" 2651 + 2652 + The array MUST contain either one or two elements. The first 2653 + element is the name of the header field to match against. The 2654 + second (optional) element is the text to look for in the header 2655 + field value. If not supplied, the message matches simply if it 2656 + has a header field of the given name. 2657 + 2658 + If zero properties are specified on the FilterCondition, the 2659 + condition MUST always evaluate to true. If multiple properties are 2660 + specified, ALL must apply for the condition to be true (it is 2661 + equivalent to splitting the object into one-property conditions and 2662 + making them all the child of an AND filter operator). 2663 + 2664 + The exact semantics for matching "String" fields is *deliberately not 2665 + defined* to allow for flexibility in indexing implementation, subject 2666 + to the following: 2667 + 2668 + o Any syntactically correct encoded sections [RFC2047] of header 2669 + fields with a known encoding SHOULD be decoded before attempting 2670 + to match text. 2671 + 2672 + o When searching inside a "text/html" body part, any text considered 2673 + markup rather than content SHOULD be ignored, including HTML tags 2674 + and most attributes, anything inside the "<head>" tag, Cascading 2675 + Style Sheets (CSS), and JavaScript. Attribute content intended 2676 + for presentation to the user such as "alt" and "title" SHOULD be 2677 + considered in the search. 2678 + 2679 + o Text SHOULD be matched in a case-insensitive manner. 2680 + 2681 + o Text contained in either (but matched) single (') or double (") 2682 + quotes SHOULD be treated as a *phrase search*; that is, a match is 2683 + required for that exact word or sequence of words, excluding the 2684 + surrounding quotation marks. 2685 + 2686 + 2687 + 2688 + 2689 + 2690 + Jenkins & Newman Standards Track [Page 48] 2691 + 2692 + RFC 8621 JMAP Mail August 2019 2693 + 2694 + 2695 + Within a phrase, to match one of the following characters you MUST 2696 + escape it by prefixing it with a backslash (\): 2697 + 2698 + ' " \ 2699 + 2700 + o Outside of a phrase, white space SHOULD be treated as dividing 2701 + separate tokens that may be searched for separately but MUST all 2702 + be present for the Email to match the filter. 2703 + 2704 + o Tokens (not part of a phrase) MAY be matched on a whole-word basis 2705 + using stemming (for example, a text search for "bus" would match 2706 + "buses" but not "business"). 2707 + 2708 + 4.4.2. Sorting 2709 + 2710 + The following value for the "property" field on the Comparator object 2711 + MUST be supported for sorting: 2712 + 2713 + o "receivedAt" - The "receivedAt" date as returned in the Email 2714 + object. 2715 + 2716 + The following values for the "property" field on the Comparator 2717 + object SHOULD be supported for sorting. When specifying a 2718 + "hasKeyword", "allInThreadHaveKeyword", or "someInThreadHaveKeyword" 2719 + sort, the Comparator object MUST also have a "keyword" property. 2720 + 2721 + o "size" - The "size" as returned in the Email object. 2722 + 2723 + o "from" - This is taken to be either the "name" property or if 2724 + null/empty, the "email" property of the *first* EmailAddress 2725 + object in the Email's "from" property. If still none, consider 2726 + the value to be the empty string. 2727 + 2728 + o "to" - This is taken to be either the "name" property or if null/ 2729 + empty, the "email" property of the *first* EmailAddress object in 2730 + the Email's "to" property. If still none, consider the value to 2731 + be the empty string. 2732 + 2733 + o "subject" - This is taken to be the base subject of the message, 2734 + as defined in Section 2.1 of [RFC5256]. 2735 + 2736 + o "sentAt" - The "sentAt" property on the Email object. 2737 + 2738 + o "hasKeyword" - This value MUST be considered true if the Email has 2739 + the keyword given as an additional "keyword" property on the 2740 + Comparator object, or false otherwise. 2741 + 2742 + 2743 + 2744 + 2745 + 2746 + Jenkins & Newman Standards Track [Page 49] 2747 + 2748 + RFC 8621 JMAP Mail August 2019 2749 + 2750 + 2751 + o "allInThreadHaveKeyword" - This value MUST be considered true for 2752 + the Email if *all* of the Emails in the same Thread have the 2753 + keyword given as an additional "keyword" property on the 2754 + Comparator object. 2755 + 2756 + o "someInThreadHaveKeyword" - This value MUST be considered true for 2757 + the Email if *any* of the Emails in the same Thread have the 2758 + keyword given as an additional "keyword" property on the 2759 + Comparator object. 2760 + 2761 + The server MAY support sorting based on other properties as well. A 2762 + client can discover which properties are supported by inspecting the 2763 + account's "capabilities" object (see Section 1.3). 2764 + 2765 + Example sort: 2766 + 2767 + [{ 2768 + "property": "someInThreadHaveKeyword", 2769 + "keyword": "$flagged", 2770 + "isAscending": false 2771 + }, { 2772 + "property": "subject", 2773 + "collation": "i;ascii-casemap" 2774 + }, { 2775 + "property": "receivedAt", 2776 + "isAscending": false 2777 + }] 2778 + 2779 + This would sort Emails in flagged Threads first (the Thread is 2780 + considered flagged if any Email within it is flagged), in subject 2781 + order second, and then from newest first for messages with the same 2782 + subject. If two Emails have identical values for all three 2783 + properties, then the order is server dependent but must be stable. 2784 + 2785 + 4.4.3. Thread Collapsing 2786 + 2787 + When "collapseThreads" is true, then after filtering and sorting the 2788 + Email list, the list is further winnowed by removing any Emails for a 2789 + Thread id that has already been seen (when passing through the list 2790 + sequentially). A Thread will therefore only appear *once* in the 2791 + result, at the position of the first Email in the list that belongs 2792 + to the Thread (given the current sort/filter). 2793 + 2794 + 2795 + 2796 + 2797 + 2798 + 2799 + 2800 + 2801 + 2802 + Jenkins & Newman Standards Track [Page 50] 2803 + 2804 + RFC 8621 JMAP Mail August 2019 2805 + 2806 + 2807 + 4.5. Email/queryChanges 2808 + 2809 + This is a standard "/queryChanges" method as described in [RFC8620], 2810 + Section 5.6 with the following additional request argument: 2811 + 2812 + o collapseThreads: "Boolean" (default: false) 2813 + 2814 + The "collapseThreads" argument that was used with "Email/query". 2815 + 2816 + 4.6. Email/set 2817 + 2818 + This is a standard "/set" method as described in [RFC8620], 2819 + Section 5.3. The "Email/set" method encompasses: 2820 + 2821 + o Creating a draft 2822 + 2823 + o Changing the keywords of an Email (e.g., unread/flagged status) 2824 + 2825 + o Adding/removing an Email to/from Mailboxes (moving a message) 2826 + 2827 + o Deleting Emails 2828 + 2829 + The format of the "keywords"/"mailboxIds" properties means that when 2830 + updating an Email, you can either replace the entire set of keywords/ 2831 + Mailboxes (by setting the full value of the property) or add/remove 2832 + individual ones using the JMAP patch syntax (see [RFC8620], 2833 + Section 5.3 for the specification and Section 5.7 for an example). 2834 + 2835 + Due to the format of the Email object, when creating an Email, there 2836 + are a number of ways to specify the same information. To ensure that 2837 + the message [RFC5322] to create is unambiguous, the following 2838 + constraints apply to Email objects submitted for creation: 2839 + 2840 + o The "headers" property MUST NOT be given on either the top-level 2841 + Email or an EmailBodyPart -- the client must set each header field 2842 + as an individual property. 2843 + 2844 + o There MUST NOT be two properties that represent the same header 2845 + field (e.g., "header:from" and "from") within the Email or 2846 + particular EmailBodyPart. 2847 + 2848 + o Header fields MUST NOT be specified in parsed forms that are 2849 + forbidden for that particular field. 2850 + 2851 + o Header fields beginning with "Content-" MUST NOT be specified on 2852 + the Email object, only on EmailBodyPart objects. 2853 + 2854 + 2855 + 2856 + 2857 + 2858 + Jenkins & Newman Standards Track [Page 51] 2859 + 2860 + RFC 8621 JMAP Mail August 2019 2861 + 2862 + 2863 + o If a "bodyStructure" property is given, there MUST NOT be 2864 + "textBody", "htmlBody", or "attachments" properties. 2865 + 2866 + o If given, the "bodyStructure" EmailBodyPart MUST NOT contain a 2867 + property representing a header field that is already defined on 2868 + the top-level Email object. 2869 + 2870 + o If given, textBody MUST contain exactly one body part and it MUST 2871 + be of type "text/plain". 2872 + 2873 + o If given, htmlBody MUST contain exactly one body part and it MUST 2874 + be of type "text/html". 2875 + 2876 + o Within an EmailBodyPart: 2877 + 2878 + * The client may specify a partId OR a blobId, but not both. If 2879 + a partId is given, this partId MUST be present in the 2880 + "bodyValues" property. 2881 + 2882 + * The "charset" property MUST be omitted if a partId is given 2883 + (the part's content is included in bodyValues, and the server 2884 + may choose any appropriate encoding). 2885 + 2886 + * The "size" property MUST be omitted if a partId is given. If a 2887 + blobId is given, it may be included but is ignored by the 2888 + server (the size is actually calculated from the blob content 2889 + itself). 2890 + 2891 + * A Content-Transfer-Encoding header field MUST NOT be given. 2892 + 2893 + o Within an EmailBodyValue object, isEncodingProblem and isTruncated 2894 + MUST be either false or omitted. 2895 + 2896 + Creation attempts that violate any of this SHOULD be rejected with an 2897 + "invalidProperties" error; however, a server MAY choose to modify the 2898 + Email (e.g., choose between conflicting headers, use a different 2899 + content-encoding, etc.) to comply with its requirements instead. 2900 + 2901 + The server MAY also choose to set additional headers. If not 2902 + included, the server MUST generate and set a Message-ID header field 2903 + in conformance with [RFC5322], Section 3.6.4 and a Date header field 2904 + in conformance with Section 3.6.1. 2905 + 2906 + The final message generated may be invalid per RFC 5322. For 2907 + example, if it is a half-finished draft, the To header field may have 2908 + a value that does not conform to the required syntax for this header. 2909 + The message will be checked for strict conformance when submitted for 2910 + sending (see the EmailSubmission object description). 2911 + 2912 + 2913 + 2914 + Jenkins & Newman Standards Track [Page 52] 2915 + 2916 + RFC 8621 JMAP Mail August 2019 2917 + 2918 + 2919 + Destroying an Email removes it from all Mailboxes to which it 2920 + belonged. To just delete an Email to trash, simply change the 2921 + "mailboxIds" property, so it is now in the Mailbox with a "role" 2922 + property equal to "trash", and remove all other Mailbox ids. 2923 + 2924 + When emptying the trash, clients SHOULD NOT destroy Emails that are 2925 + also in a Mailbox other than trash. For those Emails, they SHOULD 2926 + just remove the trash Mailbox from the Email. 2927 + 2928 + For successfully created Email objects, the "created" response 2929 + contains the "id", "blobId", "threadId", and "size" properties of the 2930 + object. 2931 + 2932 + The following extra SetError types are defined: 2933 + 2934 + For "create": 2935 + 2936 + o "blobNotFound": At least one blob id given for an EmailBodyPart 2937 + doesn't exist. An extra "notFound" property of type "Id[]" MUST 2938 + be included in the SetError object containing every "blobId" 2939 + referenced by an EmailBodyPart that could not be found on the 2940 + server. 2941 + 2942 + For "create" and "update": 2943 + 2944 + o "tooManyKeywords": The change to the Email's keywords would exceed 2945 + a server-defined maximum. 2946 + 2947 + o "tooManyMailboxes": The change to the set of Mailboxes that this 2948 + Email is in would exceed a server-defined maximum. 2949 + 2950 + 4.7. Email/copy 2951 + 2952 + This is a standard "/copy" method as described in [RFC8620], 2953 + Section 5.4, except only the "mailboxIds", "keywords", and 2954 + "receivedAt" properties may be set during the copy. This method 2955 + cannot modify the message represented by the Email. 2956 + 2957 + The server MAY forbid two Email objects with identical message 2958 + content [RFC5322], or even just with the same Message-ID [RFC5322], 2959 + to coexist within an account; if the target account already has the 2960 + Email, the copy will be rejected with a standard "alreadyExists" 2961 + error. 2962 + 2963 + For successfully copied Email objects, the "created" response 2964 + contains the "id", "blobId", "threadId", and "size" properties of the 2965 + new object. 2966 + 2967 + 2968 + 2969 + 2970 + Jenkins & Newman Standards Track [Page 53] 2971 + 2972 + RFC 8621 JMAP Mail August 2019 2973 + 2974 + 2975 + 4.8. Email/import 2976 + 2977 + The "Email/import" method adds messages [RFC5322] to the set of 2978 + Emails in an account. The server MUST support messages with Email 2979 + Address Internationalization (EAI) headers [RFC6532]. The messages 2980 + must first be uploaded as blobs using the standard upload mechanism. 2981 + The method takes the following arguments: 2982 + 2983 + o accountId: "Id" 2984 + 2985 + The id of the account to use. 2986 + 2987 + o ifInState: "String|null" 2988 + 2989 + This is a state string as returned by the "Email/get" method. If 2990 + supplied, the string must match the current state of the account 2991 + referenced by the accountId; otherwise, the method will be aborted 2992 + and a "stateMismatch" error returned. If null, any changes will 2993 + be applied to the current state. 2994 + 2995 + o emails: "Id[EmailImport]" 2996 + 2997 + A map of creation id (client specified) to EmailImport objects. 2998 + 2999 + An *EmailImport* object has the following properties: 3000 + 3001 + o blobId: "Id" 3002 + 3003 + The id of the blob containing the raw message [RFC5322]. 3004 + 3005 + o mailboxIds: "Id[Boolean]" 3006 + 3007 + The ids of the Mailboxes to assign this Email to. At least one 3008 + Mailbox MUST be given. 3009 + 3010 + o keywords: "String[Boolean]" (default: {}) 3011 + 3012 + The keywords to apply to the Email. 3013 + 3014 + o receivedAt: "UTCDate" (default: time of most recent Received 3015 + header, or time of import on server if none) 3016 + 3017 + The "receivedAt" date to set on the Email. 3018 + 3019 + Each Email to import is considered an atomic unit that may succeed or 3020 + fail individually. Importing successfully creates a new Email object 3021 + from the data referenced by the blobId and applies the given 3022 + Mailboxes, keywords, and receivedAt date. 3023 + 3024 + 3025 + 3026 + Jenkins & Newman Standards Track [Page 54] 3027 + 3028 + RFC 8621 JMAP Mail August 2019 3029 + 3030 + 3031 + The server MAY forbid two Email objects with the same exact content 3032 + [RFC5322], or even just with the same Message-ID [RFC5322], to 3033 + coexist within an account. In this case, it MUST reject attempts to 3034 + import an Email considered to be a duplicate with an "alreadyExists" 3035 + SetError. An "existingId" property of type "Id" MUST be included on 3036 + the SetError object with the id of the existing Email. If duplicates 3037 + are allowed, the newly created Email object MUST have a separate id 3038 + and independent mutable properties to the existing object. 3039 + 3040 + If the "blobId", "mailboxIds", or "keywords" properties are invalid 3041 + (e.g., missing, wrong type, id not found), the server MUST reject the 3042 + import with an "invalidProperties" SetError. 3043 + 3044 + If the Email cannot be imported because it would take the account 3045 + over quota, the import should be rejected with an "overQuota" 3046 + SetError. 3047 + 3048 + If the blob referenced is not a valid message [RFC5322], the server 3049 + MAY modify the message to fix errors (such as removing NUL octets or 3050 + fixing invalid headers). If it does this, the "blobId" on the 3051 + response MUST represent the new representation and therefore be 3052 + different to the "blobId" on the EmailImport object. Alternatively, 3053 + the server MAY reject the import with an "invalidEmail" SetError. 3054 + 3055 + The response has the following arguments: 3056 + 3057 + o accountId: "Id" 3058 + 3059 + The id of the account used for this call. 3060 + 3061 + o oldState: "String|null" 3062 + 3063 + The state string that would have been returned by "Email/get" on 3064 + this account before making the requested changes, or null if the 3065 + server doesn't know what the previous state string was. 3066 + 3067 + o newState: "String" 3068 + 3069 + The state string that will now be returned by "Email/get" on this 3070 + account. 3071 + 3072 + o created: "Id[Email]|null" 3073 + 3074 + A map of the creation id to an object containing the "id", 3075 + "blobId", "threadId", and "size" properties for each successfully 3076 + imported Email, or null if none. 3077 + 3078 + 3079 + 3080 + 3081 + 3082 + Jenkins & Newman Standards Track [Page 55] 3083 + 3084 + RFC 8621 JMAP Mail August 2019 3085 + 3086 + 3087 + o notCreated: "Id[SetError]|null" 3088 + 3089 + A map of the creation id to a SetError object for each Email that 3090 + failed to be created, or null if all successful. The possible 3091 + errors are defined above. 3092 + 3093 + The following additional errors may be returned instead of the 3094 + "Email/import" response: 3095 + 3096 + "stateMismatch": An "ifInState" argument was supplied, and it does 3097 + not match the current state. 3098 + 3099 + 4.9. Email/parse 3100 + 3101 + This method allows you to parse blobs as messages [RFC5322] to get 3102 + Email objects. The server MUST support messages with EAI headers 3103 + [RFC6532]. This can be used to parse and display attached messages 3104 + without having to import them as top-level Email objects in the mail 3105 + store in their own right. 3106 + 3107 + The following metadata properties on the Email objects will be null 3108 + if requested: 3109 + 3110 + o id 3111 + 3112 + o mailboxIds 3113 + 3114 + o keywords 3115 + 3116 + o receivedAt 3117 + 3118 + The "threadId" property of the Email MAY be present if the server can 3119 + calculate which Thread the Email would be assigned to were it to be 3120 + imported. Otherwise, this too is null if fetched. 3121 + 3122 + The "Email/parse" method takes the following arguments: 3123 + 3124 + o accountId: "Id" 3125 + 3126 + The id of the account to use. 3127 + 3128 + o blobIds: "Id[]" 3129 + 3130 + The ids of the blobs to parse. 3131 + 3132 + 3133 + 3134 + 3135 + 3136 + 3137 + 3138 + Jenkins & Newman Standards Track [Page 56] 3139 + 3140 + RFC 8621 JMAP Mail August 2019 3141 + 3142 + 3143 + o properties: "String[]" 3144 + 3145 + If supplied, only the properties listed in the array are returned 3146 + for each Email object. If omitted, defaults to: 3147 + 3148 + [ "messageId", "inReplyTo", "references", "sender", "from", "to", 3149 + "cc", "bcc", "replyTo", "subject", "sentAt", "hasAttachment", 3150 + "preview", "bodyValues", "textBody", "htmlBody", "attachments" ] 3151 + 3152 + o bodyProperties: "String[]" 3153 + 3154 + A list of properties to fetch for each EmailBodyPart returned. If 3155 + omitted, defaults to the same value as the "Email/get" 3156 + "bodyProperties" default argument. 3157 + 3158 + o fetchTextBodyValues: "Boolean" (default: false) 3159 + 3160 + If true, the "bodyValues" property includes any "text/*" part in 3161 + the "textBody" property. 3162 + 3163 + o fetchHTMLBodyValues: "Boolean" (default: false) 3164 + 3165 + If true, the "bodyValues" property includes any "text/*" part in 3166 + the "htmlBody" property. 3167 + 3168 + o fetchAllBodyValues: "Boolean" (default: false) 3169 + 3170 + If true, the "bodyValues" property includes any "text/*" part in 3171 + the "bodyStructure" property. 3172 + 3173 + o maxBodyValueBytes: "UnsignedInt" (default: 0) 3174 + 3175 + If greater than zero, the "value" property of any EmailBodyValue 3176 + object returned in "bodyValues" MUST be truncated if necessary so 3177 + it does not exceed this number of octets in size. If 0 (the 3178 + default), no truncation occurs. 3179 + 3180 + The server MUST ensure the truncation results in valid UTF-8 and 3181 + does not occur mid-codepoint. If the part is of type "text/html", 3182 + the server SHOULD NOT truncate inside an HTML tag, e.g., in the 3183 + middle of "<a href="https://example.com">". There is no 3184 + requirement for the truncated form to be a balanced tree or valid 3185 + HTML (indeed, the original source may well be neither of these 3186 + things). 3187 + 3188 + 3189 + 3190 + 3191 + 3192 + 3193 + 3194 + Jenkins & Newman Standards Track [Page 57] 3195 + 3196 + RFC 8621 JMAP Mail August 2019 3197 + 3198 + 3199 + The response has the following arguments: 3200 + 3201 + o accountId: "Id" 3202 + 3203 + The id of the account used for the call. 3204 + 3205 + o parsed: "Id[Email]|null" 3206 + 3207 + A map of blob id to parsed Email representation for each 3208 + successfully parsed blob, or null if none. 3209 + 3210 + o notParsable: "Id[]|null" 3211 + 3212 + A list of ids given that corresponded to blobs that could not be 3213 + parsed as Emails, or null if none. 3214 + 3215 + o notFound: "Id[]|null" 3216 + 3217 + A list of blob ids given that could not be found, or null if none. 3218 + 3219 + As specified above, parsed forms of headers may only be used on 3220 + appropriate header fields. Attempting to fetch a form that is 3221 + forbidden (e.g., "header:From:asDate") MUST result in the method call 3222 + being rejected with an "invalidArguments" error. 3223 + 3224 + Where a specific header field is requested as a property, the 3225 + capitalization of the property name in the response MUST be identical 3226 + to that used in the request. 3227 + 3228 + 4.10. Examples 3229 + 3230 + A client logs in for the first time. It first fetches the set of 3231 + Mailboxes. Now it will display the inbox to the user, which we will 3232 + presume has Mailbox id "fb666a55". The inbox may be (very!) large, 3233 + but the user's screen is only so big, so the client can just load the 3234 + Threads it needs to fill the screen and then load in more only when 3235 + the user scrolls. The client sends this request: 3236 + 3237 + [[ "Email/query",{ 3238 + "accountId": "ue150411c", 3239 + "filter": { 3240 + "inMailbox": "fb666a55" 3241 + }, 3242 + "sort": [{ 3243 + "isAscending": false, 3244 + "property": "receivedAt" 3245 + }], 3246 + "collapseThreads": true, 3247 + 3248 + 3249 + 3250 + Jenkins & Newman Standards Track [Page 58] 3251 + 3252 + RFC 8621 JMAP Mail August 2019 3253 + 3254 + 3255 + "position": 0, 3256 + "limit": 30, 3257 + "calculateTotal": true 3258 + }, "0" ], 3259 + [ "Email/get", { 3260 + "accountId": "ue150411c", 3261 + "#ids": { 3262 + "resultOf": "0", 3263 + "name": "Email/query", 3264 + "path": "/ids" 3265 + }, 3266 + "properties": [ 3267 + "threadId" 3268 + ] 3269 + }, "1" ], 3270 + [ "Thread/get", { 3271 + "accountId": "ue150411c", 3272 + "#ids": { 3273 + "resultOf": "1", 3274 + "name": "Email/get", 3275 + "path": "/list/*/threadId" 3276 + } 3277 + }, "2" ], 3278 + [ "Email/get", { 3279 + "accountId": "ue150411c", 3280 + "#ids": { 3281 + "resultOf": "2", 3282 + "name": "Thread/get", 3283 + "path": "/list/*/emailIds" 3284 + }, 3285 + "properties": [ 3286 + "threadId", 3287 + "mailboxIds", 3288 + "keywords", 3289 + "hasAttachment", 3290 + "from", 3291 + "subject", 3292 + "receivedAt", 3293 + "size", 3294 + "preview" 3295 + ] 3296 + }, "3" ]] 3297 + 3298 + 3299 + 3300 + 3301 + 3302 + 3303 + 3304 + 3305 + 3306 + Jenkins & Newman Standards Track [Page 59] 3307 + 3308 + RFC 8621 JMAP Mail August 2019 3309 + 3310 + 3311 + Let's break down the 4 method calls to see what they're doing: 3312 + 3313 + "0": This asks the server for the ids of the first 30 Email objects 3314 + in the inbox, sorted newest first, ignoring Emails from the same 3315 + Thread as a newer Email in the Mailbox (i.e., it is the first 30 3316 + unique Threads). 3317 + 3318 + "1": Now we use a back-reference to fetch the Thread ids for each of 3319 + these Email ids. 3320 + 3321 + "2": Another back-reference fetches the Thread object for each of 3322 + these Thread ids. 3323 + 3324 + "3": Finally, we fetch the information we need to display the Mailbox 3325 + listing (but no more!) for every Email in each of these 30 Threads. 3326 + The client may aggregate this data for display, for example, by 3327 + showing the Thread as "flagged" if any of the Emails in it has the 3328 + "$flagged" keyword. 3329 + 3330 + The response from the server may look something like this: 3331 + 3332 + [[ "Email/query", { 3333 + "accountId": "ue150411c", 3334 + "queryState": "09aa9a075588-780599:0", 3335 + "canCalculateChanges": true, 3336 + "position": 0, 3337 + "total": 115, 3338 + "ids": [ "Ma783e5cdf5f2deffbc97930a", 3339 + "M9bd17497e2a99cb345fc1d0a", ... ] 3340 + }, "0" ], 3341 + [ "Email/get", { 3342 + "accountId": "ue150411c", 3343 + "state": "780599", 3344 + "list": [{ 3345 + "id": "Ma783e5cdf5f2deffbc97930a", 3346 + "threadId": "T36703c2cfe9bd5ed" 3347 + }, { 3348 + "id": "M9bd17497e2a99cb345fc1d0a", 3349 + "threadId": "T0a22ad76e9c097a1" 3350 + }, ... ], 3351 + "notFound": [] 3352 + }, "1" ], 3353 + [ "Thread/get", { 3354 + "accountId": "ue150411c", 3355 + "state": "22a8728b", 3356 + "list": [{ 3357 + "id": "T36703c2cfe9bd5ed", 3358 + "emailIds": [ "Ma783e5cdf5f2deffbc97930a" ] 3359 + 3360 + 3361 + 3362 + Jenkins & Newman Standards Track [Page 60] 3363 + 3364 + RFC 8621 JMAP Mail August 2019 3365 + 3366 + 3367 + }, { 3368 + "id": "T0a22ad76e9c097a1", 3369 + "emailIds": [ "M3b568670a63e5d100f518fa5", 3370 + "M9bd17497e2a99cb345fc1d0a" ] 3371 + }, ... ], 3372 + "notFound": [] 3373 + }, "2" ], 3374 + [ "Email/get", { 3375 + "accountId": "ue150411c", 3376 + "state": "780599", 3377 + "list": [{ 3378 + "id": "Ma783e5cdf5f2deffbc97930a", 3379 + "threadId": "T36703c2cfe9bd5ed", 3380 + "mailboxIds": { 3381 + "fb666a55": true 3382 + }, 3383 + "keywords": { 3384 + "$seen": true, 3385 + "$flagged": true 3386 + }, 3387 + "hasAttachment": true, 3388 + "from": [{ 3389 + "email": "jdoe@example.com", 3390 + "name": "Jane Doe" 3391 + }], 3392 + "subject": "The Big Reveal", 3393 + "receivedAt": "2018-06-27T00:20:35Z", 3394 + "size": 175047, 3395 + "preview": "As you may be aware, we are required to prepare a 3396 + presentation where we wow a panel of 5 random members of the 3397 + public, on or before 30 June each year. We have drafted..." 3398 + }, 3399 + ... 3400 + ], 3401 + "notFound": [] 3402 + }, "3" ]] 3403 + 3404 + 3405 + 3406 + 3407 + 3408 + 3409 + 3410 + 3411 + 3412 + 3413 + 3414 + 3415 + 3416 + 3417 + 3418 + Jenkins & Newman Standards Track [Page 61] 3419 + 3420 + RFC 8621 JMAP Mail August 2019 3421 + 3422 + 3423 + Now, on another device, the user marks the first Email as unread, 3424 + sending this API request: 3425 + 3426 + [[ "Email/set", { 3427 + "accountId": "ue150411c", 3428 + "update": { 3429 + "Ma783e5cdf5f2deffbc97930a": { 3430 + "keywords/$seen": null 3431 + } 3432 + } 3433 + }, "0" ]] 3434 + 3435 + The server applies this and sends the success response: 3436 + 3437 + [[ "Email/set", { 3438 + "accountId": "ue150411c", 3439 + "oldState": "780605", 3440 + "newState": "780606", 3441 + "updated": { 3442 + "Ma783e5cdf5f2deffbc97930a": null 3443 + }, 3444 + ... 3445 + }, "0" ]] 3446 + 3447 + The user also deletes a few Emails, and then a new message arrives. 3448 + 3449 + 3450 + 3451 + 3452 + 3453 + 3454 + 3455 + 3456 + 3457 + 3458 + 3459 + 3460 + 3461 + 3462 + 3463 + 3464 + 3465 + 3466 + 3467 + 3468 + 3469 + 3470 + 3471 + 3472 + 3473 + 3474 + Jenkins & Newman Standards Track [Page 62] 3475 + 3476 + RFC 8621 JMAP Mail August 2019 3477 + 3478 + 3479 + Back on our original machine, we receive a push update that the state 3480 + string for Email is now "780800". As this does not match the 3481 + client's current state, it issues a request for the changes: 3482 + 3483 + [[ "Email/changes", { 3484 + "accountId": "ue150411c", 3485 + "sinceState": "780605", 3486 + "maxChanges": 50 3487 + }, "3" ], 3488 + [ "Email/queryChanges", { 3489 + "accountId": "ue150411c", 3490 + "filter": { 3491 + "inMailbox": "fb666a55" 3492 + }, 3493 + "sort": [{ 3494 + "property": "receivedAt", 3495 + "isAscending": false 3496 + }], 3497 + "collapseThreads": true, 3498 + "sinceQueryState": "09aa9a075588-780599:0", 3499 + "upToId": "Mc2781d5e856a908d8a35a564", 3500 + "maxChanges": 25, 3501 + "calculateTotal": true 3502 + }, "11" ]] 3503 + 3504 + The response: 3505 + 3506 + [[ "Email/changes", { 3507 + "accountId": "ue150411c", 3508 + "oldState": "780605", 3509 + "newState": "780800", 3510 + "hasMoreChanges": false, 3511 + "created": [ "Me8de6c9f6de198239b982ea2" ], 3512 + "updated": [ "Ma783e5cdf5f2deffbc97930a" ], 3513 + "destroyed": [ "M9bd17497e2a99cb345fc1d0a", ... ] 3514 + }, "3" ], 3515 + [ "Email/queryChanges", { 3516 + "accountId": "ue150411c", 3517 + "oldQueryState": "09aa9a075588-780599:0", 3518 + "newQueryState": "e35e9facf117-780615:0", 3519 + "added": [{ 3520 + "id": "Me8de6c9f6de198239b982ea2", 3521 + "index": 0 3522 + }], 3523 + "removed": [ "M9bd17497e2a99cb345fc1d0a" ], 3524 + "total": 115 3525 + }, "11" ]] 3526 + 3527 + 3528 + 3529 + 3530 + Jenkins & Newman Standards Track [Page 63] 3531 + 3532 + RFC 8621 JMAP Mail August 2019 3533 + 3534 + 3535 + The client can update its local cache of the query results by 3536 + removing "M9bd17497e2a99cb345fc1d0a" and then splicing in 3537 + "Me8de6c9f6de198239b982ea2" at position 0. As it does not have the 3538 + data for this new Email, it will then fetch it (it also could have 3539 + done this in the same request using back-references). 3540 + 3541 + It knows something has changed about "Ma783e5cdf5f2deffbc97930a", so 3542 + it will refetch the Mailbox ids and keywords (the only mutable 3543 + properties) for this Email too. 3544 + 3545 + The user starts composing a new Email. The email is plaintext and 3546 + the client knows the email in English so adds this metadata to the 3547 + body part. The user saves a draft while the composition is still in 3548 + progress. The client sends: 3549 + 3550 + [[ "Email/set", { 3551 + "accountId": "ue150411c", 3552 + "create": { 3553 + "k192": { 3554 + "mailboxIds": { 3555 + "2ea1ca41b38e": true 3556 + }, 3557 + "keywords": { 3558 + "$seen": true, 3559 + "$draft": true 3560 + }, 3561 + "from": [{ 3562 + "name": "Joe Bloggs", 3563 + "email": "joe@example.com" 3564 + }], 3565 + "subject": "World domination", 3566 + "receivedAt": "2018-07-10T01:03:11Z", 3567 + "sentAt": "2018-07-10T11:03:11+10:00", 3568 + "bodyStructure": { 3569 + "type": "text/plain", 3570 + "partId": "bd48", 3571 + "header:Content-Language": "en" 3572 + }, 3573 + "bodyValues": { 3574 + "bd48": { 3575 + "value": "I have the most brilliant plan. Let me tell 3576 + you all about it. What we do is, we", 3577 + "isTruncated": false 3578 + } 3579 + } 3580 + } 3581 + } 3582 + }, "0" ]] 3583 + 3584 + 3585 + 3586 + Jenkins & Newman Standards Track [Page 64] 3587 + 3588 + RFC 8621 JMAP Mail August 2019 3589 + 3590 + 3591 + The server creates the message and sends the success response: 3592 + 3593 + [[ "Email/set", { 3594 + "accountId": "ue150411c", 3595 + "oldState": "780823", 3596 + "newState": "780839", 3597 + "created": { 3598 + "k192": { 3599 + "id": "Mf40b5f831efa7233b9eb1c7f", 3600 + "blobId": "Gf40b5f831efa7233b9eb1c7f8f97d84eeeee64f7", 3601 + "threadId": "Td957e72e89f516dc", 3602 + "size": 359 3603 + } 3604 + }, 3605 + ... 3606 + }, "0" ]] 3607 + 3608 + The message created on the server looks something like this: 3609 + 3610 + Message-Id: <bbce0ae9-58be-4b24-ac82-deb840d58016@sloti7d1t02> 3611 + User-Agent: Cyrus-JMAP/3.1.6-736-gdfb8e44 3612 + Mime-Version: 1.0 3613 + Date: Tue, 10 Jul 2018 11:03:11 +1000 3614 + From: "Joe Bloggs" <joe@example.com> 3615 + Subject: World domination 3616 + Content-Language: en 3617 + Content-Type: text/plain 3618 + 3619 + I have the most brilliant plan. Let me tell you all about it. What we 3620 + do is, we 3621 + 3622 + The user adds a recipient and converts the message to HTML so they 3623 + can add formatting, then saves an updated draft: 3624 + 3625 + [[ "Email/set", { 3626 + "accountId": "ue150411c", 3627 + "create": { 3628 + "k1546": { 3629 + "mailboxIds": { 3630 + "2ea1ca41b38e": true 3631 + }, 3632 + "keywords": { 3633 + "$seen": true, 3634 + "$draft": true 3635 + }, 3636 + "from": [{ 3637 + "name": "Joe Bloggs", 3638 + "email": "joe@example.com" 3639 + 3640 + 3641 + 3642 + Jenkins & Newman Standards Track [Page 65] 3643 + 3644 + RFC 8621 JMAP Mail August 2019 3645 + 3646 + 3647 + }], 3648 + "to": [{ 3649 + "name": "John", 3650 + "email": "john@example.com" 3651 + }], 3652 + "subject": "World domination", 3653 + "receivedAt": "2018-07-10T01:05:08Z", 3654 + "sentAt": "2018-07-10T11:05:08+10:00", 3655 + "bodyStructure": { 3656 + "type": "multipart/alternative", 3657 + "subParts": [{ 3658 + "partId": "a49d", 3659 + "type": "text/html", 3660 + "header:Content-Language": "en" 3661 + }, { 3662 + "partId": "bd48", 3663 + "type": "text/plain", 3664 + "header:Content-Language": "en" 3665 + }] 3666 + }, 3667 + "bodyValues": { 3668 + "bd48": { 3669 + "value": "I have the most brilliant plan. Let me tell 3670 + you all about it. What we do is, we", 3671 + "isTruncated": false 3672 + }, 3673 + "a49d": { 3674 + "value": "<!DOCTYPE html><html><head><title></title> 3675 + <style type=\"text/css\">div{font-size:16px}</style></head> 3676 + <body><div>I have the most <b>brilliant</b> plan. Let me 3677 + tell you all about it. What we do is, we</div></body> 3678 + </html>", 3679 + "isTruncated": false 3680 + } 3681 + } 3682 + } 3683 + }, 3684 + "destroy": [ "Mf40b5f831efa7233b9eb1c7f" ] 3685 + }, "0" ]] 3686 + 3687 + 3688 + 3689 + 3690 + 3691 + 3692 + 3693 + 3694 + 3695 + 3696 + 3697 + 3698 + Jenkins & Newman Standards Track [Page 66] 3699 + 3700 + RFC 8621 JMAP Mail August 2019 3701 + 3702 + 3703 + The server creates the new draft, deletes the old one, and sends the 3704 + success response: 3705 + 3706 + [[ "Email/set", { 3707 + "accountId": "ue150411c", 3708 + "oldState": "780839", 3709 + "newState": "780842", 3710 + "created": { 3711 + "k1546": { 3712 + "id": "Md45b47b4877521042cec0938", 3713 + "blobId": "Ge8de6c9f6de198239b982ea214e0f3a704e4af74", 3714 + "threadId": "Td957e72e89f516dc", 3715 + "size": 11721 3716 + } 3717 + }, 3718 + "destroyed": [ "Mf40b5f831efa7233b9eb1c7f" ], 3719 + ... 3720 + }, "0" ]] 3721 + 3722 + The client moves this draft to a different account. The only way to 3723 + do this is via the "Email/copy" method. It MUST set a new 3724 + "mailboxIds" property, since the current value will not be valid 3725 + Mailbox ids in the destination account: 3726 + 3727 + [[ "Email/copy", { 3728 + "fromAccountId": "ue150411c", 3729 + "accountId": "u6c6c41ac", 3730 + "create": { 3731 + "k45": { 3732 + "id": "Md45b47b4877521042cec0938", 3733 + "mailboxIds": { 3734 + "75a4c956": true 3735 + } 3736 + } 3737 + }, 3738 + "onSuccessDestroyOriginal": true 3739 + }, "0" ]] 3740 + 3741 + 3742 + 3743 + 3744 + 3745 + 3746 + 3747 + 3748 + 3749 + 3750 + 3751 + 3752 + 3753 + 3754 + Jenkins & Newman Standards Track [Page 67] 3755 + 3756 + RFC 8621 JMAP Mail August 2019 3757 + 3758 + 3759 + The server successfully copies the Email and deletes the original. 3760 + Due to the implicit call to "Email/set", there are two responses to 3761 + the single method call, both with the same method call id: 3762 + 3763 + [[ "Email/copy", { 3764 + "fromAccountId": "ue150411c", 3765 + "accountId": "u6c6c41ac", 3766 + "oldState": "7ee7e9263a6d", 3767 + "newState": "5a0d2447ed26", 3768 + "created": { 3769 + "k45": { 3770 + "id": "M138f9954a5cd2423daeafa55", 3771 + "blobId": "G6b9fb047cba722c48c611e79233d057c6b0b74e8", 3772 + "threadId": "T2f242ea424a4079a", 3773 + "size": 11721 3774 + } 3775 + }, 3776 + "notCreated": null 3777 + }, "0" ], 3778 + [ "Email/set", { 3779 + "accountId": "ue150411c", 3780 + "oldState": "780842", 3781 + "newState": "780871", 3782 + "destroyed": [ "Md45b47b4877521042cec0938" ], 3783 + ... 3784 + }, "0" ]] 3785 + 3786 + 5. Search Snippets 3787 + 3788 + When doing a search on a "String" property, the client may wish to 3789 + show the relevant section of the body that matches the search as a 3790 + preview and to highlight any matching terms in both this and the 3791 + subject of the Email. Search snippets represent this data. 3792 + 3793 + A *SearchSnippet* object has the following properties: 3794 + 3795 + o emailId: "Id" 3796 + 3797 + The Email id the snippet applies to. 3798 + 3799 + 3800 + 3801 + 3802 + 3803 + 3804 + 3805 + 3806 + 3807 + 3808 + 3809 + 3810 + Jenkins & Newman Standards Track [Page 68] 3811 + 3812 + RFC 8621 JMAP Mail August 2019 3813 + 3814 + 3815 + o subject: "String|null" 3816 + 3817 + If text from the filter matches the subject, this is the subject 3818 + of the Email with the following transformations: 3819 + 3820 + 1. Any instance of the following three characters MUST be 3821 + replaced by an appropriate HTML entity: & (ampersand), < 3822 + (less-than sign), and > (greater-than sign) [HTML]. Other 3823 + characters MAY also be replaced with an HTML entity form. 3824 + 3825 + 2. The matching words/phrases from the filter are wrapped in HTML 3826 + "<mark></mark>" tags. 3827 + 3828 + If the subject does not match text from the filter, this property 3829 + is null. 3830 + 3831 + o preview: "String|null" 3832 + 3833 + If text from the filter matches the plaintext or HTML body, this 3834 + is the relevant section of the body (converted to plaintext if 3835 + originally HTML), with the same transformations as the "subject" 3836 + property. It MUST NOT be bigger than 255 octets in size. If the 3837 + body does not contain a match for the text from the filter, this 3838 + property is null. 3839 + 3840 + What is a relevant section of the body for preview is server defined. 3841 + If the server is unable to determine search snippets, it MUST return 3842 + null for both the "subject" and "preview" properties. 3843 + 3844 + Note that unlike most data types, a SearchSnippet DOES NOT have a 3845 + property called "id". 3846 + 3847 + The following JMAP method is supported. 3848 + 3849 + 5.1. SearchSnippet/get 3850 + 3851 + To fetch search snippets, make a call to "SearchSnippet/get". It 3852 + takes the following arguments: 3853 + 3854 + o accountId: "Id" 3855 + 3856 + The id of the account to use. 3857 + 3858 + o filter: "FilterOperator|FilterCondition|null" 3859 + 3860 + The same filter as passed to "Email/query"; see the description of 3861 + this method in Section 4.4 for details. 3862 + 3863 + 3864 + 3865 + 3866 + Jenkins & Newman Standards Track [Page 69] 3867 + 3868 + RFC 8621 JMAP Mail August 2019 3869 + 3870 + 3871 + o emailIds: "Id[]" 3872 + 3873 + The ids of the Emails to fetch snippets for. 3874 + 3875 + The response has the following arguments: 3876 + 3877 + o accountId: "Id" 3878 + 3879 + The id of the account used for the call. 3880 + 3881 + o list: "SearchSnippet[]" 3882 + 3883 + An array of SearchSnippet objects for the requested Email ids. 3884 + This may not be in the same order as the ids that were in the 3885 + request. 3886 + 3887 + o notFound: "Id[]|null" 3888 + 3889 + An array of Email ids requested that could not be found, or null 3890 + if all ids were found. 3891 + 3892 + As the search snippets are derived from the message content and the 3893 + algorithm for doing so could change over time, fetching the same 3894 + snippets a second time MAY return a different result. However, the 3895 + previous value is not considered incorrect, so there is no state 3896 + string or update mechanism needed. 3897 + 3898 + The following additional errors may be returned instead of the 3899 + "SearchSnippet/get" response: 3900 + 3901 + "requestTooLarge": The number of "emailIds" requested by the client 3902 + exceeds the maximum number the server is willing to process in a 3903 + single method call. 3904 + 3905 + "unsupportedFilter": The server is unable to process the given 3906 + "filter" for any reason. 3907 + 3908 + 3909 + 3910 + 3911 + 3912 + 3913 + 3914 + 3915 + 3916 + 3917 + 3918 + 3919 + 3920 + 3921 + 3922 + Jenkins & Newman Standards Track [Page 70] 3923 + 3924 + RFC 8621 JMAP Mail August 2019 3925 + 3926 + 3927 + 5.2. Example 3928 + 3929 + Here, we did an "Email/query" to search for any Email in the account 3930 + containing the word "foo"; now, we are fetching the search snippets 3931 + for some of the ids that were returned in the results: 3932 + 3933 + [[ "SearchSnippet/get", { 3934 + "accountId": "ue150411c", 3935 + "filter": { 3936 + "text": "foo" 3937 + }, 3938 + "emailIds": [ 3939 + "M44200ec123de277c0c1ce69c", 3940 + "M7bcbcb0b58d7729686e83d99", 3941 + "M28d12783a0969584b6deaac0", 3942 + ... 3943 + ] 3944 + }, "0" ]] 3945 + 3946 + Example response: 3947 + 3948 + [[ "SearchSnippet/get", { 3949 + "accountId": "ue150411c", 3950 + "list": [{ 3951 + "emailId": "M44200ec123de277c0c1ce69c", 3952 + "subject": null, 3953 + "preview": null 3954 + }, { 3955 + "emailId": "M7bcbcb0b58d7729686e83d99", 3956 + "subject": "The <mark>Foo</mark>sball competition", 3957 + "preview": "...year the <mark>foo</mark>sball competition will 3958 + be held in the Stadium de ..." 3959 + }, { 3960 + "emailId": "M28d12783a0969584b6deaac0", 3961 + "subject": null, 3962 + "preview": "...the <mark>Foo</mark>/bar method results often 3963 + returns &lt;1 widget rather than the complete..." 3964 + }, 3965 + ... 3966 + ], 3967 + "notFound": null 3968 + }, "0" ]] 3969 + 3970 + 3971 + 3972 + 3973 + 3974 + 3975 + 3976 + 3977 + 3978 + Jenkins & Newman Standards Track [Page 71] 3979 + 3980 + RFC 8621 JMAP Mail August 2019 3981 + 3982 + 3983 + 6. Identities 3984 + 3985 + An *Identity* object stores information about an email address or 3986 + domain the user may send from. It has the following properties: 3987 + 3988 + o id: "Id" (immutable; server-set) 3989 + 3990 + The id of the Identity. 3991 + 3992 + o name: "String" (default: "") 3993 + 3994 + The "From" name the client SHOULD use when creating a new Email 3995 + from this Identity. 3996 + 3997 + o email: "String" (immutable) 3998 + 3999 + The "From" email address the client MUST use when creating a new 4000 + Email from this Identity. If the "mailbox" part of the address 4001 + (the section before the "@") is the single character "*" (e.g., 4002 + "*@example.com"), the client may use any valid address ending in 4003 + that domain (e.g., "foo@example.com"). 4004 + 4005 + o replyTo: "EmailAddress[]|null" (default: null) 4006 + 4007 + The Reply-To value the client SHOULD set when creating a new Email 4008 + from this Identity. 4009 + 4010 + o bcc: "EmailAddress[]|null" (default: null) 4011 + 4012 + The Bcc value the client SHOULD set when creating a new Email from 4013 + this Identity. 4014 + 4015 + o textSignature: "String" (default: "") 4016 + 4017 + A signature the client SHOULD insert into new plaintext messages 4018 + that will be sent from this Identity. Clients MAY ignore this 4019 + and/or combine this with a client-specific signature preference. 4020 + 4021 + o htmlSignature: "String" (default: "") 4022 + 4023 + A signature the client SHOULD insert into new HTML messages that 4024 + will be sent from this Identity. This text MUST be an HTML 4025 + snippet to be inserted into the "<body></body>" section of the 4026 + HTML. Clients MAY ignore this and/or combine this with a client- 4027 + specific signature preference. 4028 + 4029 + 4030 + 4031 + 4032 + 4033 + 4034 + Jenkins & Newman Standards Track [Page 72] 4035 + 4036 + RFC 8621 JMAP Mail August 2019 4037 + 4038 + 4039 + o mayDelete: "Boolean" (server-set) 4040 + 4041 + Is the user allowed to delete this Identity? Servers may wish to 4042 + set this to false for the user's username or other default 4043 + address. Attempts to destroy an Identity with "mayDelete: false" 4044 + will be rejected with a standard "forbidden" SetError. 4045 + 4046 + See the "Addresses" header form description in the Email object 4047 + (Section 4.1.2.3) for the definition of EmailAddress. 4048 + 4049 + Multiple identities with the same email address MAY exist, to allow 4050 + for different settings the user wants to pick between (for example, 4051 + with different names/signatures). 4052 + 4053 + The following JMAP methods are supported. 4054 + 4055 + 6.1. Identity/get 4056 + 4057 + This is a standard "/get" method as described in [RFC8620], 4058 + Section 5.1. The "ids" argument may be null to fetch all at once. 4059 + 4060 + 6.2. Identity/changes 4061 + 4062 + This is a standard "/changes" method as described in [RFC8620], 4063 + Section 5.2. 4064 + 4065 + 6.3. Identity/set 4066 + 4067 + This is a standard "/set" method as described in [RFC8620], 4068 + Section 5.3. The following extra SetError types are defined: 4069 + 4070 + For "create": 4071 + 4072 + o "forbiddenFrom": The user is not allowed to send from the address 4073 + given as the "email" property of the Identity. 4074 + 4075 + 6.4. Example 4076 + 4077 + Request: 4078 + 4079 + [ "Identity/get", { 4080 + "accountId": "acme" 4081 + }, "0" ] 4082 + 4083 + 4084 + 4085 + 4086 + 4087 + 4088 + 4089 + 4090 + Jenkins & Newman Standards Track [Page 73] 4091 + 4092 + RFC 8621 JMAP Mail August 2019 4093 + 4094 + 4095 + with response: 4096 + 4097 + [ "Identity/get", { 4098 + "accountId": "acme", 4099 + "state": "99401312ae-11-333", 4100 + "list": [ 4101 + { 4102 + "id": "XD-3301-222-11_22AAz", 4103 + "name": "Joe Bloggs", 4104 + "email": "joe@example.com", 4105 + "replyTo": null, 4106 + "bcc": [{ 4107 + "name": null, 4108 + "email": "joe+archive@example.com" 4109 + }], 4110 + "textSignature": "-- \nJoe Bloggs\nMaster of Email", 4111 + "htmlSignature": "<div><b>Joe Bloggs</b></div> 4112 + <div>Master of Email</div>", 4113 + "mayDelete": false 4114 + }, 4115 + { 4116 + "id": "XD-9911312-11_22AAz", 4117 + "name": "Joe B", 4118 + "email": "*@example.com", 4119 + "replyTo": null, 4120 + "bcc": null, 4121 + "textSignature": "", 4122 + "htmlSignature": "", 4123 + "mayDelete": true 4124 + } 4125 + ], 4126 + "notFound": [] 4127 + }, "0" ] 4128 + 4129 + 7. Email Submission 4130 + 4131 + An *EmailSubmission* object represents the submission of an Email for 4132 + delivery to one or more recipients. It has the following properties: 4133 + 4134 + o id: "Id" (immutable; server-set) 4135 + 4136 + The id of the EmailSubmission. 4137 + 4138 + o identityId: "Id" (immutable) 4139 + 4140 + The id of the Identity to associate with this submission. 4141 + 4142 + 4143 + 4144 + 4145 + 4146 + Jenkins & Newman Standards Track [Page 74] 4147 + 4148 + RFC 8621 JMAP Mail August 2019 4149 + 4150 + 4151 + o emailId: "Id" (immutable) 4152 + 4153 + The id of the Email to send. The Email being sent does not have 4154 + to be a draft, for example, when "redirecting" an existing Email 4155 + to a different address. 4156 + 4157 + o threadId: "Id" (immutable; server-set) 4158 + 4159 + The Thread id of the Email to send. This is set by the server to 4160 + the "threadId" property of the Email referenced by the "emailId". 4161 + 4162 + o envelope: "Envelope|null" (immutable) 4163 + 4164 + Information for use when sending via SMTP. An *Envelope* object 4165 + has the following properties: 4166 + 4167 + * mailFrom: "Address" 4168 + 4169 + The email address to use as the return address in the SMTP 4170 + submission, plus any parameters to pass with the MAIL FROM 4171 + address. The JMAP server MAY allow the address to be the empty 4172 + string. 4173 + 4174 + When a JMAP server performs an SMTP message submission, it MAY 4175 + use the same id string for the ENVID parameter [RFC3461] and 4176 + the EmailSubmission object id. Servers that do this MAY 4177 + replace a client-provided value for ENVID with a server- 4178 + provided value. 4179 + 4180 + * rcptTo: "Address[]" 4181 + 4182 + The email addresses to send the message to, and any RCPT TO 4183 + parameters to pass with the recipient. 4184 + 4185 + An *Address* object has the following properties: 4186 + 4187 + * email: "String" 4188 + 4189 + The email address being represented by the object. This is a 4190 + "Mailbox" as used in the Reverse-path or Forward-path of the 4191 + MAIL FROM or RCPT TO command in [RFC5321]. 4192 + 4193 + * parameters: "Object|null" 4194 + 4195 + Any parameters to send with the email address (either mail- 4196 + parameter or rcpt-parameter as appropriate, as specified in 4197 + [RFC5321]). If supplied, each key in the object is a parameter 4198 + name, and the value is either the parameter value (type 4199 + 4200 + 4201 + 4202 + Jenkins & Newman Standards Track [Page 75] 4203 + 4204 + RFC 8621 JMAP Mail August 2019 4205 + 4206 + 4207 + "String") or null if the parameter does not take a value. For 4208 + both name and value, any xtext or unitext encodings are removed 4209 + (see [RFC3461] and [RFC6533]) and JSON string encoding is 4210 + applied. 4211 + 4212 + If the "envelope" property is null or omitted on creation, the 4213 + server MUST generate this from the referenced Email as follows: 4214 + 4215 + * "mailFrom": The email address in the Sender header field, if 4216 + present; otherwise, it's the email address in the From header 4217 + field, if present. In either case, no parameters are added. 4218 + 4219 + If multiple addresses are present in one of these header 4220 + fields, or there is more than one Sender/From header field, the 4221 + server SHOULD reject the EmailSubmission as invalid; otherwise, 4222 + it MUST take the first address in the last Sender/From header 4223 + field. 4224 + 4225 + If the address found from this is not allowed by the Identity 4226 + associated with this submission, the "email" property from the 4227 + Identity MUST be used instead. 4228 + 4229 + * "rcptTo": The deduplicated set of email addresses from the To, 4230 + Cc, and Bcc header fields, if present, with no parameters for 4231 + any of them. 4232 + 4233 + o sendAt: "UTCDate" (immutable; server-set) 4234 + 4235 + The date the submission was/will be released for delivery. If the 4236 + client successfully used FUTURERELEASE [RFC4865] with the 4237 + submission, this MUST be the time when the server will release the 4238 + message; otherwise, it MUST be the time the EmailSubmission was 4239 + created. 4240 + 4241 + o undoStatus: "String" 4242 + 4243 + This represents whether the submission may be canceled. This is 4244 + server set on create and MUST be one of the following values: 4245 + 4246 + * "pending": It may be possible to cancel this submission. 4247 + 4248 + * "final": The message has been relayed to at least one recipient 4249 + in a manner that cannot be recalled. It is no longer possible 4250 + to cancel this submission. 4251 + 4252 + * "canceled": The submission was canceled and will not be 4253 + delivered to any recipient. 4254 + 4255 + 4256 + 4257 + 4258 + Jenkins & Newman Standards Track [Page 76] 4259 + 4260 + RFC 8621 JMAP Mail August 2019 4261 + 4262 + 4263 + On systems that do not support unsending, the value of this 4264 + property will always be "final". On systems that do support 4265 + canceling submission, it will start as "pending" and MAY 4266 + transition to "final" when the server knows it definitely cannot 4267 + recall the message, but it MAY just remain "pending". If in 4268 + pending state, a client can attempt to cancel the submission by 4269 + setting this property to "canceled"; if the update succeeds, the 4270 + submission was successfully canceled, and the message has not been 4271 + delivered to any of the original recipients. 4272 + 4273 + o deliveryStatus: "String[DeliveryStatus]|null" (server-set) 4274 + 4275 + This represents the delivery status for each of the submission's 4276 + recipients, if known. This property MAY not be supported by all 4277 + servers, in which case it will remain null. Servers that support 4278 + it SHOULD update the EmailSubmission object each time the status 4279 + of any of the recipients changes, even if some recipients are 4280 + still being retried. 4281 + 4282 + This value is a map from the email address of each recipient to a 4283 + DeliveryStatus object. 4284 + 4285 + A *DeliveryStatus* object has the following properties: 4286 + 4287 + * smtpReply: "String" 4288 + 4289 + The SMTP reply string returned for this recipient when the 4290 + server last tried to relay the message, or in a later Delivery 4291 + Status Notification (DSN, as defined in [RFC3464]) response for 4292 + the message. This SHOULD be the response to the RCPT TO stage, 4293 + unless this was accepted and the message as a whole was 4294 + rejected at the end of the DATA stage, in which case the DATA 4295 + stage reply SHOULD be used instead. 4296 + 4297 + Multi-line SMTP responses should be concatenated to a single 4298 + string as follows: 4299 + 4300 + + The hyphen following the SMTP code on all but the last line 4301 + is replaced with a space. 4302 + 4303 + + Any prefix in common with the first line is stripped from 4304 + lines after the first. 4305 + 4306 + + CRLF is replaced by a space. 4307 + 4308 + 4309 + 4310 + 4311 + 4312 + 4313 + 4314 + Jenkins & Newman Standards Track [Page 77] 4315 + 4316 + RFC 8621 JMAP Mail August 2019 4317 + 4318 + 4319 + For example: 4320 + 4321 + 550-5.7.1 Our system has detected that this message is 4322 + 550 5.7.1 likely spam. 4323 + 4324 + would become: 4325 + 4326 + 550 5.7.1 Our system has detected that this message is likely spam. 4327 + 4328 + For messages relayed via an alternative to SMTP, the server MAY 4329 + generate a synthetic string representing the status instead. 4330 + If it does this, the string MUST be of the following form: 4331 + 4332 + + A 3-digit SMTP reply code, as defined in [RFC5321], 4333 + Section 4.2.3. 4334 + 4335 + + Then a single space character. 4336 + 4337 + + Then an SMTP Enhanced Mail System Status Code as defined in 4338 + [RFC3463], with a registry defined in [RFC5248]. 4339 + 4340 + + Then a single space character. 4341 + 4342 + + Then an implementation-specific information string with a 4343 + human-readable explanation of the response. 4344 + 4345 + * delivered: "String" 4346 + 4347 + Represents whether the message has been successfully delivered 4348 + to the recipient. This MUST be one of the following values: 4349 + 4350 + + "queued": The message is in a local mail queue and the 4351 + status will change once it exits the local mail queues. The 4352 + "smtpReply" property may still change. 4353 + 4354 + + "yes": The message was successfully delivered to the mail 4355 + store of the recipient. The "smtpReply" property is final. 4356 + 4357 + + "no": Delivery to the recipient permanently failed. The 4358 + "smtpReply" property is final. 4359 + 4360 + + "unknown": The final delivery status is unknown, (e.g., it 4361 + was relayed to an external machine and no further 4362 + information is available). The "smtpReply" property may 4363 + still change if a DSN arrives. 4364 + 4365 + 4366 + 4367 + 4368 + 4369 + 4370 + Jenkins & Newman Standards Track [Page 78] 4371 + 4372 + RFC 8621 JMAP Mail August 2019 4373 + 4374 + 4375 + Note that successful relaying to an external SMTP server SHOULD 4376 + NOT be taken as an indication that the message has successfully 4377 + reached the final mail store. In this case though, the server 4378 + may receive a DSN response, if requested. 4379 + 4380 + If a DSN is received for the recipient with Action equal to 4381 + "delivered", as per [RFC3464], Section 2.3.3, then the 4382 + "delivered" property SHOULD be set to "yes"; if the Action 4383 + equals "failed", the property SHOULD be set to "no". Receipt 4384 + of any other DSN SHOULD NOT affect this property. 4385 + 4386 + The server MAY also set this property based on other feedback 4387 + channels. 4388 + 4389 + * displayed: "String" 4390 + 4391 + Represents whether the message has been displayed to the 4392 + recipient. This MUST be one of the following values: 4393 + 4394 + + "unknown": The display status is unknown. This is the 4395 + initial value. 4396 + 4397 + + "yes": The recipient's system claims the message content has 4398 + been displayed to the recipient. Note that there is no 4399 + guarantee that the recipient has noticed, read, or 4400 + understood the content. 4401 + 4402 + If a Message Disposition Notification (MDN) is received for 4403 + this recipient with Disposition-Type (as per [RFC8098], 4404 + Section 3.2.6.2) equal to "displayed", this property SHOULD be 4405 + set to "yes". 4406 + 4407 + The server MAY also set this property based on other feedback 4408 + channels. 4409 + 4410 + o dsnBlobIds: "Id[]" (server-set) 4411 + 4412 + A list of blob ids for DSNs [RFC3464] received for this 4413 + submission, in order of receipt, oldest first. The blob is the 4414 + whole MIME message (with a top-level content-type of "multipart/ 4415 + report"), as received. 4416 + 4417 + o mdnBlobIds: "Id[]" (server-set) 4418 + 4419 + A list of blob ids for MDNs [RFC8098] received for this 4420 + submission, in order of receipt, oldest first. The blob is the 4421 + whole MIME message (with a top-level content-type of "multipart/ 4422 + report"), as received. 4423 + 4424 + 4425 + 4426 + Jenkins & Newman Standards Track [Page 79] 4427 + 4428 + RFC 8621 JMAP Mail August 2019 4429 + 4430 + 4431 + JMAP servers MAY choose not to expose DSN and MDN responses as Email 4432 + objects if they correlate to an EmailSubmission object. It SHOULD 4433 + only do this if it exposes them in the "dsnBlobIds" and "mdnblobIds" 4434 + fields instead, and it expects the user to be using clients capable 4435 + of fetching and displaying delivery status via the EmailSubmission 4436 + object. 4437 + 4438 + For efficiency, a server MAY destroy EmailSubmission objects at any 4439 + time after the message is successfully sent or after it has finished 4440 + retrying to send the message. For very basic SMTP proxies, this MAY 4441 + be immediately after creation, as it has no way to assign a real id 4442 + and return the information again if fetched later. 4443 + 4444 + The following JMAP methods are supported. 4445 + 4446 + 7.1. EmailSubmission/get 4447 + 4448 + This is a standard "/get" method as described in [RFC8620], 4449 + Section 5.1. 4450 + 4451 + 7.2. EmailSubmission/changes 4452 + 4453 + This is a standard "/changes" method as described in [RFC8620], 4454 + Section 5.2. 4455 + 4456 + 7.3. EmailSubmission/query 4457 + 4458 + This is a standard "/query" method as described in [RFC8620], 4459 + Section 5.5. 4460 + 4461 + A *FilterCondition* object has the following properties, any of which 4462 + may be omitted: 4463 + 4464 + o identityIds: "Id[]" 4465 + 4466 + The EmailSubmission "identityId" property must be in this list to 4467 + match the condition. 4468 + 4469 + o emailIds: "Id[]" 4470 + 4471 + The EmailSubmission "emailId" property must be in this list to 4472 + match the condition. 4473 + 4474 + o threadIds: "Id[]" 4475 + 4476 + The EmailSubmission "threadId" property must be in this list to 4477 + match the condition. 4478 + 4479 + 4480 + 4481 + 4482 + Jenkins & Newman Standards Track [Page 80] 4483 + 4484 + RFC 8621 JMAP Mail August 2019 4485 + 4486 + 4487 + o undoStatus: "String" 4488 + 4489 + The EmailSubmission "undoStatus" property must be identical to the 4490 + value given to match the condition. 4491 + 4492 + o before: "UTCDate" 4493 + 4494 + The "sendAt" property of the EmailSubmission object must be before 4495 + this date-time to match the condition. 4496 + 4497 + o after: "UTCDate" 4498 + 4499 + The "sendAt" property of the EmailSubmission object must be the 4500 + same as or after this date-time to match the condition. 4501 + 4502 + An EmailSubmission object matches the FilterCondition if and only if 4503 + all of the given conditions match. If zero properties are specified, 4504 + it is automatically true for all objects. 4505 + 4506 + The following EmailSubmission properties MUST be supported for 4507 + sorting: 4508 + 4509 + o "emailId" 4510 + 4511 + o "threadId" 4512 + 4513 + o "sentAt" 4514 + 4515 + 7.4. EmailSubmission/queryChanges 4516 + 4517 + This is a standard "/queryChanges" method as described in [RFC8620], 4518 + Section 5.6. 4519 + 4520 + 7.5. EmailSubmission/set 4521 + 4522 + This is a standard "/set" method as described in [RFC8620], 4523 + Section 5.3 with the following two additional request arguments: 4524 + 4525 + o onSuccessUpdateEmail: "Id[PatchObject]|null" 4526 + 4527 + A map of EmailSubmission id to an object containing properties to 4528 + update on the Email object referenced by the EmailSubmission if 4529 + the create/update/destroy succeeds. (For references to 4530 + EmailSubmissions created in the same "/set" invocation, this is 4531 + equivalent to a creation-reference, so the id will be the creation 4532 + id prefixed with a "#".) 4533 + 4534 + 4535 + 4536 + 4537 + 4538 + Jenkins & Newman Standards Track [Page 81] 4539 + 4540 + RFC 8621 JMAP Mail August 2019 4541 + 4542 + 4543 + o onSuccessDestroyEmail: "Id[]|null" 4544 + 4545 + A list of EmailSubmission ids for which the Email with the 4546 + corresponding "emailId" should be destroyed if the create/update/ 4547 + destroy succeeds. (For references to EmailSubmission creations, 4548 + this is equivalent to a creation-reference, so the id will be the 4549 + creation id prefixed with a "#".) 4550 + 4551 + After all create/update/destroy items in the "EmailSubmission/set" 4552 + invocation have been processed, a single implicit "Email/set" call 4553 + MUST be made to perform any changes requested in these two arguments. 4554 + The response to this MUST be returned after the "EmailSubmission/set" 4555 + response. 4556 + 4557 + An Email is sent by creating an EmailSubmission object. When 4558 + processing each create, the server must check that the message is 4559 + valid, and the user has sufficient authorisation to send it. If the 4560 + creation succeeds, the message will be sent to the recipients given 4561 + in the envelope "rcptTo" parameter. The server MUST remove any Bcc 4562 + header field present on the message during delivery. The server MAY 4563 + add or remove other header fields from the submitted message or make 4564 + further alterations in accordance with the server's policy during 4565 + delivery. 4566 + 4567 + If the referenced Email is destroyed at any point after the 4568 + EmailSubmission object is created, this MUST NOT change the behaviour 4569 + of the submission (i.e., it does not cancel a future send). The 4570 + "emailId" and "threadId" properties of the EmailSubmission object 4571 + remain, but trying to fetch them (with a standard "Email/get" call) 4572 + will return a "notFound" error if the corresponding objects have been 4573 + destroyed. 4574 + 4575 + Similarly, destroying an EmailSubmission object MUST NOT affect the 4576 + deliveries it represents. It purely removes the record of the 4577 + submission. The server MAY automatically destroy EmailSubmission 4578 + objects after some time or in response to other triggers, and MAY 4579 + forbid the client from manually destroying EmailSubmission objects. 4580 + 4581 + If the message to be sent is larger than the server supports sending, 4582 + a standard "tooLarge" SetError MUST be returned. A "maxSize" 4583 + "UnsignedInt" property MUST be present on the SetError specifying the 4584 + maximum size of a message that may be sent, in octets. 4585 + 4586 + If the Email or Identity id given cannot be found, the submission 4587 + creation is rejected with a standard "invalidProperties" SetError. 4588 + 4589 + 4590 + 4591 + 4592 + 4593 + 4594 + Jenkins & Newman Standards Track [Page 82] 4595 + 4596 + RFC 8621 JMAP Mail August 2019 4597 + 4598 + 4599 + The following extra SetError types are defined: 4600 + 4601 + For "create": 4602 + 4603 + o "invalidEmail" - The Email to be sent is invalid in some way. The 4604 + SetError SHOULD contain a property called "properties" of type 4605 + "String[]" that lists *all* the properties of the Email that were 4606 + invalid. 4607 + 4608 + o "tooManyRecipients" - The envelope (supplied or generated) has 4609 + more recipients than the server allows. A "maxRecipients" 4610 + "UnsignedInt" property MUST also be present on the SetError 4611 + specifying the maximum number of allowed recipients. 4612 + 4613 + o "noRecipients" - The envelope (supplied or generated) does not 4614 + have any rcptTo email addresses. 4615 + 4616 + o "invalidRecipients" - The "rcptTo" property of the envelope 4617 + (supplied or generated) contains at least one rcptTo value, which 4618 + is not a valid email address for sending to. An 4619 + "invalidRecipients" "String[]" property MUST also be present on 4620 + the SetError, which is a list of the invalid addresses. 4621 + 4622 + o "forbiddenMailFrom" - The server does not permit the user to send 4623 + a message with the envelope From address [RFC5321]. 4624 + 4625 + o "forbiddenFrom" - The server does not permit the user to send a 4626 + message with the From header field [RFC5322] of the message to be 4627 + sent. 4628 + 4629 + o "forbiddenToSend" - The user does not have permission to send at 4630 + all right now for some reason. A "description" "String" property 4631 + MAY be present on the SetError object to display to the user why 4632 + they are not permitted. 4633 + 4634 + For "update": 4635 + 4636 + o "cannotUnsend" - The client attempted to update the "undoStatus" 4637 + of a valid EmailSubmission object from "pending" to "canceled", 4638 + but the message cannot be unsent. 4639 + 4640 + 4641 + 4642 + 4643 + 4644 + 4645 + 4646 + 4647 + 4648 + 4649 + 4650 + Jenkins & Newman Standards Track [Page 83] 4651 + 4652 + RFC 8621 JMAP Mail August 2019 4653 + 4654 + 4655 + 7.5.1. Example 4656 + 4657 + The following example presumes a draft of the Email to be sent has 4658 + already been saved, and its Email id is "M7f6ed5bcfd7e2604d1753f6c". 4659 + This call then sends the Email immediately, and if successful, 4660 + removes the "$draft" flag and moves it from the drafts folder (which 4661 + has Mailbox id "7cb4e8ee-df87-4757-b9c4-2ea1ca41b38e") to the sent 4662 + folder (which we presume has Mailbox id "73dbcb4b-bffc-48bd-8c2a- 4663 + a2e91ca672f6"). 4664 + 4665 + [[ "EmailSubmission/set", { 4666 + "accountId": "ue411d190", 4667 + "create": { 4668 + "k1490": { 4669 + "identityId": "I64588216", 4670 + "emailId": "M7f6ed5bcfd7e2604d1753f6c", 4671 + "envelope": { 4672 + "mailFrom": { 4673 + "email": "john@example.com", 4674 + "parameters": null 4675 + }, 4676 + "rcptTo": [{ 4677 + "email": "jane@example.com", 4678 + "parameters": null 4679 + }, 4680 + ... 4681 + ] 4682 + } 4683 + } 4684 + }, 4685 + "onSuccessUpdateEmail": { 4686 + "#k1490": { 4687 + "mailboxIds/7cb4e8ee-df87-4757-b9c4-2ea1ca41b38e": null, 4688 + "mailboxIds/73dbcb4b-bffc-48bd-8c2a-a2e91ca672f6": true, 4689 + "keywords/$draft": null 4690 + } 4691 + } 4692 + }, "0" ]] 4693 + 4694 + 4695 + 4696 + 4697 + 4698 + 4699 + 4700 + 4701 + 4702 + 4703 + 4704 + 4705 + 4706 + Jenkins & Newman Standards Track [Page 84] 4707 + 4708 + RFC 8621 JMAP Mail August 2019 4709 + 4710 + 4711 + A successful response might look like this. Note that there are two 4712 + responses due to the implicit "Email/set" call, but both have the 4713 + same method call id as they are due to the same call in the request: 4714 + 4715 + [[ "EmailSubmission/set", { 4716 + "accountId": "ue411d190", 4717 + "oldState": "012421s6-8nrq-4ps4-n0p4-9330r951ns21", 4718 + "newState": "355421f6-8aed-4cf4-a0c4-7377e951af36", 4719 + "created": { 4720 + "k1490": { 4721 + "id": "ES-3bab7f9a-623e-4acf-99a5-2e67facb02a0" 4722 + } 4723 + } 4724 + }, "0" ], 4725 + [ "Email/set", { 4726 + "accountId": "ue411d190", 4727 + "oldState": "778193", 4728 + "newState": "778197", 4729 + "updated": { 4730 + "M7f6ed5bcfd7e2604d1753f6c": null 4731 + } 4732 + }, "0" ]] 4733 + 4734 + Suppose instead an admin has removed sending rights for the user, so 4735 + the submission is rejected with a "forbiddenToSend" error. The 4736 + description argument of the error is intended for display to the 4737 + user, so it should be localised appropriately. Let's suppose the 4738 + request was sent with an Accept-Language header like this: 4739 + 4740 + Accept-Language: de;q=0.9,en;q=0.8 4741 + 4742 + 4743 + 4744 + 4745 + 4746 + 4747 + 4748 + 4749 + 4750 + 4751 + 4752 + 4753 + 4754 + 4755 + 4756 + 4757 + 4758 + 4759 + 4760 + 4761 + 4762 + Jenkins & Newman Standards Track [Page 85] 4763 + 4764 + RFC 8621 JMAP Mail August 2019 4765 + 4766 + 4767 + The server should attempt to choose the best localisation from those 4768 + it has available based on the Accept-Language header, as described in 4769 + [RFC8620], Section 3.8. If the server has English, French, and 4770 + German translations, it would choose German as the preferred language 4771 + and return a response like this: 4772 + 4773 + [[ "EmailSubmission/set", { 4774 + "accountId": "ue411d190", 4775 + "oldState": "012421s6-8nrq-4ps4-n0p4-9330r951ns21", 4776 + "newState": "012421s6-8nrq-4ps4-n0p4-9330r951ns21", 4777 + "notCreated": { 4778 + "k1490": { 4779 + "type": "forbiddenToSend", 4780 + "description": "Verzeihung, wegen verdaechtiger Aktivitaeten Ihres 4781 + Benutzerkontos haben wir den Versand von Nachrichten gesperrt. 4782 + Bitte wenden Sie sich fuer Hilfe an unser Support Team." 4783 + } 4784 + } 4785 + }, "0" ]] 4786 + 4787 + 8. Vacation Response 4788 + 4789 + A vacation response sends an automatic reply when a message is 4790 + delivered to the mail store, informing the original sender that their 4791 + message may not be read for some time. 4792 + 4793 + Automated message sending can produce undesirable behaviour. To 4794 + avoid this, implementors MUST follow the recommendations set forth in 4795 + [RFC3834]. 4796 + 4797 + The *VacationResponse* object represents the state of vacation- 4798 + response-related settings for an account. It has the following 4799 + properties: 4800 + 4801 + o id: "Id" (immutable; server-set) 4802 + 4803 + The id of the object. There is only ever one VacationResponse 4804 + object, and its id is "singleton". 4805 + 4806 + o isEnabled: "Boolean" 4807 + 4808 + Should a vacation response be sent if a message arrives between 4809 + the "fromDate" and "toDate"? 4810 + 4811 + 4812 + 4813 + 4814 + 4815 + 4816 + 4817 + 4818 + Jenkins & Newman Standards Track [Page 86] 4819 + 4820 + RFC 8621 JMAP Mail August 2019 4821 + 4822 + 4823 + o fromDate: "UTCDate|null" 4824 + 4825 + If "isEnabled" is true, messages that arrive on or after this 4826 + date-time (but before the "toDate" if defined) should receive the 4827 + user's vacation response. If null, the vacation response is 4828 + effective immediately. 4829 + 4830 + o toDate: "UTCDate|null" 4831 + 4832 + If "isEnabled" is true, messages that arrive before this date-time 4833 + (but on or after the "fromDate" if defined) should receive the 4834 + user's vacation response. If null, the vacation response is 4835 + effective indefinitely. 4836 + 4837 + o subject: "String|null" 4838 + 4839 + The subject that will be used by the message sent in response to 4840 + messages when the vacation response is enabled. If null, an 4841 + appropriate subject SHOULD be set by the server. 4842 + 4843 + o textBody: "String|null" 4844 + 4845 + The plaintext body to send in response to messages when the 4846 + vacation response is enabled. If this is null, the server SHOULD 4847 + generate a plaintext body part from the "htmlBody" when sending 4848 + vacation responses but MAY choose to send the response as HTML 4849 + only. If both "textBody" and "htmlBody" are null, an appropriate 4850 + default body SHOULD be generated for responses by the server. 4851 + 4852 + o htmlBody: "String|null" 4853 + 4854 + The HTML body to send in response to messages when the vacation 4855 + response is enabled. If this is null, the server MAY choose to 4856 + generate an HTML body part from the "textBody" when sending 4857 + vacation responses or MAY choose to send the response as plaintext 4858 + only. 4859 + 4860 + The following JMAP methods are supported. 4861 + 4862 + 8.1. VacationResponse/get 4863 + 4864 + This is a standard "/get" method as described in [RFC8620], 4865 + Section 5.1. 4866 + 4867 + There MUST only be exactly one VacationResponse object in an account. 4868 + It MUST have the id "singleton". 4869 + 4870 + 4871 + 4872 + 4873 + 4874 + Jenkins & Newman Standards Track [Page 87] 4875 + 4876 + RFC 8621 JMAP Mail August 2019 4877 + 4878 + 4879 + 8.2. VacationResponse/set 4880 + 4881 + This is a standard "/set" method as described in [RFC8620], 4882 + Section 5.3. 4883 + 4884 + 9. Security Considerations 4885 + 4886 + All security considerations of JMAP [RFC8620] apply to this 4887 + specification. Additional considerations specific to the data types 4888 + and functionality introduced by this document are described in the 4889 + following subsections. 4890 + 4891 + 9.1. EmailBodyPart Value 4892 + 4893 + Service providers typically perform security filtering on incoming 4894 + messages, and it's important that the detection of content-type and 4895 + charset for the security filter aligns with the heuristics performed 4896 + by JMAP servers. Servers that apply heuristics to determine the 4897 + content-type or charset for an EmailBodyValue SHOULD document the 4898 + heuristics and provide a mechanism to turn them off in the event they 4899 + are misaligned with the security filter used at a particular mail 4900 + host. 4901 + 4902 + Automatic conversion of charsets that allow hidden channels for ASCII 4903 + text, such as UTF-7, have been problematic for security filters in 4904 + the past, so server implementations can mitigate this risk by having 4905 + such conversions off-by-default and/or separately configurable. 4906 + 4907 + To allow the client to restrict the volume of data it can receive in 4908 + response to a request, a maximum length may be requested for the data 4909 + returned for a textual body part. However, truncating the data may 4910 + change the semantic meaning, for example, truncating a URL changes 4911 + its location. Servers that scan for links to malicious sites should 4912 + take care to either ensure truncation is not at a semantically 4913 + significant point or rescan the truncated value for malicious content 4914 + before returning it. 4915 + 4916 + 9.2. HTML Email Display 4917 + 4918 + HTML message bodies provide richer formatting for messages but 4919 + present a number of security challenges, especially when embedded in 4920 + a webmail context in combination with interface HTML. Clients that 4921 + render HTML messages should carefully consider the potential risks, 4922 + including: 4923 + 4924 + 4925 + 4926 + 4927 + 4928 + 4929 + 4930 + Jenkins & Newman Standards Track [Page 88] 4931 + 4932 + RFC 8621 JMAP Mail August 2019 4933 + 4934 + 4935 + o Embedded JavaScript can rewrite the message to change its content 4936 + on subsequent opening, allowing users to be mislead. In webmail 4937 + systems, if run in the same origin as the interface, it can access 4938 + and exfiltrate all private data accessible to the user, including 4939 + all other messages and potentially contacts, calendar events, 4940 + settings, and credentials. It can also rewrite the interface to 4941 + undetectably phish passwords. A compromise is likely to be 4942 + persistent, not just for the duration of page load, due to 4943 + exfiltration of session credentials or installation of a service 4944 + worker that can intercept all subsequent network requests 4945 + (however, this would only be possible if blob downloads are also 4946 + available on the same origin, and the service worker script is 4947 + attached to the message). 4948 + 4949 + o HTML documents may load content directly from the Internet rather 4950 + than just referencing attached resources. For example, you may 4951 + have an "<img>" tag with an external "src" attribute. This may 4952 + leak to the sender when a message is opened, as well as the IP 4953 + address of the recipient. Cookies may also be sent and set by the 4954 + server, allowing tracking between different messages and even 4955 + website visits and advertising profiles. 4956 + 4957 + o In webmail systems, CSS can break the layout or create phishing 4958 + vulnerabilities. For example, the use of "position:fixed" can 4959 + allow a message to draw content outside of its normal bounds, 4960 + potentially clickjacking a real interface element. 4961 + 4962 + o If in a webmail context and not inside a separate frame, any 4963 + styles defined in CSS rules will apply to interface elements as 4964 + well if the selector matches, allowing the interface to be 4965 + modified. Similarly, any interface styles that match elements in 4966 + the message will alter their appearance, potentially breaking the 4967 + layout of the message. 4968 + 4969 + o The link text in HTML has no necessary correlation with the actual 4970 + target of the link, which can be used to make phishing attacks 4971 + more convincing. 4972 + 4973 + o Links opened from a message or embedded external content may leak 4974 + private info in the Referer header sent by default in most 4975 + systems. 4976 + 4977 + o Forms can be used to mimic login boxes, providing a potent 4978 + phishing vector if allowed to submit directly from the message 4979 + display. 4980 + 4981 + 4982 + 4983 + 4984 + 4985 + 4986 + Jenkins & Newman Standards Track [Page 89] 4987 + 4988 + RFC 8621 JMAP Mail August 2019 4989 + 4990 + 4991 + There are a number of ways clients can mitigate these issues, and a 4992 + defence-in-depth approach that uses a combination of techniques will 4993 + provide the strongest security. 4994 + 4995 + o HTML can be filtered before rendering, stripping potentially 4996 + malicious content. Sanitising HTML correctly is tricky, and 4997 + implementors are strongly recommended to use a well-tested library 4998 + with a carefully vetted whitelist-only approach. New features 4999 + with unexpected security characteristics may be added to HTML 5000 + rendering engines in the future; a blacklist approach is likely to 5001 + result in security issues. 5002 + 5003 + Subtle differences in parsing of HTML can introduce security 5004 + flaws: to filter with 100% accuracy, you need to use the same 5005 + parser that the HTML rendering engine will use. 5006 + 5007 + o Encapsulating the message in an "<iframe sandbox>", as defined in 5008 + [HTML], Section 4.7.6, can help mitigate a number of risks. This 5009 + will: 5010 + 5011 + * Disable JavaScript. 5012 + 5013 + * Disable form submission. 5014 + 5015 + * Prevent drawing outside of its bounds or conflicts between 5016 + message CSS and interface CSS. 5017 + 5018 + * Establish a unique anonymous origin, separate to the containing 5019 + origin. 5020 + 5021 + o A strong Content Security Policy (see <https://www.w3.org/TR/ 5022 + CSP3/>) can, among other things, block JavaScript and the loading 5023 + of external content should it manage to evade the filter. 5024 + 5025 + o The leakage of information in the Referer header can be mitigated 5026 + with the use of a referrer policy (see <https://www.w3.org/TR/ 5027 + referrer-policy/>). 5028 + 5029 + o A "crossorigin=anonymous" attribute on tags that load remote 5030 + content can prevent cookies from being sent. 5031 + 5032 + o If adding "target=_blank" to open links in new tabs, also add 5033 + "rel=noopener" to ensure the page that opens cannot change the URL 5034 + in the original tab to redirect the user to a phishing site. 5035 + 5036 + As highly complex software components, HTML rendering engines 5037 + increase the attack surface of a client considerably, especially when 5038 + being used to process untrusted, potentially malicious content. 5039 + 5040 + 5041 + 5042 + Jenkins & Newman Standards Track [Page 90] 5043 + 5044 + RFC 8621 JMAP Mail August 2019 5045 + 5046 + 5047 + Serious bugs have been found in image decoders, JavaScript engines, 5048 + and HTML parsers in the past, which could lead to full system 5049 + compromise. Clients using an engine should ensure they get the 5050 + latest version and continue to incorporate any security patches 5051 + released by the vendor. 5052 + 5053 + 9.3. Multiple Part Display 5054 + 5055 + Messages may consist of multiple parts to be displayed sequentially 5056 + as a body. Clients MUST render each part in isolation and MUST NOT 5057 + concatenate the raw text values to render. Doing so may change the 5058 + overall semantics of the message. If the client or server is 5059 + decrypting a Pretty Good Privacy (PGP) or S/MIME encrypted part, 5060 + concatenating with other parts may leak the decrypted text to an 5061 + attacker, as described in [EFAIL]. 5062 + 5063 + 9.4. Email Submission 5064 + 5065 + SMTP submission servers [RFC6409] use a number of mechanisms to 5066 + mitigate damage caused by compromised user accounts and end-user 5067 + systems including rate limiting, anti-virus/anti-spam milters (mail 5068 + filters), and other technologies. The technologies work better when 5069 + they have more information about the client connection. If JMAP 5070 + email submission is implemented as a proxy to an SMTP submission 5071 + server, it is useful to communicate this information from the JMAP 5072 + proxy to the submission server. The de facto XCLIENT extension to 5073 + SMTP [XCLIENT] can be used to do this, but use of an authenticated 5074 + channel is recommended to limit use of that extension to explicitly 5075 + authorised proxies. 5076 + 5077 + JMAP servers that proxy to an SMTP submission server SHOULD allow use 5078 + of the submissions port [RFC8314]. Implementation of a mechanism 5079 + similar to SMTP XCLIENT is strongly encouraged. While Simple 5080 + Authentication and Security Layer (SASL) PLAIN over TLS [RFC4616] is 5081 + presently the mandatory-to-implement mechanism for interoperability 5082 + with SMTP submission servers [RFC4954], a JMAP submission proxy 5083 + SHOULD implement and prefer a stronger mechanism for this use case 5084 + such as TLS client certificate authentication with SASL EXTERNAL 5085 + ([RFC4422], Appendix A) or Salted Challenge Response Authentication 5086 + Mechanism (SCRAM) [RFC7677]. 5087 + 5088 + In the event the JMAP server directly relays mail to SMTP servers in 5089 + other administrative domains, implementation of the de facto [milter] 5090 + protocol is strongly encouraged to integrate with third-party 5091 + products that address security issues including anti-virus/anti-spam, 5092 + reputation protection, compliance archiving, and data loss 5093 + prevention. Proxying to a local SMTP submission server may be a 5094 + simpler way to provide such security services. 5095 + 5096 + 5097 + 5098 + Jenkins & Newman Standards Track [Page 91] 5099 + 5100 + RFC 8621 JMAP Mail August 2019 5101 + 5102 + 5103 + 9.5. Partial Account Access 5104 + 5105 + A user may only have permission to access a subset of the data that 5106 + exists in an account. To avoid leaking unauthorised information, in 5107 + such a situation, the server MUST treat any data the user does not 5108 + have permission to access the same as if it did not exist. 5109 + 5110 + For example, suppose user A has an account with two Mailboxes, inbox 5111 + and sent, but only shares the inbox with user B. In this case, when 5112 + user B fetches Mailboxes for this account, the server MUST behave as 5113 + though the sent Mailbox did not exist. Similarly, when querying or 5114 + fetching Email objects, it MUST treat any messages that just belong 5115 + to the sent Mailbox as though they did not exist. Fetching Thread 5116 + objects MUST only return ids for Email objects the user has 5117 + permission to access; if none, the Thread again MUST be treated the 5118 + same as if it did not exist. 5119 + 5120 + If the server forbids a single account from having two identical 5121 + messages, or two messages with the same Message-Id header field, a 5122 + user with write access can use the error returned by trying to 5123 + create/import such a message to detect whether it already exists in 5124 + an inaccessible portion of the account. 5125 + 5126 + 9.6. Permission to Send from an Address 5127 + 5128 + In recent years, the email ecosystem has moved towards associating 5129 + trust with the From address in the message [RFC5322], particularly 5130 + with schemes such as Domain-based Message Authentication, Reporting, 5131 + and Conformance (DMARC) [RFC7489]. 5132 + 5133 + The set of Identity objects (see Section 6) in an account lets the 5134 + client know which email addresses the user has permission to send 5135 + from. Each email submission is associated with an Identity, and 5136 + servers SHOULD reject submissions where the From header field of the 5137 + message does not correspond to the associated Identity. 5138 + 5139 + The server MAY allow an exception to send an exact copy of an 5140 + existing message received into the mail store to another address 5141 + (otherwise known as "redirecting" or "bouncing"), although it is 5142 + RECOMMENDED the server limit this to destinations the user has 5143 + verified they also control. 5144 + 5145 + If the user attempts to create a new Identity object, the server MUST 5146 + reject it with the appropriate error if the user does not have 5147 + permission to use that email address to send from. 5148 + 5149 + 5150 + 5151 + 5152 + 5153 + 5154 + Jenkins & Newman Standards Track [Page 92] 5155 + 5156 + RFC 8621 JMAP Mail August 2019 5157 + 5158 + 5159 + The SMTP MAIL FROM address [RFC5321] is often confused with the From 5160 + message header field [RFC5322]. The user generally only ever sees 5161 + the address in the message header field, and this is the primary one 5162 + to enforce. However, the server MUST also enforce appropriate 5163 + restrictions on the MAIL FROM address [RFC5321] to stop the user from 5164 + flooding a third-party address with bounces and non-delivery notices. 5165 + 5166 + The JMAP submission model provides separate errors for impermissible 5167 + addresses in either context. 5168 + 5169 + 10. IANA Considerations 5170 + 5171 + 10.1. JMAP Capability Registration for "mail" 5172 + 5173 + IANA has registered the "mail" JMAP Capability as follows: 5174 + 5175 + Capability Name: urn:ietf:params:jmap:mail 5176 + 5177 + Specification document: this document 5178 + 5179 + Intended use: common 5180 + 5181 + Change Controller: IETF 5182 + 5183 + Security and privacy considerations: this document, Section 9 5184 + 5185 + 10.2. JMAP Capability Registration for "submission" 5186 + 5187 + IANA has registered the "submission" JMAP Capability as follows: 5188 + 5189 + Capability Name: urn:ietf:params:jmap:submission 5190 + 5191 + Specification document: this document 5192 + 5193 + Intended use: common 5194 + 5195 + Change Controller: IETF 5196 + 5197 + Security and privacy considerations: this document, Section 9 5198 + 5199 + 5200 + 5201 + 5202 + 5203 + 5204 + 5205 + 5206 + 5207 + 5208 + 5209 + 5210 + Jenkins & Newman Standards Track [Page 93] 5211 + 5212 + RFC 8621 JMAP Mail August 2019 5213 + 5214 + 5215 + 10.3. JMAP Capability Registration for "vacationresponse" 5216 + 5217 + IANA has registered the "vacationresponse" JMAP Capability as 5218 + follows: 5219 + 5220 + Capability Name: urn:ietf:params:jmap:vacationresponse 5221 + 5222 + Specification document: this document 5223 + 5224 + Intended use: common 5225 + 5226 + Change Controller: IETF 5227 + 5228 + Security and privacy considerations: this document, Section 9 5229 + 5230 + 10.4. IMAP and JMAP Keywords Registry 5231 + 5232 + This document makes two changes to the IMAP keywords registry as 5233 + defined in [RFC5788]. 5234 + 5235 + First, the name of the registry is changed to the "IMAP and JMAP 5236 + Keywords" registry. 5237 + 5238 + Second, a scope column is added to the template and registry 5239 + indicating whether a keyword applies to "IMAP-only", "JMAP-only", 5240 + "both", or "reserved". All keywords already in the IMAP keyword 5241 + registry have been marked with a scope of "both". The "reserved" 5242 + status can be used to prevent future registration of a name that 5243 + would be confusing if registered. Registration of keywords with 5244 + scope "reserved" omit most fields in the registration template (see 5245 + registration of "$recent" below for an example); such registrations 5246 + are intended to be infrequent. 5247 + 5248 + IMAP clients MAY silently ignore any keywords marked "JMAP-only" or 5249 + "reserved" in the event they appear in protocol. JMAP clients MAY 5250 + silently ignore any keywords marked "IMAP-only" or "reserved" in the 5251 + event they appear in protocol. 5252 + 5253 + New "JMAP-only" keywords are registered in the following subsections. 5254 + These keywords correspond to IMAP system keywords and are thus not 5255 + appropriate for use in IMAP. These keywords cannot be subsequently 5256 + registered for use in IMAP except via standards action. 5257 + 5258 + 5259 + 5260 + 5261 + 5262 + 5263 + 5264 + 5265 + 5266 + Jenkins & Newman Standards Track [Page 94] 5267 + 5268 + RFC 8621 JMAP Mail August 2019 5269 + 5270 + 5271 + 10.4.1. Registration of JMAP Keyword "$draft" 5272 + 5273 + This registers the "JMAP-only" keyword "$draft" in the "IMAP and JMAP 5274 + Keywords" registry. 5275 + 5276 + Keyword name: $draft 5277 + 5278 + Scope: JMAP-only 5279 + 5280 + Purpose (description): This is set when the user wants to treat the 5281 + message as a draft the user is composing. This is the JMAP 5282 + equivalent of the IMAP \Draft flag. 5283 + 5284 + Private or Shared on a server: BOTH 5285 + 5286 + Is it an advisory keyword or may it cause an automatic action: 5287 + Automatic. If the account has an IMAP mailbox marked with the 5288 + \Drafts special use attribute [RFC6154], setting this flag MAY cause 5289 + the message to appear in that mailbox automatically. Certain JMAP 5290 + computed values such as "unreadEmails" will change as a result of 5291 + changing this flag. In addition, mail clients will typically present 5292 + draft messages in a composer window rather than a viewer window. 5293 + 5294 + When/by whom the keyword is set/cleared: This is typically set by a 5295 + JMAP client when referring to a draft message. One model for draft 5296 + Emails would result in clearing this flag in an "EmailSubmission/set" 5297 + operation with an "onSuccessUpdateEmail" argument. In a mail store 5298 + shared by JMAP and IMAP, this is also set and cleared as necessary so 5299 + it matches the IMAP \Draft flag. 5300 + 5301 + Related keywords: None 5302 + 5303 + Related IMAP/JMAP Capabilities: SPECIAL-USE [RFC6154] 5304 + 5305 + Security Considerations: A server implementing this keyword as a 5306 + shared keyword may disclose that a user considers the message a draft 5307 + message. This information would be exposed to other users with read 5308 + permission for the Mailbox keywords. 5309 + 5310 + Published specification: this document 5311 + 5312 + Person & email address to contact for further information: 5313 + JMAP mailing list <jmap@ietf.org> 5314 + 5315 + Intended usage: COMMON 5316 + 5317 + Owner/Change controller: IESG 5318 + 5319 + 5320 + 5321 + 5322 + Jenkins & Newman Standards Track [Page 95] 5323 + 5324 + RFC 8621 JMAP Mail August 2019 5325 + 5326 + 5327 + 10.4.2. Registration of JMAP Keyword "$seen" 5328 + 5329 + This registers the "JMAP-only" keyword "$seen" in the "IMAP and JMAP 5330 + Keywords" registry. 5331 + 5332 + Keyword name: $seen 5333 + 5334 + Scope: JMAP-only 5335 + 5336 + Purpose (description): This is set when the user wants to treat the 5337 + message as read. This is the JMAP equivalent of the IMAP \Seen flag. 5338 + 5339 + Private or Shared on a server: BOTH 5340 + 5341 + Is it an advisory keyword or may it cause an automatic action: 5342 + Advisory. However, certain JMAP computed values such as 5343 + "unreadEmails" will change as a result of changing this flag. 5344 + 5345 + When/by whom the keyword is set/cleared: This is set by a JMAP client 5346 + when it presents the message content to the user; clients often offer 5347 + an option to clear this flag. In a mail store shared by JMAP and 5348 + IMAP, this is also set and cleared as necessary so it matches the 5349 + IMAP \Seen flag. 5350 + 5351 + Related keywords: None 5352 + 5353 + Related IMAP/JMAP Capabilities: None 5354 + 5355 + Security Considerations: A server implementing this keyword as a 5356 + shared keyword may disclose that a user considers the message to have 5357 + been read. This information would be exposed to other users with 5358 + read permission for the Mailbox keywords. 5359 + 5360 + Published specification: this document 5361 + 5362 + Person & email address to contact for further information: 5363 + JMAP mailing list <jmap@ietf.org> 5364 + 5365 + Intended usage: COMMON 5366 + 5367 + Owner/Change controller: IESG 5368 + 5369 + 5370 + 5371 + 5372 + 5373 + 5374 + 5375 + 5376 + 5377 + 5378 + Jenkins & Newman Standards Track [Page 96] 5379 + 5380 + RFC 8621 JMAP Mail August 2019 5381 + 5382 + 5383 + 10.4.3. Registration of JMAP Keyword "$flagged" 5384 + 5385 + This registers the "JMAP-only" keyword "$flagged" in the "IMAP and 5386 + JMAP Keywords" registry. 5387 + 5388 + Keyword name: $flagged 5389 + 5390 + Scope: JMAP-only 5391 + 5392 + Purpose (description): This is set when the user wants to treat the 5393 + message as flagged for urgent/special attention. This is the JMAP 5394 + equivalent of the IMAP \Flagged flag. 5395 + 5396 + Private or Shared on a server: BOTH 5397 + 5398 + Is it an advisory keyword or may it cause an automatic action: 5399 + Automatic. If the account has an IMAP mailbox marked with the 5400 + \Flagged special use attribute [RFC6154], setting this flag MAY cause 5401 + the message to appear in that mailbox automatically. 5402 + 5403 + When/by whom the keyword is set/cleared: JMAP clients typically allow 5404 + a user to set/clear this flag as desired. In a mail store shared by 5405 + JMAP and IMAP, this is also set and cleared as necessary so it 5406 + matches the IMAP \Flagged flag. 5407 + 5408 + Related keywords: None 5409 + 5410 + Related IMAP/JMAP Capabilities: SPECIAL-USE [RFC6154] 5411 + 5412 + Security Considerations: A server implementing this keyword as a 5413 + shared keyword may disclose that a user considers the message as 5414 + flagged for urgent/special attention. This information would be 5415 + exposed to other users with read permission for the Mailbox keywords. 5416 + 5417 + Published specification: this document 5418 + 5419 + Person & email address to contact for further information: 5420 + JMAP mailing list <jmap@ietf.org> 5421 + 5422 + Intended usage: COMMON 5423 + 5424 + Owner/Change controller: IESG 5425 + 5426 + 5427 + 5428 + 5429 + 5430 + 5431 + 5432 + 5433 + 5434 + Jenkins & Newman Standards Track [Page 97] 5435 + 5436 + RFC 8621 JMAP Mail August 2019 5437 + 5438 + 5439 + 10.4.4. Registration of JMAP Keyword "$answered" 5440 + 5441 + This registers the "JMAP-only" keyword "$answered" in the "IMAP and 5442 + JMAP Keywords" registry. 5443 + 5444 + Keyword name: $answered 5445 + 5446 + Scope: JMAP-only 5447 + 5448 + Purpose (description): This is set when the message has been 5449 + answered. 5450 + 5451 + Private or Shared on a server: BOTH 5452 + 5453 + Is it an advisory keyword or may it cause an automatic action: 5454 + Advisory. 5455 + 5456 + When/by whom the keyword is set/cleared: JMAP clients typically set 5457 + this when submitting a reply or answer to the message. It may be set 5458 + by the "EmailSubmission/set" operation with an "onSuccessUpdateEmail" 5459 + argument. In a mail store shared by JMAP and IMAP, this is also set 5460 + and cleared as necessary so it matches the IMAP \Answered flag. 5461 + 5462 + Related keywords: None 5463 + 5464 + Related IMAP/JMAP Capabilities: None 5465 + 5466 + Security Considerations: A server implementing this keyword as a 5467 + shared keyword may disclose that a user has replied to a message. 5468 + This information would be exposed to other users with read permission 5469 + for the Mailbox keywords. 5470 + 5471 + Published specification: this document 5472 + 5473 + Person & email address to contact for further information: 5474 + JMAP mailing list <jmap@ietf.org> 5475 + 5476 + Intended usage: COMMON 5477 + 5478 + Owner/Change controller: IESG 5479 + 5480 + 5481 + 5482 + 5483 + 5484 + 5485 + 5486 + 5487 + 5488 + 5489 + 5490 + Jenkins & Newman Standards Track [Page 98] 5491 + 5492 + RFC 8621 JMAP Mail August 2019 5493 + 5494 + 5495 + 10.4.5. Registration of "$recent" Keyword 5496 + 5497 + This registers the keyword "$recent" in the "IMAP and JMAP Keywords" 5498 + registry. 5499 + 5500 + Keyword name: $recent 5501 + 5502 + Scope: reserved 5503 + 5504 + Purpose (description): This keyword is not used to avoid confusion 5505 + with the IMAP \Recent system flag. 5506 + 5507 + Published specification: this document 5508 + 5509 + Person & email address to contact for further information: 5510 + JMAP mailing list <jmap@ietf.org> 5511 + 5512 + Owner/Change controller: IESG 5513 + 5514 + 10.5. IMAP Mailbox Name Attributes Registry 5515 + 5516 + 10.5.1. Registration of "inbox" Role 5517 + 5518 + This registers the "JMAP-only" "inbox" attribute in the "IMAP Mailbox 5519 + Name Attributes" registry, as established in [RFC8457]. 5520 + 5521 + Attribute Name: Inbox 5522 + 5523 + Description: New mail is delivered here by default. 5524 + 5525 + Reference: This document, Section 10.5.1 5526 + 5527 + Usage Notes: JMAP only 5528 + 5529 + 5530 + 5531 + 5532 + 5533 + 5534 + 5535 + 5536 + 5537 + 5538 + 5539 + 5540 + 5541 + 5542 + 5543 + 5544 + 5545 + 5546 + Jenkins & Newman Standards Track [Page 99] 5547 + 5548 + RFC 8621 JMAP Mail August 2019 5549 + 5550 + 5551 + 10.6. JMAP Error Codes Registry 5552 + 5553 + The following subsections register several new error codes in the 5554 + "JMAP Error Codes" registry, as defined in [RFC8620]. 5555 + 5556 + 10.6.1. mailboxHasChild 5557 + 5558 + JMAP Error Code: mailboxHasChild 5559 + 5560 + Intended use: common 5561 + 5562 + Change controller: IETF 5563 + 5564 + Reference: This document, Section 2.5 5565 + 5566 + Description: The Mailbox still has at least one child Mailbox. The 5567 + client MUST remove these before it can delete the parent Mailbox. 5568 + 5569 + 10.6.2. mailboxHasEmail 5570 + 5571 + JMAP Error Code: mailboxHasEmail 5572 + 5573 + Intended use: common 5574 + 5575 + Change controller: IETF 5576 + 5577 + Reference: This document, Section 2.5 5578 + 5579 + Description: The Mailbox has at least one message assigned to it, and 5580 + the onDestroyRemoveEmails argument was false. 5581 + 5582 + 10.6.3. blobNotFound 5583 + 5584 + JMAP Error Code: blobNotFound 5585 + 5586 + Intended use: common 5587 + 5588 + Change controller: IETF 5589 + 5590 + Reference: This document, Section 4.6 5591 + 5592 + Description: At least one blob id referenced in the object doesn't 5593 + exist. 5594 + 5595 + 5596 + 5597 + 5598 + 5599 + 5600 + 5601 + 5602 + Jenkins & Newman Standards Track [Page 100] 5603 + 5604 + RFC 8621 JMAP Mail August 2019 5605 + 5606 + 5607 + 10.6.4. tooManyKeywords 5608 + 5609 + JMAP Error Code: tooManyKeywords 5610 + 5611 + Intended use: common 5612 + 5613 + Change controller: IETF 5614 + 5615 + Reference: This document, Section 4.6 5616 + 5617 + Description: The change to the Email's keywords would exceed a 5618 + server-defined maximum. 5619 + 5620 + 10.6.5. tooManyMailboxes 5621 + 5622 + JMAP Error Code: tooManyMailboxes 5623 + 5624 + Intended use: common 5625 + 5626 + Change controller: IETF 5627 + 5628 + Reference: This document, Section 4.6 5629 + 5630 + Description: The change to the set of Mailboxes that this Email is in 5631 + would exceed a server-defined maximum. 5632 + 5633 + 10.6.6. invalidEmail 5634 + 5635 + JMAP Error Code: invalidEmail 5636 + 5637 + Intended use: common 5638 + 5639 + Change controller: IETF 5640 + 5641 + Reference: This document, Section 7.5 5642 + 5643 + Description: The Email to be sent is invalid in some way. 5644 + 5645 + 5646 + 5647 + 5648 + 5649 + 5650 + 5651 + 5652 + 5653 + 5654 + 5655 + 5656 + 5657 + 5658 + Jenkins & Newman Standards Track [Page 101] 5659 + 5660 + RFC 8621 JMAP Mail August 2019 5661 + 5662 + 5663 + 10.6.7. tooManyRecipients 5664 + 5665 + JMAP Error Code: tooManyRecipients 5666 + 5667 + Intended use: common 5668 + 5669 + Change controller: IETF 5670 + 5671 + Reference: This document, Section 7.5 5672 + 5673 + Description: The envelope [RFC5321] (supplied or generated) has more 5674 + recipients than the server allows. 5675 + 5676 + 10.6.8. noRecipients 5677 + 5678 + JMAP Error Code: noRecipients 5679 + 5680 + Intended use: common 5681 + 5682 + Change controller: IETF 5683 + 5684 + Reference: This document, Section 7.5 5685 + 5686 + Description: The envelope [RFC5321] (supplied or generated) does not 5687 + have any rcptTo email addresses. 5688 + 5689 + 10.6.9. invalidRecipients 5690 + 5691 + JMAP Error Code: invalidRecipients 5692 + 5693 + Intended use: common 5694 + 5695 + Change controller: IETF 5696 + 5697 + Reference: This document, Section 7.5 5698 + 5699 + Description: The rcptTo property of the envelope [RFC5321] (supplied 5700 + or generated) contains at least one rcptTo value that is not a valid 5701 + email address for sending to. 5702 + 5703 + 5704 + 5705 + 5706 + 5707 + 5708 + 5709 + 5710 + 5711 + 5712 + 5713 + 5714 + Jenkins & Newman Standards Track [Page 102] 5715 + 5716 + RFC 8621 JMAP Mail August 2019 5717 + 5718 + 5719 + 10.6.10. forbiddenMailFrom 5720 + 5721 + JMAP Error Code: forbiddenMailFrom 5722 + 5723 + Intended use: common 5724 + 5725 + Change controller: IETF 5726 + 5727 + Reference: This document, Section 7.5 5728 + 5729 + Description: The server does not permit the user to send a message 5730 + with this envelope From address [RFC5321]. 5731 + 5732 + 10.6.11. forbiddenFrom 5733 + 5734 + JMAP Error Code: forbiddenFrom 5735 + 5736 + Intended use: common 5737 + 5738 + Change controller: IETF 5739 + 5740 + Reference: This document, Sections 6.3 and 7.5 5741 + 5742 + Description: The server does not permit the user to send a message 5743 + with the From header field [RFC5322] of the message to be sent. 5744 + 5745 + 10.6.12. forbiddenToSend 5746 + 5747 + JMAP Error Code: forbiddenToSend 5748 + 5749 + Intended use: common 5750 + 5751 + Change controller: IETF 5752 + 5753 + Reference: This document, Section 7.5 5754 + 5755 + Description: The user does not have permission to send at all right 5756 + now. 5757 + 5758 + 5759 + 5760 + 5761 + 5762 + 5763 + 5764 + 5765 + 5766 + 5767 + 5768 + 5769 + 5770 + Jenkins & Newman Standards Track [Page 103] 5771 + 5772 + RFC 8621 JMAP Mail August 2019 5773 + 5774 + 5775 + 11. References 5776 + 5777 + 11.1. Normative References 5778 + 5779 + [HTML] Faulkner, S., Eicholz, A., Leithead, T., Danilo, A., and 5780 + S. Moon, "HTML 5.2", World Wide Web Consortium 5781 + Recommendation REC-html52-20171214, December 2017, 5782 + <https://www.w3.org/TR/html52/>. 5783 + 5784 + [RFC1870] Klensin, J., Freed, N., and K. Moore, "SMTP Service 5785 + Extension for Message Size Declaration", STD 10, RFC 1870, 5786 + DOI 10.17487/RFC1870, November 1995, 5787 + <https://www.rfc-editor.org/info/rfc1870>. 5788 + 5789 + [RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail 5790 + Extensions (MIME) Part One: Format of Internet Message 5791 + Bodies", RFC 2045, DOI 10.17487/RFC2045, November 1996, 5792 + <https://www.rfc-editor.org/info/rfc2045>. 5793 + 5794 + [RFC2047] Moore, K., "MIME (Multipurpose Internet Mail Extensions) 5795 + Part Three: Message Header Extensions for Non-ASCII Text", 5796 + RFC 2047, DOI 10.17487/RFC2047, November 1996, 5797 + <https://www.rfc-editor.org/info/rfc2047>. 5798 + 5799 + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 5800 + Requirement Levels", BCP 14, RFC 2119, 5801 + DOI 10.17487/RFC2119, March 1997, 5802 + <https://www.rfc-editor.org/info/rfc2119>. 5803 + 5804 + [RFC2231] Freed, N. and K. Moore, "MIME Parameter Value and Encoded 5805 + Word Extensions: Character Sets, Languages, and 5806 + Continuations", RFC 2231, DOI 10.17487/RFC2231, November 5807 + 1997, <https://www.rfc-editor.org/info/rfc2231>. 5808 + 5809 + [RFC2369] Neufeld, G. and J. Baer, "The Use of URLs as Meta-Syntax 5810 + for Core Mail List Commands and their Transport through 5811 + Message Header Fields", RFC 2369, DOI 10.17487/RFC2369, 5812 + July 1998, <https://www.rfc-editor.org/info/rfc2369>. 5813 + 5814 + [RFC2392] Levinson, E., "Content-ID and Message-ID Uniform Resource 5815 + Locators", RFC 2392, DOI 10.17487/RFC2392, August 1998, 5816 + <https://www.rfc-editor.org/info/rfc2392>. 5817 + 5818 + [RFC2557] Palme, J., Hopmann, A., and N. Shelness, "MIME 5819 + Encapsulation of Aggregate Documents, such as HTML 5820 + (MHTML)", RFC 2557, DOI 10.17487/RFC2557, March 1999, 5821 + <https://www.rfc-editor.org/info/rfc2557>. 5822 + 5823 + 5824 + 5825 + 5826 + Jenkins & Newman Standards Track [Page 104] 5827 + 5828 + RFC 8621 JMAP Mail August 2019 5829 + 5830 + 5831 + [RFC2852] Newman, D., "Deliver By SMTP Service Extension", RFC 2852, 5832 + DOI 10.17487/RFC2852, June 2000, 5833 + <https://www.rfc-editor.org/info/rfc2852>. 5834 + 5835 + [RFC3282] Alvestrand, H., "Content Language Headers", RFC 3282, 5836 + DOI 10.17487/RFC3282, May 2002, 5837 + <https://www.rfc-editor.org/info/rfc3282>. 5838 + 5839 + [RFC3461] Moore, K., "Simple Mail Transfer Protocol (SMTP) Service 5840 + Extension for Delivery Status Notifications (DSNs)", 5841 + RFC 3461, DOI 10.17487/RFC3461, January 2003, 5842 + <https://www.rfc-editor.org/info/rfc3461>. 5843 + 5844 + [RFC3463] Vaudreuil, G., "Enhanced Mail System Status Codes", 5845 + RFC 3463, DOI 10.17487/RFC3463, January 2003, 5846 + <https://www.rfc-editor.org/info/rfc3463>. 5847 + 5848 + [RFC3464] Moore, K. and G. Vaudreuil, "An Extensible Message Format 5849 + for Delivery Status Notifications", RFC 3464, 5850 + DOI 10.17487/RFC3464, January 2003, 5851 + <https://www.rfc-editor.org/info/rfc3464>. 5852 + 5853 + [RFC3834] Moore, K., "Recommendations for Automatic Responses to 5854 + Electronic Mail", RFC 3834, DOI 10.17487/RFC3834, August 5855 + 2004, <https://www.rfc-editor.org/info/rfc3834>. 5856 + 5857 + [RFC4314] Melnikov, A., "IMAP4 Access Control List (ACL) Extension", 5858 + RFC 4314, DOI 10.17487/RFC4314, December 2005, 5859 + <https://www.rfc-editor.org/info/rfc4314>. 5860 + 5861 + [RFC4422] Melnikov, A., Ed. and K. Zeilenga, Ed., "Simple 5862 + Authentication and Security Layer (SASL)", RFC 4422, 5863 + DOI 10.17487/RFC4422, June 2006, 5864 + <https://www.rfc-editor.org/info/rfc4422>. 5865 + 5866 + [RFC4616] Zeilenga, K., Ed., "The PLAIN Simple Authentication and 5867 + Security Layer (SASL) Mechanism", RFC 4616, 5868 + DOI 10.17487/RFC4616, August 2006, 5869 + <https://www.rfc-editor.org/info/rfc4616>. 5870 + 5871 + [RFC4865] White, G. and G. Vaudreuil, "SMTP Submission Service 5872 + Extension for Future Message Release", RFC 4865, 5873 + DOI 10.17487/RFC4865, May 2007, 5874 + <https://www.rfc-editor.org/info/rfc4865>. 5875 + 5876 + 5877 + 5878 + 5879 + 5880 + 5881 + 5882 + Jenkins & Newman Standards Track [Page 105] 5883 + 5884 + RFC 8621 JMAP Mail August 2019 5885 + 5886 + 5887 + [RFC4954] Siemborski, R., Ed. and A. Melnikov, Ed., "SMTP Service 5888 + Extension for Authentication", RFC 4954, 5889 + DOI 10.17487/RFC4954, July 2007, 5890 + <https://www.rfc-editor.org/info/rfc4954>. 5891 + 5892 + [RFC5198] Klensin, J. and M. Padlipsky, "Unicode Format for Network 5893 + Interchange", RFC 5198, DOI 10.17487/RFC5198, March 2008, 5894 + <https://www.rfc-editor.org/info/rfc5198>. 5895 + 5896 + [RFC5248] Hansen, T. and J. Klensin, "A Registry for SMTP Enhanced 5897 + Mail System Status Codes", BCP 138, RFC 5248, 5898 + DOI 10.17487/RFC5248, June 2008, 5899 + <https://www.rfc-editor.org/info/rfc5248>. 5900 + 5901 + [RFC5256] Crispin, M. and K. Murchison, "Internet Message Access 5902 + Protocol - SORT and THREAD Extensions", RFC 5256, 5903 + DOI 10.17487/RFC5256, June 2008, 5904 + <https://www.rfc-editor.org/info/rfc5256>. 5905 + 5906 + [RFC5321] Klensin, J., "Simple Mail Transfer Protocol", RFC 5321, 5907 + DOI 10.17487/RFC5321, October 2008, 5908 + <https://www.rfc-editor.org/info/rfc5321>. 5909 + 5910 + [RFC5322] Resnick, P., Ed., "Internet Message Format", RFC 5322, 5911 + DOI 10.17487/RFC5322, October 2008, 5912 + <https://www.rfc-editor.org/info/rfc5322>. 5913 + 5914 + [RFC5788] Melnikov, A. and D. Cridland, "IMAP4 Keyword Registry", 5915 + RFC 5788, DOI 10.17487/RFC5788, March 2010, 5916 + <https://www.rfc-editor.org/info/rfc5788>. 5917 + 5918 + [RFC6154] Leiba, B. and J. Nicolson, "IMAP LIST Extension for 5919 + Special-Use Mailboxes", RFC 6154, DOI 10.17487/RFC6154, 5920 + March 2011, <https://www.rfc-editor.org/info/rfc6154>. 5921 + 5922 + [RFC6409] Gellens, R. and J. Klensin, "Message Submission for Mail", 5923 + STD 72, RFC 6409, DOI 10.17487/RFC6409, November 2011, 5924 + <https://www.rfc-editor.org/info/rfc6409>. 5925 + 5926 + [RFC6532] Yang, A., Steele, S., and N. Freed, "Internationalized 5927 + Email Headers", RFC 6532, DOI 10.17487/RFC6532, February 5928 + 2012, <https://www.rfc-editor.org/info/rfc6532>. 5929 + 5930 + [RFC6533] Hansen, T., Ed., Newman, C., and A. Melnikov, 5931 + "Internationalized Delivery Status and Disposition 5932 + Notifications", RFC 6533, DOI 10.17487/RFC6533, February 5933 + 2012, <https://www.rfc-editor.org/info/rfc6533>. 5934 + 5935 + 5936 + 5937 + 5938 + Jenkins & Newman Standards Track [Page 106] 5939 + 5940 + RFC 8621 JMAP Mail August 2019 5941 + 5942 + 5943 + [RFC6710] Melnikov, A. and K. Carlberg, "Simple Mail Transfer 5944 + Protocol Extension for Message Transfer Priorities", 5945 + RFC 6710, DOI 10.17487/RFC6710, August 2012, 5946 + <https://www.rfc-editor.org/info/rfc6710>. 5947 + 5948 + [RFC7677] Hansen, T., "SCRAM-SHA-256 and SCRAM-SHA-256-PLUS Simple 5949 + Authentication and Security Layer (SASL) Mechanisms", 5950 + RFC 7677, DOI 10.17487/RFC7677, November 2015, 5951 + <https://www.rfc-editor.org/info/rfc7677>. 5952 + 5953 + [RFC8098] Hansen, T., Ed. and A. Melnikov, Ed., "Message Disposition 5954 + Notification", STD 85, RFC 8098, DOI 10.17487/RFC8098, 5955 + February 2017, <https://www.rfc-editor.org/info/rfc8098>. 5956 + 5957 + [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 5958 + 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 5959 + May 2017, <https://www.rfc-editor.org/info/rfc8174>. 5960 + 5961 + [RFC8314] Moore, K. and C. Newman, "Cleartext Considered Obsolete: 5962 + Use of Transport Layer Security (TLS) for Email Submission 5963 + and Access", RFC 8314, DOI 10.17487/RFC8314, January 2018, 5964 + <https://www.rfc-editor.org/info/rfc8314>. 5965 + 5966 + [RFC8457] Leiba, B., Ed., "IMAP "$Important" Keyword and 5967 + "\Important" Special-Use Attribute", RFC 8457, 5968 + DOI 10.17487/RFC8457, September 2018, 5969 + <https://www.rfc-editor.org/info/rfc8457>. 5970 + 5971 + [RFC8474] Gondwana, B., Ed., "IMAP Extension for Object 5972 + Identifiers", RFC 8474, DOI 10.17487/RFC8474, September 5973 + 2018, <https://www.rfc-editor.org/info/rfc8474>. 5974 + 5975 + [RFC8620] Jenkins, N. and C. Newman, "The JSON Meta Application 5976 + Protocol", RFC 8620, DOI 10.17487/RFC8620, June 2019, 5977 + <https://www.rfc-editor.org/info/rfc8620>. 5978 + 5979 + 11.2. Informative References 5980 + 5981 + [EFAIL] Poddebniak, D., Dresen, C., Mueller, J., Ising, F., 5982 + Schinzel, S., Friedberger, S., Somorovsky, J., and J. 5983 + Schwenk, "Efail: Breaking S/MIME and OpenPGP Email 5984 + Encryption using Exfiltration Channels", August 2018, 5985 + <https://www.usenix.org/system/files/conference/ 5986 + usenixsecurity18/sec18-poddebniak.pdf>. 5987 + 5988 + [milter] Postfix, "Postfix before-queue Milter support", 2019, 5989 + <http://www.postfix.org/MILTER_README.html>. 5990 + 5991 + 5992 + 5993 + 5994 + Jenkins & Newman Standards Track [Page 107] 5995 + 5996 + RFC 8621 JMAP Mail August 2019 5997 + 5998 + 5999 + [RFC3501] Crispin, M., "INTERNET MESSAGE ACCESS PROTOCOL - VERSION 6000 + 4rev1", RFC 3501, DOI 10.17487/RFC3501, March 2003, 6001 + <https://www.rfc-editor.org/info/rfc3501>. 6002 + 6003 + [RFC7489] Kucherawy, M., Ed. and E. Zwicky, Ed., "Domain-based 6004 + Message Authentication, Reporting, and Conformance 6005 + (DMARC)", RFC 7489, DOI 10.17487/RFC7489, March 2015, 6006 + <https://www.rfc-editor.org/info/rfc7489>. 6007 + 6008 + [XCLIENT] Postfix, "Postfix XCLIENT Howto", 2019, 6009 + <http://www.postfix.org/XCLIENT_README.html>. 6010 + 6011 + Authors' Addresses 6012 + 6013 + Neil Jenkins 6014 + Fastmail 6015 + PO Box 234, Collins St. West 6016 + Melbourne, VIC 8007 6017 + Australia 6018 + 6019 + Email: neilj@fastmailteam.com 6020 + URI: https://www.fastmail.com 6021 + 6022 + 6023 + Chris Newman 6024 + Oracle 6025 + 440 E. Huntington Dr., Suite 400 6026 + Arcadia, CA 91006 6027 + United States of America 6028 + 6029 + Email: chris.newman@oracle.com 6030 + 6031 + 6032 + 6033 + 6034 + 6035 + 6036 + 6037 + 6038 + 6039 + 6040 + 6041 + 6042 + 6043 + 6044 + 6045 + 6046 + 6047 + 6048 + 6049 + 6050 + Jenkins & Newman Standards Track [Page 108] 6051 +