draft-ietf-jmap-mail-08.txt   draft-ietf-jmap-mail-09.txt 
JMAP N. Jenkins JMAP N. Jenkins
Internet-Draft FastMail Internet-Draft FastMail
Updates: 5788 (if approved) C. Newman Updates: 5788 (if approved) C. Newman
Intended status: Standards Track Oracle Intended status: Standards Track Oracle
Expires: March 14, 2019 September 10, 2018 Expires: April 26, 2019 October 23, 2018
JMAP for Mail JMAP for Mail
draft-ietf-jmap-mail-08 draft-ietf-jmap-mail-09
Abstract Abstract
This document specifies a data model for synchronising email data This document specifies a data model for synchronising email data
with a server using JMAP. with a server using JMAP.
Status of This Memo Status of This Memo
This Internet-Draft is submitted in full conformance with the This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79. provisions of BCP 78 and BCP 79.
skipping to change at page 1, line 32 skipping to change at page 1, line 32
Internet-Drafts are working documents of the Internet Engineering Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet- working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/. Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
This Internet-Draft will expire on March 14, 2019. This Internet-Draft will expire on April 26, 2019.
Copyright Notice Copyright Notice
Copyright (c) 2018 IETF Trust and the persons identified as the Copyright (c) 2018 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents
(https://trustee.ietf.org/license-info) in effect on the date of (https://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents publication of this document. Please review these documents
skipping to change at page 2, line 45 skipping to change at page 2, line 45
4.3. Email/changes . . . . . . . . . . . . . . . . . . . . . . 37 4.3. Email/changes . . . . . . . . . . . . . . . . . . . . . . 37
4.4. Email/query . . . . . . . . . . . . . . . . . . . . . . . 38 4.4. Email/query . . . . . . . . . . . . . . . . . . . . . . . 38
4.4.1. Filtering . . . . . . . . . . . . . . . . . . . . . . 38 4.4.1. Filtering . . . . . . . . . . . . . . . . . . . . . . 38
4.4.2. Sorting . . . . . . . . . . . . . . . . . . . . . . . 40 4.4.2. Sorting . . . . . . . . . . . . . . . . . . . . . . . 40
4.4.3. Thread collapsing . . . . . . . . . . . . . . . . . . 42 4.4.3. Thread collapsing . . . . . . . . . . . . . . . . . . 42
4.4.4. Response . . . . . . . . . . . . . . . . . . . . . . 42 4.4.4. Response . . . . . . . . . . . . . . . . . . . . . . 42
4.5. Email/queryChanges . . . . . . . . . . . . . . . . . . . 42 4.5. Email/queryChanges . . . . . . . . . . . . . . . . . . . 42
4.6. Email/set . . . . . . . . . . . . . . . . . . . . . . . . 42 4.6. Email/set . . . . . . . . . . . . . . . . . . . . . . . . 42
4.7. Email/copy . . . . . . . . . . . . . . . . . . . . . . . 45 4.7. Email/copy . . . . . . . . . . . . . . . . . . . . . . . 45
4.8. Email/import . . . . . . . . . . . . . . . . . . . . . . 45 4.8. Email/import . . . . . . . . . . . . . . . . . . . . . . 45
4.9. Email/parse . . . . . . . . . . . . . . . . . . . . . . . 46 4.9. Email/parse . . . . . . . . . . . . . . . . . . . . . . . 47
4.10. Examples . . . . . . . . . . . . . . . . . . . . . . . . 48 4.10. Examples . . . . . . . . . . . . . . . . . . . . . . . . 49
5. Search snippets . . . . . . . . . . . . . . . . . . . . . . . 56 5. Search snippets . . . . . . . . . . . . . . . . . . . . . . . 57
5.1. SearchSnippet/get . . . . . . . . . . . . . . . . . . . . 57 5.1. SearchSnippet/get . . . . . . . . . . . . . . . . . . . . 58
5.2. Example . . . . . . . . . . . . . . . . . . . . . . . . . 58 5.2. Example . . . . . . . . . . . . . . . . . . . . . . . . . 59
6. Identities . . . . . . . . . . . . . . . . . . . . . . . . . 59 6. Identities . . . . . . . . . . . . . . . . . . . . . . . . . 60
6.1. Identity/get . . . . . . . . . . . . . . . . . . . . . . 60 6.1. Identity/get . . . . . . . . . . . . . . . . . . . . . . 61
6.2. Identity/changes . . . . . . . . . . . . . . . . . . . . 60 6.2. Identity/changes . . . . . . . . . . . . . . . . . . . . 61
6.3. Identity/set . . . . . . . . . . . . . . . . . . . . . . 60 6.3. Identity/set . . . . . . . . . . . . . . . . . . . . . . 61
6.4. Example . . . . . . . . . . . . . . . . . . . . . . . . . 60 6.4. Example . . . . . . . . . . . . . . . . . . . . . . . . . 61
7. Email submission . . . . . . . . . . . . . . . . . . . . . . 61 7. Email submission . . . . . . . . . . . . . . . . . . . . . . 62
7.1. EmailSubmission/get . . . . . . . . . . . . . . . . . . . 66 7.1. EmailSubmission/get . . . . . . . . . . . . . . . . . . . 67
7.2. EmailSubmission/changes . . . . . . . . . . . . . . . . . 66 7.2. EmailSubmission/changes . . . . . . . . . . . . . . . . . 67
7.3. EmailSubmission/query . . . . . . . . . . . . . . . . . . 66 7.3. EmailSubmission/query . . . . . . . . . . . . . . . . . . 67
7.4. EmailSubmission/queryChanges . . . . . . . . . . . . . . 67 7.4. EmailSubmission/queryChanges . . . . . . . . . . . . . . 68
7.5. EmailSubmission/set . . . . . . . . . . . . . . . . . . . 67 7.5. EmailSubmission/set . . . . . . . . . . . . . . . . . . . 68
7.5.1. Example . . . . . . . . . . . . . . . . . . . . . . . 69 7.5.1. Example . . . . . . . . . . . . . . . . . . . . . . . 70
8. Vacation response . . . . . . . . . . . . . . . . . . . . . . 71 8. Vacation response . . . . . . . . . . . . . . . . . . . . . . 72
8.1. VacationResponse/get . . . . . . . . . . . . . . . . . . 72 8.1. VacationResponse/get . . . . . . . . . . . . . . . . . . 73
8.2. VacationResponse/set . . . . . . . . . . . . . . . . . . 72 8.2. VacationResponse/set . . . . . . . . . . . . . . . . . . 73
9. Security considerations . . . . . . . . . . . . . . . . . . . 72 9. Security considerations . . . . . . . . . . . . . . . . . . . 73
9.1. EmailBodyPart value . . . . . . . . . . . . . . . . . . . 72 9.1. EmailBodyPart value . . . . . . . . . . . . . . . . . . . 73
9.2. HTML email display . . . . . . . . . . . . . . . . . . . 72 9.2. HTML email display . . . . . . . . . . . . . . . . . . . 73
9.3. Email submission . . . . . . . . . . . . . . . . . . . . 75 9.3. Email submission . . . . . . . . . . . . . . . . . . . . 76
10. IANA considerations . . . . . . . . . . . . . . . . . . . . . 75 10. IANA considerations . . . . . . . . . . . . . . . . . . . . . 76
10.1. JMAP capability registration for "mail" . . . . . . . . 75 10.1. JMAP capability registration for "mail" . . . . . . . . 76
10.2. JMAP capability registration for "submission" . . . . . 76 10.2. JMAP capability registration for "submission" . . . . . 77
10.3. JMAP capability registration for "vacationresponse" . . 76 10.3. JMAP capability registration for "vacationresponse" . . 77
10.4. IMAP and JMAP keywords registry . . . . . . . . . . . . 76 10.4. IMAP and JMAP keywords registry . . . . . . . . . . . . 77
10.4.1. Registration of JMAP keyword '$draft' . . . . . . . 77 10.4.1. Registration of JMAP keyword '$draft' . . . . . . . 78
10.4.2. Registration of JMAP keyword '$seen' . . . . . . . . 78 10.4.2. Registration of JMAP keyword '$seen' . . . . . . . . 79
10.4.3. Registration of JMAP keyword '$flagged' . . . . . . 79 10.4.3. Registration of JMAP keyword '$flagged' . . . . . . 80
10.4.4. Registration of JMAP keyword '$answered' . . . . . . 79 10.4.4. Registration of JMAP keyword '$answered' . . . . . . 80
10.4.5. Registration of '$recent' keyword . . . . . . . . . 80 10.4.5. Registration of '$recent' keyword . . . . . . . . . 81
10.5. Registration of "inbox" role in . . . . . . . . . . . . 81 10.5. Registration of "inbox" role in . . . . . . . . . . . . 82
10.6. JMAP Error Codes registry . . . . . . . . . . . . . . . 81 10.6. JMAP Error Codes registry . . . . . . . . . . . . . . . 82
10.6.1. mailboxHasChild . . . . . . . . . . . . . . . . . . 81 10.6.1. mailboxHasChild . . . . . . . . . . . . . . . . . . 82
10.6.2. mailboxHasEmail . . . . . . . . . . . . . . . . . . 81 10.6.2. mailboxHasEmail . . . . . . . . . . . . . . . . . . 82
10.6.3. blobNotFound . . . . . . . . . . . . . . . . . . . . 82 10.6.3. blobNotFound . . . . . . . . . . . . . . . . . . . . 83
10.6.4. tooManyKeywords . . . . . . . . . . . . . . . . . . 82 10.6.4. tooManyKeywords . . . . . . . . . . . . . . . . . . 83
10.6.5. tooManyMailboxes . . . . . . . . . . . . . . . . . . 82 10.6.5. tooManyMailboxes . . . . . . . . . . . . . . . . . . 83
10.6.6. emailNotFound . . . . . . . . . . . . . . . . . . . 82 10.6.6. emailNotFound . . . . . . . . . . . . . . . . . . . 83
10.6.7. emailTooLarge . . . . . . . . . . . . . . . . . . . 82 10.6.7. emailTooLarge . . . . . . . . . . . . . . . . . . . 83
10.6.8. invalidEmail . . . . . . . . . . . . . . . . . . . . 83 10.6.8. invalidEmail . . . . . . . . . . . . . . . . . . . . 84
10.6.9. tooManyRecipients . . . . . . . . . . . . . . . . . 83 10.6.9. tooManyRecipients . . . . . . . . . . . . . . . . . 84
10.6.10. noRecipients . . . . . . . . . . . . . . . . . . . . 83 10.6.10. noRecipients . . . . . . . . . . . . . . . . . . . . 84
10.6.11. invalidRecipients . . . . . . . . . . . . . . . . . 83 10.6.11. invalidRecipients . . . . . . . . . . . . . . . . . 84
10.6.12. forbiddenMailFrom . . . . . . . . . . . . . . . . . 83 10.6.12. forbiddenMailFrom . . . . . . . . . . . . . . . . . 84
10.6.13. forbiddenFrom . . . . . . . . . . . . . . . . . . . 84 10.6.13. forbiddenFrom . . . . . . . . . . . . . . . . . . . 85
10.6.14. forbiddenToSend . . . . . . . . . . . . . . . . . . 84 10.6.14. forbiddenToSend . . . . . . . . . . . . . . . . . . 85
11. References . . . . . . . . . . . . . . . . . . . . . . . . . 84 11. References . . . . . . . . . . . . . . . . . . . . . . . . . 85
11.1. Normative References . . . . . . . . . . . . . . . . . . 84 11.1. Normative References . . . . . . . . . . . . . . . . . . 85
11.2. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 87 11.2. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 87 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 88
1. Introduction 1. Introduction
JMAP <https://tools.ietf.org/html/draft-ietf-jmap-core-05> is a JMAP <https://tools.ietf.org/html/draft-ietf-jmap-core-05> is a
generic protocol for synchronising data, such as mail, calendars or generic protocol for synchronising data, such as mail, calendars or
contacts, between a client and a server. It is optimised for mobile contacts, between a client and a server. It is optimised for mobile
and web environments, and aims to provide a consistent interface to and web environments, and aims to provide a consistent interface to
different data types. different data types.
This specification defines a data model for synchronising mail This specification defines a data model for synchronising mail
skipping to change at page 44, line 6 skipping to change at page 44, line 6
* The client may specify a partId OR a blobId but not both. If a * The client may specify a partId OR a blobId but not both. If a
partId is given, this partId MUST be present in the bodyValues partId is given, this partId MUST be present in the bodyValues
property. property.
* The charset property MUST be omitted if a partId is given (the * The charset property MUST be omitted if a partId is given (the
part's content is included in bodyValues and the server may part's content is included in bodyValues and the server may
choose any appropriate encoding). choose any appropriate encoding).
* The size property MUST be omitted if a partId is given. If a * The size property MUST be omitted if a partId is given. If a
blobId is given, it may be omitted, but otherwise MUST match blobId is given, it may be included but is ignored by the
the size of the blob. server (the size is actually calculated from the blob content
itself).
* A "Content-Transfer-Encoding" header field MUST NOT be given. * A "Content-Transfer-Encoding" header field MUST NOT be given.
o Within an EmailBodyValue object, isEncodingProblem and isTruncated o Within an EmailBodyValue object, isEncodingProblem and isTruncated
MUST be either "false" or omitted. MUST be either "false" or omitted.
Creation attempts that violate any of this SHOULD be rejected with an Creation attempts that violate any of this SHOULD be rejected with an
"invalidProperties" error, however a server MAY choose to modify the "invalidProperties" error, however a server MAY choose to modify the
Email (e.g. choose between conflicting headers, use a different Email (e.g. choose between conflicting headers, use a different
content-encoding etc.) to comply with its requirements instead. content-encoding etc.) to comply with its requirements instead.
skipping to change at page 45, line 36 skipping to change at page 45, line 36
new object. new object.
4.8. Email/import 4.8. Email/import
The _Email/import_ method adds [RFC5322] messages to a user's set of The _Email/import_ method adds [RFC5322] messages to a user's set of
emails. The messages must first be uploaded as a file using the emails. The messages must first be uploaded as a file using the
standard upload mechanism. It takes the following arguments: standard upload mechanism. It takes the following arguments:
o *accountId*: "String" The id of the account to use. o *accountId*: "String" The id of the account to use.
o *ifInState*: "String|null" This is a state string as returned by
the _Email/get_ method. If supplied, the string must match the
current state of the account referenced by the accountId,
otherwise the method will be aborted and a "stateMismatch" error
returned. If "null", any changes will be applied to the current
state.
o *emails*: "String[EmailImport]" A map of creation id (client o *emails*: "String[EmailImport]" A map of creation id (client
specified) to EmailImport objects specified) to EmailImport objects
An *EmailImport* object has the following properties: An *EmailImport* object has the following properties:
o *blobId*: "String" The id of the blob containing the raw [RFC5322] o *blobId*: "String" The id of the blob containing the raw [RFC5322]
message. message.
o *mailboxIds*: "String[Boolean]" The ids of the mailboxes to assign o *mailboxIds*: "String[Boolean]" The ids of the mailboxes to assign
this email to. At least one mailbox MUST be given. this email to. At least one mailbox MUST be given.
skipping to change at page 46, line 38 skipping to change at page 46, line 44
MAY modify the message to fix errors (such as removing NUL octets or MAY modify the message to fix errors (such as removing NUL octets or
fixing invalid headers). If it does this, the _blobId_ on the fixing invalid headers). If it does this, the _blobId_ on the
response MUST represent the new representation and therefore be response MUST represent the new representation and therefore be
different to the _blobId_ on the EmailImport object. Alternatively, different to the _blobId_ on the EmailImport object. Alternatively,
the server MAY reject the import with an "invalidEmail" SetError. the server MAY reject the import with an "invalidEmail" SetError.
The response has the following arguments: The response has the following arguments:
o *accountId*: "String" The id of the account used for this call. o *accountId*: "String" The id of the account used for this call.
o *oldState*: "String|null" The state string that would have been
returned by _Email/get_ on this account before making the
requested changes, or "null" if the server doesn't know what the
previous state string was.
o *newState*: "String" The state string that will now be returned by
_Email/get_ on this account.
o *created*: "String[Email]" A map of the creation id to an object o *created*: "String[Email]" A map of the creation id to an object
containing the _id_, _blobId_, _threadId_ and _size_ properties containing the _id_, _blobId_, _threadId_ and _size_ properties
for each successfully imported Email. for each successfully imported Email.
o *notCreated*: "String[SetError]" A map of creation id to a o *notCreated*: "String[SetError]" A map of creation id to a
SetError object for each Email that failed to be created. The SetError object for each Email that failed to be created. The
possible errors are defined above. possible errors are defined above.
The following additional errors may be returned instead of the _Foo/
copy_ response:
"stateMismatch": An "ifInState" argument was supplied and it does not
match the current state
4.9. Email/parse 4.9. Email/parse
This method allows you to parse blobs as [RFC5322] messages to get This method allows you to parse blobs as [RFC5322] messages to get
Email objects. This can be used to parse and display attached emails Email objects. This can be used to parse and display attached emails
without having to import them as top-level email objects in the mail without having to import them as top-level email objects in the mail
store in their own right. store in their own right.
The following metadata properties on the Email objects will be "null" The following metadata properties on the Email objects will be "null"
if requested: if requested:
skipping to change at page 55, line 27 skipping to change at page 56, line 27
... ...
}, "0" ]] }, "0" ]]
The client moves this draft to a different account. The only way to The client moves this draft to a different account. The only way to
do this is via the "/copy" method. It MUST set a new mailboxIds do this is via the "/copy" method. It MUST set a new mailboxIds
property, since the current value will not be valid mailbox ids in property, since the current value will not be valid mailbox ids in
the destination account: the destination account:
[[ "Email/copy", { [[ "Email/copy", {
"fromAccountId": "ue150411c", "fromAccountId": "ue150411c",
"toAccountId": "6c6c41ac", "accountId": "6c6c41ac",
"create": { "create": {
"k45": { "k45": {
"id": "Md45b47b4877521042cec0938", "id": "Md45b47b4877521042cec0938",
"mailboxIds": { "mailboxIds": {
"75a4c956": true "75a4c956": true
} }
} }
}, },
"onSuccessDestroyOriginal": true "onSuccessDestroyOriginal": true
}, "0" ]] }, "0" ]]
The server successfully copies the email and deletes the original. The server successfully copies the email and deletes the original.
Due to the implicit call to "Email/set", there are two responses to Due to the implicit call to "Email/set", there are two responses to
the single method call, both with the same client id: the single method call, both with the same client id:
[[ "Email/copy", { [[ "Email/copy", {
"fromAccountId": "ue150411c", "fromAccountId": "ue150411c",
"toAccountId": "6c6c41ac", "accountId": "6c6c41ac",
"oldState": "7ee7e9263a6d",
"newState": "5a0d2447ed26",
"created": { "created": {
"k45": { "k45": {
"id": "M138f9954a5cd2423daeafa55", "id": "M138f9954a5cd2423daeafa55",
"blobId": "G6b9fb047cba722c48c611e79233d057c6b0b74e8", "blobId": "G6b9fb047cba722c48c611e79233d057c6b0b74e8",
"threadId": "T2f242ea424a4079a", "threadId": "T2f242ea424a4079a",
"size": 11721 "size": 11721
} }
}, },
"notCreated": null "notCreated": null
}, "0" ], }, "0" ],
 End of changes. 10 change blocks. 
61 lines changed or deleted 85 lines changed or added

This html diff was produced by rfcdiff 1.47. The latest version is available from http://tools.ietf.org/tools/rfcdiff/