···
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
14
+
The JSON Meta Application Protocol (JMAP) for Mail
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
27
+
This is an Internet Standards Track document.
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.
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.
41
+
Copyright (c) 2019 IETF Trust and the persons identified as the
42
+
document authors. All rights reserved.
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.
58
+
Jenkins & Newman Standards Track [Page 1]
60
+
RFC 8621 JMAP Mail August 2019
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
114
+
Jenkins & Newman Standards Track [Page 2]
116
+
RFC 8621 JMAP Mail August 2019
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
170
+
Jenkins & Newman Standards Track [Page 3]
172
+
RFC 8621 JMAP Mail August 2019
175
+
11. References . . . . . . . . . . . . . . . . . . . . . . . . . 104
176
+
11.1. Normative References . . . . . . . . . . . . . . . . . . 104
177
+
11.2. Informative References . . . . . . . . . . . . . . . . . 107
178
+
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 108
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
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
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).
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
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.
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.
215
+
1.1. Notational Conventions
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.
226
+
Jenkins & Newman Standards Track [Page 4]
228
+
RFC 8621 JMAP Mail August 2019
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
236
+
Servers MUST support all properties specified for the new data types
237
+
defined in this document.
241
+
This document uses the same terminology as in the core JMAP
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
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.
253
+
1.3. Additions to the Capabilities Object
255
+
The capabilities object is returned as part of the JMAP Session
256
+
object; see [RFC8620], Section 2.
258
+
This document defines three additional capability URIs.
260
+
1.3.1. urn:ietf:params:jmap:mail
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
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:
271
+
o maxMailboxesPerEmail: "UnsignedInt|null"
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).
282
+
Jenkins & Newman Standards Track [Page 5]
284
+
RFC 8621 JMAP Mail August 2019
287
+
o maxMailboxDepth: "UnsignedInt|null"
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
293
+
o maxSizeMailboxName: "UnsignedInt"
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.
299
+
o maxSizeAttachmentsPerEmail: "UnsignedInt"
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-
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.
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.
324
+
o emailQuerySortOptions: "String[]"
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
338
+
Jenkins & Newman Standards Track [Page 6]
340
+
RFC 8621 JMAP Mail August 2019
343
+
o mayCreateTopLevelMailbox: "Boolean"
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
350
+
1.3.2. urn:ietf:params:jmap:submission
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.
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:
360
+
o maxDelayedSend: "UnsignedInt"
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.
366
+
o submissionExtensions: "String[String[]]"
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".
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).
382
+
Examples of Submission extensions to include:
384
+
* FUTURERELEASE [RFC4865]
390
+
* DELIVERYBY [RFC2852]
394
+
Jenkins & Newman Standards Track [Page 7]
396
+
RFC 8621 JMAP Mail August 2019
399
+
* MT-PRIORITY [RFC6710]
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.
405
+
The full IANA registry of submission extensions can be found at
406
+
<https://www.iana.org/assignments/mail-parameters>.
408
+
1.3.3. urn:ietf:params:jmap:vacationresponse
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.
415
+
1.4. Data Type Support in Different Accounts
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.
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.
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.
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).
450
+
Jenkins & Newman Standards Track [Page 8]
452
+
RFC 8621 JMAP Mail August 2019
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
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.
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.
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
485
+
A *Mailbox* object has the following properties:
487
+
o id: "Id" (immutable; server-set)
489
+
The id of the Mailbox.
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).
506
+
Jenkins & Newman Standards Track [Page 9]
508
+
RFC 8621 JMAP Mail August 2019
511
+
o parentId: "Id|null" (default: null)
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.
518
+
o role: "String|null" (default: null)
520
+
Identifies Mailboxes that have a particular common purpose (e.g.,
521
+
the "inbox"), regardless of the "name" property (which may be
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.
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.
539
+
An account is not required to have Mailboxes with any particular
542
+
o sortOrder: "UnsignedInt" (default: 0)
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.
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.
554
+
o totalEmails: "UnsignedInt" (server-set)
556
+
The number of Emails in this Mailbox.
562
+
Jenkins & Newman Standards Track [Page 10]
564
+
RFC 8621 JMAP Mail August 2019
567
+
o unreadEmails: "UnsignedInt" (server-set)
569
+
The number of Emails in this Mailbox that have neither the "$seen"
570
+
keyword nor the "$draft" keyword.
572
+
o totalThreads: "UnsignedInt" (server-set)
574
+
The number of Threads where at least one Email in the Thread is in
577
+
o unreadThreads: "UnsignedInt" (server-set)
579
+
An indication of the number of "unread" Threads in the Mailbox.
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.
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:
598
+
1. Emails that are *only* in the trash (and no other Mailbox) are
599
+
ignored when calculating the "unreadThreads" count of other
602
+
2. Emails that are *not* in the trash are ignored when
603
+
calculating the "unreadThreads" count for the trash Mailbox.
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.
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.
618
+
Jenkins & Newman Standards Track [Page 11]
620
+
RFC 8621 JMAP Mail August 2019
623
+
o myRights: "MailboxRights" (server-set)
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:
630
+
* mayReadItems: "Boolean"
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).
640
+
* mayAddItems: "Boolean"
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".
645
+
* mayRemoveItems: "Boolean"
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).
652
+
* maySetSeen: "Boolean"
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".
659
+
* maySetKeywords: "Boolean"
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".
666
+
* mayCreateChild: "Boolean"
668
+
The user may create a Mailbox with this Mailbox as its parent.
669
+
Corresponds to IMAP ACL "k".
674
+
Jenkins & Newman Standards Track [Page 12]
676
+
RFC 8621 JMAP Mail August 2019
679
+
* mayRename: "Boolean"
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).
685
+
* mayDelete: "Boolean"
687
+
The user may delete the Mailbox itself. Corresponds to IMAP
688
+
ACL "x" (although this covers both rename and delete
691
+
* maySubmit: "Boolean"
693
+
Messages may be submitted directly to this Mailbox.
694
+
Corresponds to IMAP ACL "p".
696
+
o isSubscribed: "Boolean"
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.
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
715
+
This property corresponds to IMAP [RFC3501] mailbox subscriptions.
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).
722
+
The following JMAP methods are supported.
730
+
Jenkins & Newman Standards Track [Page 13]
732
+
RFC 8621 JMAP Mail August 2019
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.
740
+
2.2. Mailbox/changes
742
+
This is a standard "/changes" method as described in [RFC8620],
743
+
Section 5.2 but with one extra argument to the response:
745
+
o updatedProperties: "String[]|null"
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
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
763
+
This is a standard "/query" method as described in [RFC8620],
764
+
Section 5.5 but with the following additional request argument:
766
+
o sortAsTree: "Boolean" (default: false)
768
+
If true, when sorting the query results and comparing Mailboxes A
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.
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.
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
786
+
Jenkins & Newman Standards Track [Page 14]
788
+
RFC 8621 JMAP Mail August 2019
791
+
o filterAsTree: "Boolean" (default: false)
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.
796
+
A *FilterCondition* object has the following properties, any of which
799
+
o parentId: "Id|null"
801
+
The Mailbox "parentId" property must match the given value
806
+
The Mailbox "name" property contains the given string.
808
+
o role: "String|null"
810
+
The Mailbox "role" property must match the given value exactly.
812
+
o hasAnyRole: "Boolean"
814
+
If true, a Mailbox matches if it has any non-null value for its
817
+
o isSubscribed: "Boolean"
819
+
The "isSubscribed" property of the Mailbox must be identical to
820
+
the value given to match the condition.
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.
826
+
The following Mailbox properties MUST be supported for sorting:
832
+
2.4. Mailbox/queryChanges
834
+
This is a standard "/queryChanges" method as described in [RFC8620],
842
+
Jenkins & Newman Standards Track [Page 15]
844
+
RFC 8621 JMAP Mail August 2019
849
+
This is a standard "/set" method as described in [RFC8620],
850
+
Section 5.3 but with the following additional request argument:
852
+
o onDestroyRemoveEmails: "Boolean" (default: false)
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.
860
+
The following extra SetError types are defined:
864
+
o "mailboxHasChild": The Mailbox still has at least one child
865
+
Mailbox. The client MUST remove these before it can delete the
868
+
o "mailboxHasEmail": The Mailbox has at least one Email assigned to
869
+
it, and the "onDestroyRemoveEmails" argument was false.
898
+
Jenkins & Newman Standards Track [Page 16]
900
+
RFC 8621 JMAP Mail August 2019
905
+
Fetching all Mailboxes in an account:
907
+
[[ "Mailbox/get", {
908
+
"accountId": "u33084183",
914
+
[[ "Mailbox/get", {
915
+
"accountId": "u33084183",
918
+
"id": "MB23cfa8094c0f41e6",
923
+
"totalEmails": 16307,
924
+
"unreadEmails": 13905,
925
+
"totalThreads": 5833,
926
+
"unreadThreads": 5128,
928
+
"mayAddItems": true,
929
+
"mayRename": false,
931
+
"mayDelete": false,
932
+
"maySetKeywords": true,
933
+
"mayRemoveItems": true,
934
+
"mayCreateChild": true,
935
+
"maySetSeen": true,
936
+
"mayReadItems": true
938
+
"isSubscribed": true
940
+
"id": "MB674cc24095db49ce",
941
+
"name": "Important mail",
954
+
Jenkins & Newman Standards Track [Page 17]
956
+
RFC 8621 JMAP Mail August 2019
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
963
+
[[ "Mailbox/changes", {
964
+
"accountId": "u33084183",
965
+
"sinceState": "78540"
968
+
"accountId": "u33084183",
971
+
"name": "Mailbox/changes",
976
+
"accountId": "u33084183",
979
+
"name": "Mailbox/changes",
984
+
"name": "Mailbox/changes",
985
+
"path": "/updatedProperties"
1010
+
Jenkins & Newman Standards Track [Page 18]
1012
+
RFC 8621 JMAP Mail August 2019
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:
1020
+
[[ "Mailbox/changes", {
1021
+
"accountId": "u33084183",
1022
+
"oldState": "78541",
1023
+
"newState": "78542",
1024
+
"hasMoreChanges": false,
1025
+
"updatedProperties": [
1026
+
"totalEmails", "unreadEmails",
1027
+
"totalThreads", "unreadThreads"
1030
+
"updated": ["MB23cfa8094c0f41e6"],
1033
+
[ "Mailbox/get", {
1034
+
"accountId": "u33084183",
1039
+
[ "Mailbox/get", {
1040
+
"accountId": "u33084183",
1043
+
"id": "MB23cfa8094c0f41e6",
1044
+
"totalEmails": 16307,
1045
+
"unreadEmails": 13903,
1046
+
"totalThreads": 5833,
1047
+
"unreadThreads": 5127
1066
+
Jenkins & Newman Standards Track [Page 19]
1068
+
RFC 8621 JMAP Mail August 2019
1071
+
Here's an example where we try to rename one Mailbox and destroy
1074
+
[[ "Mailbox/set", {
1075
+
"accountId": "u33084183",
1076
+
"ifInState": "78542",
1078
+
"MB674cc24095db49ce": {
1079
+
"name": "Maybe important mail"
1082
+
"destroy": [ "MB23cfa8094c0f41e6" ]
1085
+
Suppose the rename succeeds, but we don't have permission to destroy
1086
+
the Mailbox we tried to destroy; we might get back:
1088
+
[[ "Mailbox/set", {
1089
+
"accountId": "u33084183",
1090
+
"oldState": "78542",
1091
+
"newState": "78549",
1093
+
"MB674cc24095db49ce": null
1096
+
"MB23cfa8094c0f41e6": {
1097
+
"type": "forbidden"
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.
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:
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.
1122
+
Jenkins & Newman Standards Track [Page 20]
1124
+
RFC 8621 JMAP Mail August 2019
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
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".
1142
+
A *Thread* object has the following properties:
1144
+
o id: "Id" (immutable; server-set)
1147
+
The id of the Thread.
1149
+
o emailIds: "Id[]" (server-set)
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).
1156
+
The following JMAP methods are supported.
1178
+
Jenkins & Newman Standards Track [Page 21]
1180
+
RFC 8621 JMAP Mail August 2019
1185
+
This is a standard "/get" method as described in [RFC8620],
1192
+
[[ "Thread/get", {
1193
+
"accountId": "acme",
1194
+
"ids": ["f123u4", "f41u44"]
1199
+
[[ "Thread/get", {
1200
+
"accountId": "acme",
1201
+
"state": "f6a7e214",
1205
+
"emailIds": [ "eaa623", "f782cbb"]
1209
+
"emailIds": [ "82cf7bb" ]
1215
+
3.2. Thread/changes
1217
+
This is a standard "/changes" method as described in [RFC8620],
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.
1234
+
Jenkins & Newman Standards Track [Page 22]
1236
+
RFC 8621 JMAP Mail August 2019
1239
+
4.1. Properties of the Email Object
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.
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.
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:
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
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.
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.
1290
+
Jenkins & Newman Standards Track [Page 23]
1292
+
RFC 8621 JMAP Mail August 2019
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.
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/".
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.
1313
+
These properties represent metadata about the message in the mail
1314
+
store and are not derived from parsing the message itself.
1316
+
o id: "Id" (immutable; server-set)
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].
1321
+
o blobId: "Id" (immutable; server-set)
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.
1327
+
o threadId: "Id" (immutable; server-set)
1329
+
The id of the Thread to which this Email belongs.
1331
+
o mailboxIds: "Id[Boolean]"
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.
1346
+
Jenkins & Newman Standards Track [Page 24]
1348
+
RFC 8621 JMAP Mail August 2019
1351
+
o keywords: "String[Boolean]" (default: {})
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.
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:
1362
+
* "$draft": The Email is a draft the user is composing.
1364
+
* "$seen": The Email has been read.
1366
+
* "$flagged": The Email has been flagged for urgent/special
1369
+
* "$answered": The Email has been replied to.
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).
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:
1385
+
Because JSON is case sensitive, servers MUST return keywords in
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:
1394
+
* "$forwarded": The Email has been forwarded.
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.
1402
+
Jenkins & Newman Standards Track [Page 25]
1404
+
RFC 8621 JMAP Mail August 2019
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.
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.
1415
+
o size: "UnsignedInt" (immutable; server-set)
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).
1421
+
o receivedAt: "UTCDate" (immutable; default: time of creation on
1424
+
The date the Email was received by the message store. This is the
1425
+
"internal date" in IMAP [RFC3501].
1427
+
4.1.2. Header Fields Parsed Forms
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.
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
1448
+
This form will typically have a leading space, as most generated
1449
+
messages insert a space after the colon that terminates the header
1458
+
Jenkins & Newman Standards Track [Page 26]
1460
+
RFC 8621 JMAP Mail August 2019
1467
+
The header field value with:
1469
+
1. White space unfolded (as defined in [RFC5322], Section 2.2.3).
1471
+
2. The terminating CRLF at the end of the value removed.
1473
+
3. Any SP characters at the beginning of the value removed.
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.
1481
+
5. The resulting unicode converted to Normalization Form C (NFC)
1484
+
If any decodings fail, the parser SHOULD insert a unicode replacement
1485
+
character (U+FFFD) and attempt to continue as much as possible.
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:
1499
+
o Any header field not defined in [RFC5322] or [RFC2369]
1501
+
4.1.2.3. Addresses
1503
+
Type: "EmailAddress[]"
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.
1514
+
Jenkins & Newman Standards Track [Page 27]
1516
+
RFC 8621 JMAP Mail August 2019
1519
+
An *EmailAddress* object has the following properties:
1521
+
o name: "String|null"
1523
+
The "display-name" of the "mailbox" [RFC5322]. If this is a
1526
+
1. The surrounding DQUOTE characters are removed.
1528
+
2. Any "quoted-pair" is decoded.
1530
+
3. White space is unfolded, and then any leading and trailing
1531
+
white space is removed.
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.
1539
+
The "addr-spec" of the "mailbox" [RFC5322].
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).
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).
1550
+
For example, the following "address-list" string:
1552
+
" James Smythe" <james@example.com>, Friends:
1553
+
jane@example.com, =?UTF-8?Q?John_Sm=C3=AEth?=
1554
+
<john@example.com>;
1556
+
would be parsed as:
1559
+
{ "name": "James Smythe", "email": "james@example.com" },
1560
+
{ "name": null, "email": "jane@example.com" },
1561
+
{ "name": "John Smith", "email": "john@example.com" }
1570
+
Jenkins & Newman Standards Track [Page 28]
1572
+
RFC 8621 JMAP Mail August 2019
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:
1603
+
o Any header field not defined in [RFC5322] or [RFC2369]
1605
+
4.1.2.4. GroupedAddresses
1607
+
Type: "EmailAddressGroup[]"
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
1626
+
Jenkins & Newman Standards Track [Page 29]
1628
+
RFC 8621 JMAP Mail August 2019
1631
+
An *EmailAddressGroup* object has the following properties:
1633
+
o name: "String|null"
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.
1639
+
o addresses: "EmailAddress[]"
1641
+
The "mailbox" values that belong to this group, represented as
1642
+
EmailAddress objects.
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).
1648
+
Parsing SHOULD be best effort in the face of invalid structure to
1649
+
accommodate invalid messages and semi-complete drafts.
1651
+
For example, the following "address-list" string:
1653
+
" James Smythe" <james@example.com>, Friends:
1654
+
jane@example.com, =?UTF-8?Q?John_Sm=C3=AEth?=
1655
+
<john@example.com>;
1657
+
would be parsed as:
1660
+
{ "name": null, "addresses": [
1661
+
{ "name": "James Smythe", "email": "james@example.com" }
1663
+
{ "name": "Friends", "addresses": [
1664
+
{ "name": null, "email": "jane@example.com" },
1665
+
{ "name": "John Smith", "email": "john@example.com" }
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).
1682
+
Jenkins & Newman Standards Track [Page 30]
1684
+
RFC 8621 JMAP Mail August 2019
1687
+
4.1.2.5. MessageIds
1689
+
Type: "String[]|null"
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.
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:
1706
+
o Resent-Message-ID
1708
+
o Any header field not defined in [RFC5322] or [RFC2369]
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
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:
1726
+
o Any header field not defined in [RFC5322] or [RFC2369]
1738
+
Jenkins & Newman Standards Track [Page 31]
1740
+
RFC 8621 JMAP Mail August 2019
1745
+
Type: "String[]|null"
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.
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:
1758
+
o List-Unsubscribe
1768
+
o Any header field not defined in [RFC5322] or [RFC2369]
1770
+
4.1.3. Header Fields Properties
1772
+
The following low-level Email property is specified for complete
1773
+
access to the header data of the message:
1775
+
o headers: "EmailHeader[]" (immutable)
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:
1783
+
The header "field name" as defined in [RFC5322], with the same
1784
+
capitalization that it has in the message.
1788
+
The header "field value" as defined in [RFC5322], in Raw form.
1794
+
Jenkins & Newman Standards Track [Page 32]
1796
+
RFC 8621 JMAP Mail August 2019
1799
+
In addition, the client may request/send properties representing
1800
+
individual header fields of the form:
1802
+
header:{header-field-name}
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:
1809
+
o :as{header-form}
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.
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.
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.
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.
1835
+
For a more complex example, consider the client requesting a property
1836
+
called "header:Resent-To:asAddresses:all". This means:
1838
+
1. Find *all* header fields named Resent-To (matched case
1841
+
2. For each instance, parse the header field value in the Addresses
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.
1850
+
Jenkins & Newman Standards Track [Page 33]
1852
+
RFC 8621 JMAP Mail August 2019
1855
+
The following convenience properties are also specified for the Email
1858
+
o messageId: "String[]|null" (immutable)
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.
1864
+
o inReplyTo: "String[]|null" (immutable)
1866
+
The value is identical to the value of "header:In-Reply-
1869
+
o references: "String[]|null" (immutable)
1871
+
The value is identical to the value of
1872
+
"header:References:asMessageIds".
1874
+
o sender: "EmailAddress[]|null" (immutable)
1876
+
The value is identical to the value of
1877
+
"header:Sender:asAddresses".
1879
+
o from: "EmailAddress[]|null" (immutable)
1881
+
The value is identical to the value of "header:From:asAddresses".
1883
+
o to: "EmailAddress[]|null" (immutable)
1885
+
The value is identical to the value of "header:To:asAddresses".
1887
+
o cc: "EmailAddress[]|null" (immutable)
1889
+
The value is identical to the value of "header:Cc:asAddresses".
1891
+
o bcc: "EmailAddress[]|null" (immutable)
1893
+
The value is identical to the value of "header:Bcc:asAddresses".
1895
+
o replyTo: "EmailAddress[]|null" (immutable)
1897
+
The value is identical to the value of "header:Reply-
1900
+
o subject: "String|null" (immutable)
1902
+
The value is identical to the value of "header:Subject:asText".
1906
+
Jenkins & Newman Standards Track [Page 34]
1908
+
RFC 8621 JMAP Mail August 2019
1911
+
o sentAt: "Date|null" (immutable; default on creation: current
1914
+
The value is identical to the value of "header:Date:asDate".
1918
+
These properties are derived from the message body [RFC5322] and its
1919
+
MIME entities [RFC2045].
1921
+
An *EmailBodyPart* object has the following properties:
1923
+
o partId: "String|null"
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
1930
+
o blobId: "Id|null"
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.
1941
+
o size: "UnsignedInt"
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).
1947
+
o headers: "EmailHeader[]"
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.
1952
+
o name: "String|null"
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].
1962
+
Jenkins & Newman Standards Track [Page 35]
1964
+
RFC 8621 JMAP Mail August 2019
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.
1974
+
o charset: "String|null"
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".
1982
+
o disposition: "String|null"
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
1988
+
o cid: "String|null"
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].
1996
+
o language: "String[]|null"
1998
+
The list of language tags, as defined in [RFC3282], in the
1999
+
Content-Language header field of the part, if present.
2001
+
o location: "String|null"
2003
+
The URI, as defined in [RFC2557], in the Content-Location header
2004
+
field of the part, if present.
2006
+
o subParts: "EmailBodyPart[]|null"
2008
+
If the type is "multipart/*", this contains the body parts of each
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".
2018
+
Jenkins & Newman Standards Track [Page 36]
2020
+
RFC 8621 JMAP Mail August 2019
2023
+
The following Email properties are specified for access to the body
2024
+
data of the message:
2026
+
o bodyStructure: "EmailBodyPart" (immutable)
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
2033
+
o bodyValues: "String[EmailBodyValue]" (immutable)
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:
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
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
2058
+
* isEncodingProblem: "Boolean" (default: false)
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.
2064
+
* isTruncated: "Boolean" (default: false)
2066
+
This is true if the "value" has been truncated.
2068
+
See the Security Considerations section for issues related to
2069
+
truncation and heuristic determination of the content-type and
2074
+
Jenkins & Newman Standards Track [Page 37]
2076
+
RFC 8621 JMAP Mail August 2019
2079
+
o textBody: "EmailBodyPart[]" (immutable)
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
2086
+
o htmlBody: "EmailBodyPart[]" (immutable)
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
2093
+
o attachments: "EmailBodyPart[]" (immutable)
2095
+
A list, traversing depth-first, of all parts in "bodyStructure"
2096
+
that satisfy either of the following conditions:
2098
+
* not of type "multipart/*" and not included in "textBody" or
2101
+
* of type "image/*", "audio/*", or "video/*" and not in both
2102
+
"textBody" and "htmlBody"
2104
+
None of these parts include subParts, including "message/*" types.
2105
+
Attached messages may be fetched using the "Email/parse" method
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.
2112
+
o hasAttachment: "Boolean" (immutable; server-set)
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.
2122
+
The server MAY set hasAttachment based on implementation-defined
2123
+
or site-configurable heuristics.
2130
+
Jenkins & Newman Standards Track [Page 38]
2132
+
RFC 8621 JMAP Mail August 2019
2135
+
o preview: "String" (immutable; server-set)
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
2144
+
This MUST NOT be more than 256 characters in length.
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
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:
2160
+
function isInlineMediaType ( type ) {
2161
+
return type.startsWith( 'image/' ) ||
2162
+
type.startsWith( 'audio/' ) ||
2163
+
type.startsWith( 'video/' );
2166
+
function parseStructure ( parts, multipartType, inAlternative,
2167
+
htmlBody, textBody, attachments ) {
2169
+
// For multipartType == alternative
2170
+
let textLength = textBody ? textBody.length : -1;
2171
+
let htmlLength = htmlBody ? htmlBody.length : -1;
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 ) ) &&
2186
+
Jenkins & Newman Standards Track [Page 39]
2188
+
RFC 8621 JMAP Mail August 2019
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
2195
+
( multipartType != "related" &&
2196
+
( isInlineMediaType( part.type ) || !part.name ) ) );
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 );
2210
+
htmlBody.push( part );
2213
+
attachments.push( part );
2217
+
} else if ( inAlternative ) {
2218
+
if ( part.type == 'text/plain' ) {
2221
+
if ( part.type == 'text/html' ) {
2226
+
textBody.push( part );
2229
+
htmlBody.push( part );
2231
+
if ( ( !textBody || !htmlBody ) &&
2232
+
isInlineMediaType( part.type ) ) {
2233
+
attachments.push( part );
2236
+
attachments.push( part );
2242
+
Jenkins & Newman Standards Track [Page 40]
2244
+
RFC 8621 JMAP Mail August 2019
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] );
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] );
2266
+
let htmlBody = [];
2267
+
let textBody = [];
2268
+
let attachments = [];
2270
+
parseStructure( [ bodyStructure ], 'mixed', false,
2271
+
htmlBody, textBody, attachments );
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:
2278
+
text/plain, content-disposition=inline - A
2280
+
multipart/alternative
2282
+
text/plain, content-disposition=inline - B
2283
+
image/jpeg, content-disposition=inline - C
2284
+
text/plain, content-disposition=inline - D
2288
+
image/jpeg, content-disposition=attachment - G
2289
+
application/x-excel - H
2290
+
message/rfc822 - J
2291
+
text/plain, content-disposition=inline - K
2298
+
Jenkins & Newman Standards Track [Page 41]
2300
+
RFC 8621 JMAP Mail August 2019
2303
+
In this case, the above algorithm would decompose this to:
2305
+
textBody => [ A, B, C, D, K ]
2306
+
htmlBody => [ A, E, K ]
2307
+
attachments => [ C, F, G, H, J ]
2311
+
This is a standard "/get" method as described in [RFC8620],
2312
+
Section 5.1 with the following additional request arguments:
2314
+
o bodyProperties: "String[]"
2316
+
A list of properties to fetch for each EmailBodyPart returned. If
2317
+
omitted, this defaults to:
2319
+
[ "partId", "blobId", "size", "name", "type", "charset",
2320
+
"disposition", "cid", "language", "location" ]
2322
+
o fetchTextBodyValues: "Boolean" (default: false)
2324
+
If true, the "bodyValues" property includes any "text/*" part in
2325
+
the "textBody" property.
2327
+
o fetchHTMLBodyValues: "Boolean" (default: false)
2329
+
If true, the "bodyValues" property includes any "text/*" part in
2330
+
the "htmlBody" property.
2332
+
o fetchAllBodyValues: "Boolean" (default: false)
2334
+
If true, the "bodyValues" property includes any "text/*" part in
2335
+
the "bodyStructure" property.
2337
+
o maxBodyValueBytes: "UnsignedInt" (default: 0)
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.
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
2354
+
Jenkins & Newman Standards Track [Page 42]
2356
+
RFC 8621 JMAP Mail August 2019
2359
+
If the standard "properties" argument is omitted or null, the
2360
+
following default MUST be used instead of "all" properties:
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" ]
2367
+
The following properties are expected to be fast to fetch in a
2368
+
quality implementation:
2410
+
Jenkins & Newman Standards Track [Page 43]
2412
+
RFC 8621 JMAP Mail August 2019
2415
+
Clients SHOULD take care when fetching any other properties, as there
2416
+
may be significantly longer latency in fetching and returning the
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.
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.
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
2445
+
"accountId": "abc",
2446
+
"state": "41234123231",
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"
2460
+
"blobId": "B841623871",
2462
+
"type": "text/html"
2466
+
Jenkins & Newman Standards Track [Page 44]
2468
+
RFC 8621 JMAP Mail August 2019
2473
+
"blobId": "B319437193",
2475
+
"type": "text/plain"
2479
+
"isEncodingProblem": false,
2480
+
"isTruncated": true,
2481
+
"value": "<html><body><p>Hello ..."
2484
+
"isEncodingProblem": false,
2485
+
"isTruncated": false,
2486
+
"value": "-- Sent by your friendly mailing list ..."
2491
+
"notFound": [ "f123u456" ]
2494
+
4.3. Email/changes
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.
2503
+
This is a standard "/query" method as described in [RFC8620],
2504
+
Section 5.5 but with the following additional request arguments:
2506
+
o collapseThreads: "Boolean" (default: false)
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
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.
2522
+
Jenkins & Newman Standards Track [Page 45]
2524
+
RFC 8621 JMAP Mail August 2019
2529
+
A *FilterCondition* object has the following properties, any of which
2534
+
A Mailbox id. An Email must be in this Mailbox to match the
2537
+
o inMailboxOtherThan: "Id[]"
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.
2543
+
o before: "UTCDate"
2545
+
The "receivedAt" date-time of the Email must be before this date-
2546
+
time to match the condition.
2548
+
o after: "UTCDate"
2550
+
The "receivedAt" date-time of the Email must be the same or after
2551
+
this date-time to match the condition.
2553
+
o minSize: "UnsignedInt"
2555
+
The "size" property of the Email must be equal to or greater than
2556
+
this number to match the condition.
2558
+
o maxSize: "UnsignedInt"
2560
+
The "size" property of the Email must be less than this number to
2561
+
match the condition.
2563
+
o allInThreadHaveKeyword: "String"
2565
+
All Emails (including this one) in the same Thread as this Email
2566
+
must have the given keyword to match the condition.
2568
+
o someInThreadHaveKeyword: "String"
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.
2578
+
Jenkins & Newman Standards Track [Page 46]
2580
+
RFC 8621 JMAP Mail August 2019
2583
+
o noneInThreadHaveKeyword: "String"
2585
+
All Emails (including this one) in the same Thread as this Email
2586
+
must *not* have the given keyword to match the condition.
2588
+
o hasKeyword: "String"
2590
+
This Email must have the given keyword to match the condition.
2592
+
o notKeyword: "String"
2594
+
This Email must not have the given keyword to match the condition.
2596
+
o hasAttachment: "Boolean"
2598
+
The "hasAttachment" property of the Email must be identical to the
2599
+
value given to match the condition.
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.
2611
+
Looks for the text in the From header field of the message.
2615
+
Looks for the text in the To header field of the message.
2619
+
Looks for the text in the Cc header field of the message.
2623
+
Looks for the text in the Bcc header field of the message.
2625
+
o subject: "String"
2627
+
Looks for the text in the Subject header field of the message.
2634
+
Jenkins & Newman Standards Track [Page 47]
2636
+
RFC 8621 JMAP Mail August 2019
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.
2650
+
o header: "String[]"
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.
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).
2664
+
The exact semantics for matching "String" fields is *deliberately not
2665
+
defined* to allow for flexibility in indexing implementation, subject
2668
+
o Any syntactically correct encoded sections [RFC2047] of header
2669
+
fields with a known encoding SHOULD be decoded before attempting
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.
2679
+
o Text SHOULD be matched in a case-insensitive manner.
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.
2690
+
Jenkins & Newman Standards Track [Page 48]
2692
+
RFC 8621 JMAP Mail August 2019
2695
+
Within a phrase, to match one of the following characters you MUST
2696
+
escape it by prefixing it with a backslash (\):
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.
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").
2710
+
The following value for the "property" field on the Comparator object
2711
+
MUST be supported for sorting:
2713
+
o "receivedAt" - The "receivedAt" date as returned in the Email
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.
2721
+
o "size" - The "size" as returned in the Email object.
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.
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.
2733
+
o "subject" - This is taken to be the base subject of the message,
2734
+
as defined in Section 2.1 of [RFC5256].
2736
+
o "sentAt" - The "sentAt" property on the Email object.
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.
2746
+
Jenkins & Newman Standards Track [Page 49]
2748
+
RFC 8621 JMAP Mail August 2019
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.
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.
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).
2768
+
"property": "someInThreadHaveKeyword",
2769
+
"keyword": "$flagged",
2770
+
"isAscending": false
2772
+
"property": "subject",
2773
+
"collation": "i;ascii-casemap"
2775
+
"property": "receivedAt",
2776
+
"isAscending": false
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.
2785
+
4.4.3. Thread Collapsing
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).
2802
+
Jenkins & Newman Standards Track [Page 50]
2804
+
RFC 8621 JMAP Mail August 2019
2807
+
4.5. Email/queryChanges
2809
+
This is a standard "/queryChanges" method as described in [RFC8620],
2810
+
Section 5.6 with the following additional request argument:
2812
+
o collapseThreads: "Boolean" (default: false)
2814
+
The "collapseThreads" argument that was used with "Email/query".
2818
+
This is a standard "/set" method as described in [RFC8620],
2819
+
Section 5.3. The "Email/set" method encompasses:
2821
+
o Creating a draft
2823
+
o Changing the keywords of an Email (e.g., unread/flagged status)
2825
+
o Adding/removing an Email to/from Mailboxes (moving a message)
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).
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:
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.
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.
2848
+
o Header fields MUST NOT be specified in parsed forms that are
2849
+
forbidden for that particular field.
2851
+
o Header fields beginning with "Content-" MUST NOT be specified on
2852
+
the Email object, only on EmailBodyPart objects.
2858
+
Jenkins & Newman Standards Track [Page 51]
2860
+
RFC 8621 JMAP Mail August 2019
2863
+
o If a "bodyStructure" property is given, there MUST NOT be
2864
+
"textBody", "htmlBody", or "attachments" properties.
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.
2870
+
o If given, textBody MUST contain exactly one body part and it MUST
2871
+
be of type "text/plain".
2873
+
o If given, htmlBody MUST contain exactly one body part and it MUST
2874
+
be of type "text/html".
2876
+
o Within an EmailBodyPart:
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.
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).
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
2891
+
* A Content-Transfer-Encoding header field MUST NOT be given.
2893
+
o Within an EmailBodyValue object, isEncodingProblem and isTruncated
2894
+
MUST be either false or omitted.
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.
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.
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).
2914
+
Jenkins & Newman Standards Track [Page 52]
2916
+
RFC 8621 JMAP Mail August 2019
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.
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.
2928
+
For successfully created Email objects, the "created" response
2929
+
contains the "id", "blobId", "threadId", and "size" properties of the
2932
+
The following extra SetError types are defined:
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
2942
+
For "create" and "update":
2944
+
o "tooManyKeywords": The change to the Email's keywords would exceed
2945
+
a server-defined maximum.
2947
+
o "tooManyMailboxes": The change to the set of Mailboxes that this
2948
+
Email is in would exceed a server-defined maximum.
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.
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"
2963
+
For successfully copied Email objects, the "created" response
2964
+
contains the "id", "blobId", "threadId", and "size" properties of the
2970
+
Jenkins & Newman Standards Track [Page 53]
2972
+
RFC 8621 JMAP Mail August 2019
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:
2985
+
The id of the account to use.
2987
+
o ifInState: "String|null"
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.
2995
+
o emails: "Id[EmailImport]"
2997
+
A map of creation id (client specified) to EmailImport objects.
2999
+
An *EmailImport* object has the following properties:
3003
+
The id of the blob containing the raw message [RFC5322].
3005
+
o mailboxIds: "Id[Boolean]"
3007
+
The ids of the Mailboxes to assign this Email to. At least one
3008
+
Mailbox MUST be given.
3010
+
o keywords: "String[Boolean]" (default: {})
3012
+
The keywords to apply to the Email.
3014
+
o receivedAt: "UTCDate" (default: time of most recent Received
3015
+
header, or time of import on server if none)
3017
+
The "receivedAt" date to set on the Email.
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.
3026
+
Jenkins & Newman Standards Track [Page 54]
3028
+
RFC 8621 JMAP Mail August 2019
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.
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.
3044
+
If the Email cannot be imported because it would take the account
3045
+
over quota, the import should be rejected with an "overQuota"
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.
3055
+
The response has the following arguments:
3059
+
The id of the account used for this call.
3061
+
o oldState: "String|null"
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.
3067
+
o newState: "String"
3069
+
The state string that will now be returned by "Email/get" on this
3072
+
o created: "Id[Email]|null"
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.
3082
+
Jenkins & Newman Standards Track [Page 55]
3084
+
RFC 8621 JMAP Mail August 2019
3087
+
o notCreated: "Id[SetError]|null"
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.
3093
+
The following additional errors may be returned instead of the
3094
+
"Email/import" response:
3096
+
"stateMismatch": An "ifInState" argument was supplied, and it does
3097
+
not match the current state.
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.
3107
+
The following metadata properties on the Email objects will be null
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.
3122
+
The "Email/parse" method takes the following arguments:
3126
+
The id of the account to use.
3130
+
The ids of the blobs to parse.
3138
+
Jenkins & Newman Standards Track [Page 56]
3140
+
RFC 8621 JMAP Mail August 2019
3143
+
o properties: "String[]"
3145
+
If supplied, only the properties listed in the array are returned
3146
+
for each Email object. If omitted, defaults to:
3148
+
[ "messageId", "inReplyTo", "references", "sender", "from", "to",
3149
+
"cc", "bcc", "replyTo", "subject", "sentAt", "hasAttachment",
3150
+
"preview", "bodyValues", "textBody", "htmlBody", "attachments" ]
3152
+
o bodyProperties: "String[]"
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.
3158
+
o fetchTextBodyValues: "Boolean" (default: false)
3160
+
If true, the "bodyValues" property includes any "text/*" part in
3161
+
the "textBody" property.
3163
+
o fetchHTMLBodyValues: "Boolean" (default: false)
3165
+
If true, the "bodyValues" property includes any "text/*" part in
3166
+
the "htmlBody" property.
3168
+
o fetchAllBodyValues: "Boolean" (default: false)
3170
+
If true, the "bodyValues" property includes any "text/*" part in
3171
+
the "bodyStructure" property.
3173
+
o maxBodyValueBytes: "UnsignedInt" (default: 0)
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.
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
3194
+
Jenkins & Newman Standards Track [Page 57]
3196
+
RFC 8621 JMAP Mail August 2019
3199
+
The response has the following arguments:
3203
+
The id of the account used for the call.
3205
+
o parsed: "Id[Email]|null"
3207
+
A map of blob id to parsed Email representation for each
3208
+
successfully parsed blob, or null if none.
3210
+
o notParsable: "Id[]|null"
3212
+
A list of ids given that corresponded to blobs that could not be
3213
+
parsed as Emails, or null if none.
3215
+
o notFound: "Id[]|null"
3217
+
A list of blob ids given that could not be found, or null if none.
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.
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.
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:
3237
+
[[ "Email/query",{
3238
+
"accountId": "ue150411c",
3240
+
"inMailbox": "fb666a55"
3243
+
"isAscending": false,
3244
+
"property": "receivedAt"
3246
+
"collapseThreads": true,
3250
+
Jenkins & Newman Standards Track [Page 58]
3252
+
RFC 8621 JMAP Mail August 2019
3257
+
"calculateTotal": true
3260
+
"accountId": "ue150411c",
3263
+
"name": "Email/query",
3271
+
"accountId": "ue150411c",
3274
+
"name": "Email/get",
3275
+
"path": "/list/*/threadId"
3279
+
"accountId": "ue150411c",
3282
+
"name": "Thread/get",
3283
+
"path": "/list/*/emailIds"
3306
+
Jenkins & Newman Standards Track [Page 59]
3308
+
RFC 8621 JMAP Mail August 2019
3311
+
Let's break down the 4 method calls to see what they're doing:
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
3318
+
"1": Now we use a back-reference to fetch the Thread ids for each of
3321
+
"2": Another back-reference fetches the Thread object for each of
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.
3330
+
The response from the server may look something like this:
3332
+
[[ "Email/query", {
3333
+
"accountId": "ue150411c",
3334
+
"queryState": "09aa9a075588-780599:0",
3335
+
"canCalculateChanges": true,
3338
+
"ids": [ "Ma783e5cdf5f2deffbc97930a",
3339
+
"M9bd17497e2a99cb345fc1d0a", ... ]
3342
+
"accountId": "ue150411c",
3343
+
"state": "780599",
3345
+
"id": "Ma783e5cdf5f2deffbc97930a",
3346
+
"threadId": "T36703c2cfe9bd5ed"
3348
+
"id": "M9bd17497e2a99cb345fc1d0a",
3349
+
"threadId": "T0a22ad76e9c097a1"
3354
+
"accountId": "ue150411c",
3355
+
"state": "22a8728b",
3357
+
"id": "T36703c2cfe9bd5ed",
3358
+
"emailIds": [ "Ma783e5cdf5f2deffbc97930a" ]
3362
+
Jenkins & Newman Standards Track [Page 60]
3364
+
RFC 8621 JMAP Mail August 2019
3368
+
"id": "T0a22ad76e9c097a1",
3369
+
"emailIds": [ "M3b568670a63e5d100f518fa5",
3370
+
"M9bd17497e2a99cb345fc1d0a" ]
3375
+
"accountId": "ue150411c",
3376
+
"state": "780599",
3378
+
"id": "Ma783e5cdf5f2deffbc97930a",
3379
+
"threadId": "T36703c2cfe9bd5ed",
3387
+
"hasAttachment": true,
3389
+
"email": "jdoe@example.com",
3390
+
"name": "Jane Doe"
3392
+
"subject": "The Big Reveal",
3393
+
"receivedAt": "2018-06-27T00:20:35Z",
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..."
3418
+
Jenkins & Newman Standards Track [Page 61]
3420
+
RFC 8621 JMAP Mail August 2019
3423
+
Now, on another device, the user marks the first Email as unread,
3424
+
sending this API request:
3427
+
"accountId": "ue150411c",
3429
+
"Ma783e5cdf5f2deffbc97930a": {
3430
+
"keywords/$seen": null
3435
+
The server applies this and sends the success response:
3438
+
"accountId": "ue150411c",
3439
+
"oldState": "780605",
3440
+
"newState": "780606",
3442
+
"Ma783e5cdf5f2deffbc97930a": null
3447
+
The user also deletes a few Emails, and then a new message arrives.
3474
+
Jenkins & Newman Standards Track [Page 62]
3476
+
RFC 8621 JMAP Mail August 2019
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:
3483
+
[[ "Email/changes", {
3484
+
"accountId": "ue150411c",
3485
+
"sinceState": "780605",
3488
+
[ "Email/queryChanges", {
3489
+
"accountId": "ue150411c",
3491
+
"inMailbox": "fb666a55"
3494
+
"property": "receivedAt",
3495
+
"isAscending": false
3497
+
"collapseThreads": true,
3498
+
"sinceQueryState": "09aa9a075588-780599:0",
3499
+
"upToId": "Mc2781d5e856a908d8a35a564",
3501
+
"calculateTotal": true
3506
+
[[ "Email/changes", {
3507
+
"accountId": "ue150411c",
3508
+
"oldState": "780605",
3509
+
"newState": "780800",
3510
+
"hasMoreChanges": false,
3511
+
"created": [ "Me8de6c9f6de198239b982ea2" ],
3512
+
"updated": [ "Ma783e5cdf5f2deffbc97930a" ],
3513
+
"destroyed": [ "M9bd17497e2a99cb345fc1d0a", ... ]
3515
+
[ "Email/queryChanges", {
3516
+
"accountId": "ue150411c",
3517
+
"oldQueryState": "09aa9a075588-780599:0",
3518
+
"newQueryState": "e35e9facf117-780615:0",
3520
+
"id": "Me8de6c9f6de198239b982ea2",
3523
+
"removed": [ "M9bd17497e2a99cb345fc1d0a" ],
3530
+
Jenkins & Newman Standards Track [Page 63]
3532
+
RFC 8621 JMAP Mail August 2019
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).
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.
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:
3551
+
"accountId": "ue150411c",
3555
+
"2ea1ca41b38e": true
3562
+
"name": "Joe Bloggs",
3563
+
"email": "joe@example.com"
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",
3571
+
"header:Content-Language": "en"
3575
+
"value": "I have the most brilliant plan. Let me tell
3576
+
you all about it. What we do is, we",
3577
+
"isTruncated": false
3586
+
Jenkins & Newman Standards Track [Page 64]
3588
+
RFC 8621 JMAP Mail August 2019
3591
+
The server creates the message and sends the success response:
3594
+
"accountId": "ue150411c",
3595
+
"oldState": "780823",
3596
+
"newState": "780839",
3599
+
"id": "Mf40b5f831efa7233b9eb1c7f",
3600
+
"blobId": "Gf40b5f831efa7233b9eb1c7f8f97d84eeeee64f7",
3601
+
"threadId": "Td957e72e89f516dc",
3608
+
The message created on the server looks something like this:
3610
+
Message-Id: <bbce0ae9-58be-4b24-ac82-deb840d58016@sloti7d1t02>
3611
+
User-Agent: Cyrus-JMAP/3.1.6-736-gdfb8e44
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
3619
+
I have the most brilliant plan. Let me tell you all about it. What we
3622
+
The user adds a recipient and converts the message to HTML so they
3623
+
can add formatting, then saves an updated draft:
3626
+
"accountId": "ue150411c",
3630
+
"2ea1ca41b38e": true
3637
+
"name": "Joe Bloggs",
3638
+
"email": "joe@example.com"
3642
+
Jenkins & Newman Standards Track [Page 65]
3644
+
RFC 8621 JMAP Mail August 2019
3650
+
"email": "john@example.com"
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",
3659
+
"type": "text/html",
3660
+
"header:Content-Language": "en"
3663
+
"type": "text/plain",
3664
+
"header:Content-Language": "en"
3669
+
"value": "I have the most brilliant plan. Let me tell
3670
+
you all about it. What we do is, we",
3671
+
"isTruncated": false
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>
3679
+
"isTruncated": false
3684
+
"destroy": [ "Mf40b5f831efa7233b9eb1c7f" ]
3698
+
Jenkins & Newman Standards Track [Page 66]
3700
+
RFC 8621 JMAP Mail August 2019
3703
+
The server creates the new draft, deletes the old one, and sends the
3707
+
"accountId": "ue150411c",
3708
+
"oldState": "780839",
3709
+
"newState": "780842",
3712
+
"id": "Md45b47b4877521042cec0938",
3713
+
"blobId": "Ge8de6c9f6de198239b982ea214e0f3a704e4af74",
3714
+
"threadId": "Td957e72e89f516dc",
3718
+
"destroyed": [ "Mf40b5f831efa7233b9eb1c7f" ],
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:
3727
+
[[ "Email/copy", {
3728
+
"fromAccountId": "ue150411c",
3729
+
"accountId": "u6c6c41ac",
3732
+
"id": "Md45b47b4877521042cec0938",
3738
+
"onSuccessDestroyOriginal": true
3754
+
Jenkins & Newman Standards Track [Page 67]
3756
+
RFC 8621 JMAP Mail August 2019
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:
3763
+
[[ "Email/copy", {
3764
+
"fromAccountId": "ue150411c",
3765
+
"accountId": "u6c6c41ac",
3766
+
"oldState": "7ee7e9263a6d",
3767
+
"newState": "5a0d2447ed26",
3770
+
"id": "M138f9954a5cd2423daeafa55",
3771
+
"blobId": "G6b9fb047cba722c48c611e79233d057c6b0b74e8",
3772
+
"threadId": "T2f242ea424a4079a",
3776
+
"notCreated": null
3779
+
"accountId": "ue150411c",
3780
+
"oldState": "780842",
3781
+
"newState": "780871",
3782
+
"destroyed": [ "Md45b47b4877521042cec0938" ],
3786
+
5. Search Snippets
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.
3793
+
A *SearchSnippet* object has the following properties:
3797
+
The Email id the snippet applies to.
3810
+
Jenkins & Newman Standards Track [Page 68]
3812
+
RFC 8621 JMAP Mail August 2019
3815
+
o subject: "String|null"
3817
+
If text from the filter matches the subject, this is the subject
3818
+
of the Email with the following transformations:
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.
3825
+
2. The matching words/phrases from the filter are wrapped in HTML
3826
+
"<mark></mark>" tags.
3828
+
If the subject does not match text from the filter, this property
3831
+
o preview: "String|null"
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
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.
3844
+
Note that unlike most data types, a SearchSnippet DOES NOT have a
3845
+
property called "id".
3847
+
The following JMAP method is supported.
3849
+
5.1. SearchSnippet/get
3851
+
To fetch search snippets, make a call to "SearchSnippet/get". It
3852
+
takes the following arguments:
3856
+
The id of the account to use.
3858
+
o filter: "FilterOperator|FilterCondition|null"
3860
+
The same filter as passed to "Email/query"; see the description of
3861
+
this method in Section 4.4 for details.
3866
+
Jenkins & Newman Standards Track [Page 69]
3868
+
RFC 8621 JMAP Mail August 2019
3871
+
o emailIds: "Id[]"
3873
+
The ids of the Emails to fetch snippets for.
3875
+
The response has the following arguments:
3879
+
The id of the account used for the call.
3881
+
o list: "SearchSnippet[]"
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
3887
+
o notFound: "Id[]|null"
3889
+
An array of Email ids requested that could not be found, or null
3890
+
if all ids were found.
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.
3898
+
The following additional errors may be returned instead of the
3899
+
"SearchSnippet/get" response:
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.
3905
+
"unsupportedFilter": The server is unable to process the given
3906
+
"filter" for any reason.
3922
+
Jenkins & Newman Standards Track [Page 70]
3924
+
RFC 8621 JMAP Mail August 2019
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:
3933
+
[[ "SearchSnippet/get", {
3934
+
"accountId": "ue150411c",
3939
+
"M44200ec123de277c0c1ce69c",
3940
+
"M7bcbcb0b58d7729686e83d99",
3941
+
"M28d12783a0969584b6deaac0",
3948
+
[[ "SearchSnippet/get", {
3949
+
"accountId": "ue150411c",
3951
+
"emailId": "M44200ec123de277c0c1ce69c",
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 ..."
3960
+
"emailId": "M28d12783a0969584b6deaac0",
3962
+
"preview": "...the <mark>Foo</mark>/bar method results often
3963
+
returns <1 widget rather than the complete..."
3978
+
Jenkins & Newman Standards Track [Page 71]
3980
+
RFC 8621 JMAP Mail August 2019
3985
+
An *Identity* object stores information about an email address or
3986
+
domain the user may send from. It has the following properties:
3988
+
o id: "Id" (immutable; server-set)
3990
+
The id of the Identity.
3992
+
o name: "String" (default: "")
3994
+
The "From" name the client SHOULD use when creating a new Email
3995
+
from this Identity.
3997
+
o email: "String" (immutable)
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").
4005
+
o replyTo: "EmailAddress[]|null" (default: null)
4007
+
The Reply-To value the client SHOULD set when creating a new Email
4008
+
from this Identity.
4010
+
o bcc: "EmailAddress[]|null" (default: null)
4012
+
The Bcc value the client SHOULD set when creating a new Email from
4015
+
o textSignature: "String" (default: "")
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.
4021
+
o htmlSignature: "String" (default: "")
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.
4034
+
Jenkins & Newman Standards Track [Page 72]
4036
+
RFC 8621 JMAP Mail August 2019
4039
+
o mayDelete: "Boolean" (server-set)
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.
4046
+
See the "Addresses" header form description in the Email object
4047
+
(Section 4.1.2.3) for the definition of EmailAddress.
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).
4053
+
The following JMAP methods are supported.
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.
4060
+
6.2. Identity/changes
4062
+
This is a standard "/changes" method as described in [RFC8620],
4067
+
This is a standard "/set" method as described in [RFC8620],
4068
+
Section 5.3. The following extra SetError types are defined:
4072
+
o "forbiddenFrom": The user is not allowed to send from the address
4073
+
given as the "email" property of the Identity.
4079
+
[ "Identity/get", {
4080
+
"accountId": "acme"
4090
+
Jenkins & Newman Standards Track [Page 73]
4092
+
RFC 8621 JMAP Mail August 2019
4097
+
[ "Identity/get", {
4098
+
"accountId": "acme",
4099
+
"state": "99401312ae-11-333",
4102
+
"id": "XD-3301-222-11_22AAz",
4103
+
"name": "Joe Bloggs",
4104
+
"email": "joe@example.com",
4108
+
"email": "joe+archive@example.com"
4110
+
"textSignature": "-- \nJoe Bloggs\nMaster of Email",
4111
+
"htmlSignature": "<div><b>Joe Bloggs</b></div>
4112
+
<div>Master of Email</div>",
4113
+
"mayDelete": false
4116
+
"id": "XD-9911312-11_22AAz",
4118
+
"email": "*@example.com",
4121
+
"textSignature": "",
4122
+
"htmlSignature": "",
4129
+
7. Email Submission
4131
+
An *EmailSubmission* object represents the submission of an Email for
4132
+
delivery to one or more recipients. It has the following properties:
4134
+
o id: "Id" (immutable; server-set)
4136
+
The id of the EmailSubmission.
4138
+
o identityId: "Id" (immutable)
4140
+
The id of the Identity to associate with this submission.
4146
+
Jenkins & Newman Standards Track [Page 74]
4148
+
RFC 8621 JMAP Mail August 2019
4151
+
o emailId: "Id" (immutable)
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.
4157
+
o threadId: "Id" (immutable; server-set)
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".
4162
+
o envelope: "Envelope|null" (immutable)
4164
+
Information for use when sending via SMTP. An *Envelope* object
4165
+
has the following properties:
4167
+
* mailFrom: "Address"
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
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-
4180
+
* rcptTo: "Address[]"
4182
+
The email addresses to send the message to, and any RCPT TO
4183
+
parameters to pass with the recipient.
4185
+
An *Address* object has the following properties:
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].
4193
+
* parameters: "Object|null"
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
4202
+
Jenkins & Newman Standards Track [Page 75]
4204
+
RFC 8621 JMAP Mail August 2019
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
4212
+
If the "envelope" property is null or omitted on creation, the
4213
+
server MUST generate this from the referenced Email as follows:
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.
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
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.
4229
+
* "rcptTo": The deduplicated set of email addresses from the To,
4230
+
Cc, and Bcc header fields, if present, with no parameters for
4233
+
o sendAt: "UTCDate" (immutable; server-set)
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
4241
+
o undoStatus: "String"
4243
+
This represents whether the submission may be canceled. This is
4244
+
server set on create and MUST be one of the following values:
4246
+
* "pending": It may be possible to cancel this submission.
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.
4252
+
* "canceled": The submission was canceled and will not be
4253
+
delivered to any recipient.
4258
+
Jenkins & Newman Standards Track [Page 76]
4260
+
RFC 8621 JMAP Mail August 2019
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.
4273
+
o deliveryStatus: "String[DeliveryStatus]|null" (server-set)
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.
4282
+
This value is a map from the email address of each recipient to a
4283
+
DeliveryStatus object.
4285
+
A *DeliveryStatus* object has the following properties:
4287
+
* smtpReply: "String"
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.
4297
+
Multi-line SMTP responses should be concatenated to a single
4298
+
string as follows:
4300
+
+ The hyphen following the SMTP code on all but the last line
4301
+
is replaced with a space.
4303
+
+ Any prefix in common with the first line is stripped from
4304
+
lines after the first.
4306
+
+ CRLF is replaced by a space.
4314
+
Jenkins & Newman Standards Track [Page 77]
4316
+
RFC 8621 JMAP Mail August 2019
4321
+
550-5.7.1 Our system has detected that this message is
4322
+
550 5.7.1 likely spam.
4326
+
550 5.7.1 Our system has detected that this message is likely spam.
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:
4332
+
+ A 3-digit SMTP reply code, as defined in [RFC5321],
4335
+
+ Then a single space character.
4337
+
+ Then an SMTP Enhanced Mail System Status Code as defined in
4338
+
[RFC3463], with a registry defined in [RFC5248].
4340
+
+ Then a single space character.
4342
+
+ Then an implementation-specific information string with a
4343
+
human-readable explanation of the response.
4345
+
* delivered: "String"
4347
+
Represents whether the message has been successfully delivered
4348
+
to the recipient. This MUST be one of the following values:
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.
4354
+
+ "yes": The message was successfully delivered to the mail
4355
+
store of the recipient. The "smtpReply" property is final.
4357
+
+ "no": Delivery to the recipient permanently failed. The
4358
+
"smtpReply" property is final.
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.
4370
+
Jenkins & Newman Standards Track [Page 78]
4372
+
RFC 8621 JMAP Mail August 2019
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.
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.
4386
+
The server MAY also set this property based on other feedback
4389
+
* displayed: "String"
4391
+
Represents whether the message has been displayed to the
4392
+
recipient. This MUST be one of the following values:
4394
+
+ "unknown": The display status is unknown. This is the
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.
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
4407
+
The server MAY also set this property based on other feedback
4410
+
o dsnBlobIds: "Id[]" (server-set)
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.
4417
+
o mdnBlobIds: "Id[]" (server-set)
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.
4426
+
Jenkins & Newman Standards Track [Page 79]
4428
+
RFC 8621 JMAP Mail August 2019
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
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.
4444
+
The following JMAP methods are supported.
4446
+
7.1. EmailSubmission/get
4448
+
This is a standard "/get" method as described in [RFC8620],
4451
+
7.2. EmailSubmission/changes
4453
+
This is a standard "/changes" method as described in [RFC8620],
4456
+
7.3. EmailSubmission/query
4458
+
This is a standard "/query" method as described in [RFC8620],
4461
+
A *FilterCondition* object has the following properties, any of which
4464
+
o identityIds: "Id[]"
4466
+
The EmailSubmission "identityId" property must be in this list to
4467
+
match the condition.
4469
+
o emailIds: "Id[]"
4471
+
The EmailSubmission "emailId" property must be in this list to
4472
+
match the condition.
4474
+
o threadIds: "Id[]"
4476
+
The EmailSubmission "threadId" property must be in this list to
4477
+
match the condition.
4482
+
Jenkins & Newman Standards Track [Page 80]
4484
+
RFC 8621 JMAP Mail August 2019
4487
+
o undoStatus: "String"
4489
+
The EmailSubmission "undoStatus" property must be identical to the
4490
+
value given to match the condition.
4492
+
o before: "UTCDate"
4494
+
The "sendAt" property of the EmailSubmission object must be before
4495
+
this date-time to match the condition.
4497
+
o after: "UTCDate"
4499
+
The "sendAt" property of the EmailSubmission object must be the
4500
+
same as or after this date-time to match the condition.
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.
4506
+
The following EmailSubmission properties MUST be supported for
4515
+
7.4. EmailSubmission/queryChanges
4517
+
This is a standard "/queryChanges" method as described in [RFC8620],
4520
+
7.5. EmailSubmission/set
4522
+
This is a standard "/set" method as described in [RFC8620],
4523
+
Section 5.3 with the following two additional request arguments:
4525
+
o onSuccessUpdateEmail: "Id[PatchObject]|null"
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 "#".)
4538
+
Jenkins & Newman Standards Track [Page 81]
4540
+
RFC 8621 JMAP Mail August 2019
4543
+
o onSuccessDestroyEmail: "Id[]|null"
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 "#".)
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"
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
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
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.
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.
4586
+
If the Email or Identity id given cannot be found, the submission
4587
+
creation is rejected with a standard "invalidProperties" SetError.
4594
+
Jenkins & Newman Standards Track [Page 82]
4596
+
RFC 8621 JMAP Mail August 2019
4599
+
The following extra SetError types are defined:
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
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.
4613
+
o "noRecipients" - The envelope (supplied or generated) does not
4614
+
have any rcptTo email addresses.
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.
4622
+
o "forbiddenMailFrom" - The server does not permit the user to send
4623
+
a message with the envelope From address [RFC5321].
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
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.
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.
4650
+
Jenkins & Newman Standards Track [Page 83]
4652
+
RFC 8621 JMAP Mail August 2019
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-
4665
+
[[ "EmailSubmission/set", {
4666
+
"accountId": "ue411d190",
4669
+
"identityId": "I64588216",
4670
+
"emailId": "M7f6ed5bcfd7e2604d1753f6c",
4673
+
"email": "john@example.com",
4674
+
"parameters": null
4677
+
"email": "jane@example.com",
4678
+
"parameters": null
4685
+
"onSuccessUpdateEmail": {
4687
+
"mailboxIds/7cb4e8ee-df87-4757-b9c4-2ea1ca41b38e": null,
4688
+
"mailboxIds/73dbcb4b-bffc-48bd-8c2a-a2e91ca672f6": true,
4689
+
"keywords/$draft": null
4706
+
Jenkins & Newman Standards Track [Page 84]
4708
+
RFC 8621 JMAP Mail August 2019
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:
4715
+
[[ "EmailSubmission/set", {
4716
+
"accountId": "ue411d190",
4717
+
"oldState": "012421s6-8nrq-4ps4-n0p4-9330r951ns21",
4718
+
"newState": "355421f6-8aed-4cf4-a0c4-7377e951af36",
4721
+
"id": "ES-3bab7f9a-623e-4acf-99a5-2e67facb02a0"
4726
+
"accountId": "ue411d190",
4727
+
"oldState": "778193",
4728
+
"newState": "778197",
4730
+
"M7f6ed5bcfd7e2604d1753f6c": null
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:
4740
+
Accept-Language: de;q=0.9,en;q=0.8
4762
+
Jenkins & Newman Standards Track [Page 85]
4764
+
RFC 8621 JMAP Mail August 2019
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:
4773
+
[[ "EmailSubmission/set", {
4774
+
"accountId": "ue411d190",
4775
+
"oldState": "012421s6-8nrq-4ps4-n0p4-9330r951ns21",
4776
+
"newState": "012421s6-8nrq-4ps4-n0p4-9330r951ns21",
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."
4787
+
8. Vacation Response
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.
4793
+
Automated message sending can produce undesirable behaviour. To
4794
+
avoid this, implementors MUST follow the recommendations set forth in
4797
+
The *VacationResponse* object represents the state of vacation-
4798
+
response-related settings for an account. It has the following
4801
+
o id: "Id" (immutable; server-set)
4803
+
The id of the object. There is only ever one VacationResponse
4804
+
object, and its id is "singleton".
4806
+
o isEnabled: "Boolean"
4808
+
Should a vacation response be sent if a message arrives between
4809
+
the "fromDate" and "toDate"?
4818
+
Jenkins & Newman Standards Track [Page 86]
4820
+
RFC 8621 JMAP Mail August 2019
4823
+
o fromDate: "UTCDate|null"
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.
4830
+
o toDate: "UTCDate|null"
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.
4837
+
o subject: "String|null"
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.
4843
+
o textBody: "String|null"
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.
4852
+
o htmlBody: "String|null"
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
4860
+
The following JMAP methods are supported.
4862
+
8.1. VacationResponse/get
4864
+
This is a standard "/get" method as described in [RFC8620],
4867
+
There MUST only be exactly one VacationResponse object in an account.
4868
+
It MUST have the id "singleton".
4874
+
Jenkins & Newman Standards Track [Page 87]
4876
+
RFC 8621 JMAP Mail August 2019
4879
+
8.2. VacationResponse/set
4881
+
This is a standard "/set" method as described in [RFC8620],
4884
+
9. Security Considerations
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.
4891
+
9.1. EmailBodyPart Value
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
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.
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.
4916
+
9.2. HTML Email Display
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,
4930
+
Jenkins & Newman Standards Track [Page 88]
4932
+
RFC 8621 JMAP Mail August 2019
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).
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.
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.
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.
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
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
4977
+
o Forms can be used to mimic login boxes, providing a potent
4978
+
phishing vector if allowed to submit directly from the message
4986
+
Jenkins & Newman Standards Track [Page 89]
4988
+
RFC 8621 JMAP Mail August 2019
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.
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.
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.
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
5011
+
* Disable JavaScript.
5013
+
* Disable form submission.
5015
+
* Prevent drawing outside of its bounds or conflicts between
5016
+
message CSS and interface CSS.
5018
+
* Establish a unique anonymous origin, separate to the containing
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.
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/>).
5029
+
o A "crossorigin=anonymous" attribute on tags that load remote
5030
+
content can prevent cookies from being sent.
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.
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.
5042
+
Jenkins & Newman Standards Track [Page 90]
5044
+
RFC 8621 JMAP Mail August 2019
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.
5053
+
9.3. Multiple Part Display
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].
5063
+
9.4. Email Submission
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.
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].
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.
5098
+
Jenkins & Newman Standards Track [Page 91]
5100
+
RFC 8621 JMAP Mail August 2019
5103
+
9.5. Partial Account Access
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.
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.
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.
5126
+
9.6. Permission to Send from an Address
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].
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.
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.
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.
5154
+
Jenkins & Newman Standards Track [Page 92]
5156
+
RFC 8621 JMAP Mail August 2019
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.
5166
+
The JMAP submission model provides separate errors for impermissible
5167
+
addresses in either context.
5169
+
10. IANA Considerations
5171
+
10.1. JMAP Capability Registration for "mail"
5173
+
IANA has registered the "mail" JMAP Capability as follows:
5175
+
Capability Name: urn:ietf:params:jmap:mail
5177
+
Specification document: this document
5179
+
Intended use: common
5181
+
Change Controller: IETF
5183
+
Security and privacy considerations: this document, Section 9
5185
+
10.2. JMAP Capability Registration for "submission"
5187
+
IANA has registered the "submission" JMAP Capability as follows:
5189
+
Capability Name: urn:ietf:params:jmap:submission
5191
+
Specification document: this document
5193
+
Intended use: common
5195
+
Change Controller: IETF
5197
+
Security and privacy considerations: this document, Section 9
5210
+
Jenkins & Newman Standards Track [Page 93]
5212
+
RFC 8621 JMAP Mail August 2019
5215
+
10.3. JMAP Capability Registration for "vacationresponse"
5217
+
IANA has registered the "vacationresponse" JMAP Capability as
5220
+
Capability Name: urn:ietf:params:jmap:vacationresponse
5222
+
Specification document: this document
5224
+
Intended use: common
5226
+
Change Controller: IETF
5228
+
Security and privacy considerations: this document, Section 9
5230
+
10.4. IMAP and JMAP Keywords Registry
5232
+
This document makes two changes to the IMAP keywords registry as
5233
+
defined in [RFC5788].
5235
+
First, the name of the registry is changed to the "IMAP and JMAP
5236
+
Keywords" registry.
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.
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.
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.
5266
+
Jenkins & Newman Standards Track [Page 94]
5268
+
RFC 8621 JMAP Mail August 2019
5271
+
10.4.1. Registration of JMAP Keyword "$draft"
5273
+
This registers the "JMAP-only" keyword "$draft" in the "IMAP and JMAP
5274
+
Keywords" registry.
5276
+
Keyword name: $draft
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.
5284
+
Private or Shared on a server: BOTH
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.
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.
5301
+
Related keywords: None
5303
+
Related IMAP/JMAP Capabilities: SPECIAL-USE [RFC6154]
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.
5310
+
Published specification: this document
5312
+
Person & email address to contact for further information:
5313
+
JMAP mailing list <jmap@ietf.org>
5315
+
Intended usage: COMMON
5317
+
Owner/Change controller: IESG
5322
+
Jenkins & Newman Standards Track [Page 95]
5324
+
RFC 8621 JMAP Mail August 2019
5327
+
10.4.2. Registration of JMAP Keyword "$seen"
5329
+
This registers the "JMAP-only" keyword "$seen" in the "IMAP and JMAP
5330
+
Keywords" registry.
5332
+
Keyword name: $seen
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.
5339
+
Private or Shared on a server: BOTH
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.
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
5351
+
Related keywords: None
5353
+
Related IMAP/JMAP Capabilities: None
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.
5360
+
Published specification: this document
5362
+
Person & email address to contact for further information:
5363
+
JMAP mailing list <jmap@ietf.org>
5365
+
Intended usage: COMMON
5367
+
Owner/Change controller: IESG
5378
+
Jenkins & Newman Standards Track [Page 96]
5380
+
RFC 8621 JMAP Mail August 2019
5383
+
10.4.3. Registration of JMAP Keyword "$flagged"
5385
+
This registers the "JMAP-only" keyword "$flagged" in the "IMAP and
5386
+
JMAP Keywords" registry.
5388
+
Keyword name: $flagged
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.
5396
+
Private or Shared on a server: BOTH
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.
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.
5408
+
Related keywords: None
5410
+
Related IMAP/JMAP Capabilities: SPECIAL-USE [RFC6154]
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.
5417
+
Published specification: this document
5419
+
Person & email address to contact for further information:
5420
+
JMAP mailing list <jmap@ietf.org>
5422
+
Intended usage: COMMON
5424
+
Owner/Change controller: IESG
5434
+
Jenkins & Newman Standards Track [Page 97]
5436
+
RFC 8621 JMAP Mail August 2019
5439
+
10.4.4. Registration of JMAP Keyword "$answered"
5441
+
This registers the "JMAP-only" keyword "$answered" in the "IMAP and
5442
+
JMAP Keywords" registry.
5444
+
Keyword name: $answered
5448
+
Purpose (description): This is set when the message has been
5451
+
Private or Shared on a server: BOTH
5453
+
Is it an advisory keyword or may it cause an automatic action:
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.
5462
+
Related keywords: None
5464
+
Related IMAP/JMAP Capabilities: None
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.
5471
+
Published specification: this document
5473
+
Person & email address to contact for further information:
5474
+
JMAP mailing list <jmap@ietf.org>
5476
+
Intended usage: COMMON
5478
+
Owner/Change controller: IESG
5490
+
Jenkins & Newman Standards Track [Page 98]
5492
+
RFC 8621 JMAP Mail August 2019
5495
+
10.4.5. Registration of "$recent" Keyword
5497
+
This registers the keyword "$recent" in the "IMAP and JMAP Keywords"
5500
+
Keyword name: $recent
5504
+
Purpose (description): This keyword is not used to avoid confusion
5505
+
with the IMAP \Recent system flag.
5507
+
Published specification: this document
5509
+
Person & email address to contact for further information:
5510
+
JMAP mailing list <jmap@ietf.org>
5512
+
Owner/Change controller: IESG
5514
+
10.5. IMAP Mailbox Name Attributes Registry
5516
+
10.5.1. Registration of "inbox" Role
5518
+
This registers the "JMAP-only" "inbox" attribute in the "IMAP Mailbox
5519
+
Name Attributes" registry, as established in [RFC8457].
5521
+
Attribute Name: Inbox
5523
+
Description: New mail is delivered here by default.
5525
+
Reference: This document, Section 10.5.1
5527
+
Usage Notes: JMAP only
5546
+
Jenkins & Newman Standards Track [Page 99]
5548
+
RFC 8621 JMAP Mail August 2019
5551
+
10.6. JMAP Error Codes Registry
5553
+
The following subsections register several new error codes in the
5554
+
"JMAP Error Codes" registry, as defined in [RFC8620].
5556
+
10.6.1. mailboxHasChild
5558
+
JMAP Error Code: mailboxHasChild
5560
+
Intended use: common
5562
+
Change controller: IETF
5564
+
Reference: This document, Section 2.5
5566
+
Description: The Mailbox still has at least one child Mailbox. The
5567
+
client MUST remove these before it can delete the parent Mailbox.
5569
+
10.6.2. mailboxHasEmail
5571
+
JMAP Error Code: mailboxHasEmail
5573
+
Intended use: common
5575
+
Change controller: IETF
5577
+
Reference: This document, Section 2.5
5579
+
Description: The Mailbox has at least one message assigned to it, and
5580
+
the onDestroyRemoveEmails argument was false.
5582
+
10.6.3. blobNotFound
5584
+
JMAP Error Code: blobNotFound
5586
+
Intended use: common
5588
+
Change controller: IETF
5590
+
Reference: This document, Section 4.6
5592
+
Description: At least one blob id referenced in the object doesn't
5602
+
Jenkins & Newman Standards Track [Page 100]
5604
+
RFC 8621 JMAP Mail August 2019
5607
+
10.6.4. tooManyKeywords
5609
+
JMAP Error Code: tooManyKeywords
5611
+
Intended use: common
5613
+
Change controller: IETF
5615
+
Reference: This document, Section 4.6
5617
+
Description: The change to the Email's keywords would exceed a
5618
+
server-defined maximum.
5620
+
10.6.5. tooManyMailboxes
5622
+
JMAP Error Code: tooManyMailboxes
5624
+
Intended use: common
5626
+
Change controller: IETF
5628
+
Reference: This document, Section 4.6
5630
+
Description: The change to the set of Mailboxes that this Email is in
5631
+
would exceed a server-defined maximum.
5633
+
10.6.6. invalidEmail
5635
+
JMAP Error Code: invalidEmail
5637
+
Intended use: common
5639
+
Change controller: IETF
5641
+
Reference: This document, Section 7.5
5643
+
Description: The Email to be sent is invalid in some way.
5658
+
Jenkins & Newman Standards Track [Page 101]
5660
+
RFC 8621 JMAP Mail August 2019
5663
+
10.6.7. tooManyRecipients
5665
+
JMAP Error Code: tooManyRecipients
5667
+
Intended use: common
5669
+
Change controller: IETF
5671
+
Reference: This document, Section 7.5
5673
+
Description: The envelope [RFC5321] (supplied or generated) has more
5674
+
recipients than the server allows.
5676
+
10.6.8. noRecipients
5678
+
JMAP Error Code: noRecipients
5680
+
Intended use: common
5682
+
Change controller: IETF
5684
+
Reference: This document, Section 7.5
5686
+
Description: The envelope [RFC5321] (supplied or generated) does not
5687
+
have any rcptTo email addresses.
5689
+
10.6.9. invalidRecipients
5691
+
JMAP Error Code: invalidRecipients
5693
+
Intended use: common
5695
+
Change controller: IETF
5697
+
Reference: This document, Section 7.5
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.
5714
+
Jenkins & Newman Standards Track [Page 102]
5716
+
RFC 8621 JMAP Mail August 2019
5719
+
10.6.10. forbiddenMailFrom
5721
+
JMAP Error Code: forbiddenMailFrom
5723
+
Intended use: common
5725
+
Change controller: IETF
5727
+
Reference: This document, Section 7.5
5729
+
Description: The server does not permit the user to send a message
5730
+
with this envelope From address [RFC5321].
5732
+
10.6.11. forbiddenFrom
5734
+
JMAP Error Code: forbiddenFrom
5736
+
Intended use: common
5738
+
Change controller: IETF
5740
+
Reference: This document, Sections 6.3 and 7.5
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.
5745
+
10.6.12. forbiddenToSend
5747
+
JMAP Error Code: forbiddenToSend
5749
+
Intended use: common
5751
+
Change controller: IETF
5753
+
Reference: This document, Section 7.5
5755
+
Description: The user does not have permission to send at all right
5770
+
Jenkins & Newman Standards Track [Page 103]
5772
+
RFC 8621 JMAP Mail August 2019
5777
+
11.1. Normative References
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/>.
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>.
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>.
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>.
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>.
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>.
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>.
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>.
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>.
5826
+
Jenkins & Newman Standards Track [Page 104]
5828
+
RFC 8621 JMAP Mail August 2019
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>.
5835
+
[RFC3282] Alvestrand, H., "Content Language Headers", RFC 3282,
5836
+
DOI 10.17487/RFC3282, May 2002,
5837
+
<https://www.rfc-editor.org/info/rfc3282>.
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>.
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>.
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>.
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>.
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>.
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>.
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>.
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>.
5882
+
Jenkins & Newman Standards Track [Page 105]
5884
+
RFC 8621 JMAP Mail August 2019
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>.
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>.
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>.
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>.
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>.
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>.
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>.
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>.
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>.
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>.
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>.
5938
+
Jenkins & Newman Standards Track [Page 106]
5940
+
RFC 8621 JMAP Mail August 2019
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>.
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>.
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>.
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>.
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>.
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>.
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>.
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>.
5979
+
11.2. Informative References
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>.
5988
+
[milter] Postfix, "Postfix before-queue Milter support", 2019,
5989
+
<http://www.postfix.org/MILTER_README.html>.
5994
+
Jenkins & Newman Standards Track [Page 107]
5996
+
RFC 8621 JMAP Mail August 2019
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>.
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>.
6008
+
[XCLIENT] Postfix, "Postfix XCLIENT Howto", 2019,
6009
+
<http://www.postfix.org/XCLIENT_README.html>.
6011
+
Authors' Addresses
6015
+
PO Box 234, Collins St. West
6016
+
Melbourne, VIC 8007
6019
+
Email: neilj@fastmailteam.com
6020
+
URI: https://www.fastmail.com
6025
+
440 E. Huntington Dr., Suite 400
6027
+
United States of America
6029
+
Email: chris.newman@oracle.com
6050
+
Jenkins & Newman Standards Track [Page 108]