
From nobody Wed Feb  7 22:11:32 2018
Return-Path: <neilj@fastmailteam.com>
X-Original-To: jmap@ietfa.amsl.com
Delivered-To: jmap@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id BDB6312773A for <jmap@ietfa.amsl.com>; Wed,  7 Feb 2018 22:11:30 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.719
X-Spam-Level: 
X-Spam-Status: No, score=-2.719 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=fastmailteam.com header.b=t5WJ0TzZ; dkim=pass (2048-bit key) header.d=messagingengine.com header.b=ddwk5bGe
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id qQ-euRirMLko for <jmap@ietfa.amsl.com>; Wed,  7 Feb 2018 22:11:26 -0800 (PST)
Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 67AC21243F6 for <jmap@ietf.org>; Wed,  7 Feb 2018 22:11:26 -0800 (PST)
Received: from betaweb1.internal (betaweb1.nyi.internal [10.202.2.10]) by mailout.nyi.internal (Postfix) with ESMTP id B44D920E45 for <jmap@ietf.org>; Thu,  8 Feb 2018 01:11:25 -0500 (EST)
Received: from betaweb1 ([::ffff:10.202.2.10]) by betaweb1.internal (MEProxy); Thu, 08 Feb 2018 01:11:25 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= fastmailteam.com; h=content-transfer-encoding:content-type:date :from:message-id:mime-version:subject:to:x-me-sender:x-me-sender :x-sasl-enc; s=fm1; bh=ErqdJKOVpLZMH4i0lQ3TlI0ZwmKqHnR9SB1GH9us4 ks=; b=t5WJ0TzZPRgg9cMaZ+xQO1faoq9ie36rzMKD1f+SLHWUKZFansmPgu5oS zFUcV3d5Je+olugiGvWSvF2vH5593TMeRZhNoVgYR+8dPMZ9PVeM5QrZmNmgb6QX 6rwT/MaS+BxxMEEkg7rgSTBcjPYzMyXpebCwbhRZv05XDHlEqYBjbPrVBjwth9HM 5a0Xr6Gj701linSqy1okl4iq8fNDVjGLUNucKSUg1d/1BUort0FkMyX9vVCRXnqf TLkXwIglsTVNs9Qt+zPmzOzvyqcvWibr3WU5KgvqF2TNbJ4H407P3bqQ1uM24XNy Pw/CdW0djft7DmsLXLnoM0aZmIShg==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:message-id:mime-version:subject:to:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; bh=ErqdJKOVpLZMH4i0lQ3TlI0ZwmKqH nR9SB1GH9us4ks=; b=ddwk5bGeCQNWlf/Iuu8RUXXdukSNvIXJm2xRjuewECeeW CFC6lYFC7QBzU094LZPVgTrORbxDApl+pmpzDsFUJvMdPz1C55b5pTi3QFLkY22f D9fFrjgEGJiUHRVwSwndSnDtkCHMVDeclK1XmBZdpYj5gu0sIs/lLbfWLydb4A/x Tj5o28m1DpLIbj9JLDwuq/qnZFQPKA6Y6EGM3f5b8Nn5p6BlqBATwVSTxQMf3veS X8wdFPa9XorU3NXvRN4P8odxfQ8aWprbyVRTZUTvZUM5qiTZ5bBHe2ay0j2pvH7X v4cKGZpijNOuPSwNSr3Jue60l2q77GUQ0wre4ldlg==
X-ME-Sender: <xms:Dep7WvfrnlNTRFdT1jjdzu9F0hFbOijkQxRlk9O5kaLcxmqBa4ATAA>
Received: by mailuser.nyi.internal (Postfix, from userid 99) id 51EDEE22A4; Thu,  8 Feb 2018 01:11:25 -0500 (EST)
Message-Id: <1518070284.168650.1263633200.05C7397A@webmail.messagingengine.com>
From: Neil Jenkins <neilj@fastmailteam.com>
To: IETF JMAP Mailing List <jmap@ietf.org>
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Type: multipart/alternative; boundary="_----------=_15180702851686500"
X-Mailer: MessagingEngine.com Webmail Interface - ajax-2ce04827
Date: Thu, 08 Feb 2018 17:11:24 +1100
Archived-At: <https://mailarchive.ietf.org/arch/msg/jmap/nrCOX8jLvnceJm5TxkyFh48n9P4>
Subject: [Jmap] New JSON message representation
X-BeenThere: jmap@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: JSON Message Access Protocol <jmap.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/jmap>, <mailto:jmap-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/jmap/>
List-Post: <mailto:jmap@ietf.org>
List-Help: <mailto:jmap-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/jmap>, <mailto:jmap-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 08 Feb 2018 06:11:31 -0000

This is a multi-part message in MIME format.

--_----------=_15180702851686500
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"

With an eye to closing off all remaining issues before the next IETF
meeting in March, I have been looking at the issues raised with the JSON
representation of an RFC5322 message. This email presents a new proposal
that I think resolves the issues presented. In particular, I aim to
address the following goals:
 * Allow access to the full MIME structure without requiring the client
   to parse the full message itself.
 * Allow access to full header field information if required.
 * Keep a simpler representation available for the common case.
 * Allow the client to only load the data required.Comments, suggestions an=
d other feedback requested. Cheers!

------
Emails


The *Email* object is a representation of an [@!RFC5322] message, which
allows clients to avoid the complexities of MIME parsing, transport
encoding and character encoding.Properties of the Email object


Broadly, a message consists of two parts: a list of header fields, then
a body. The body is normally a MIME-encoded set of documents in a tree
structure. The JMAP Email object provides a way to access the full
structure, or to use simplified properties and avoid some complexity if
this is sufficient for the client application.Due to the number of properti=
es involved, the set of *Email* properties
is specified over the following three sub-sections.Metadata


These properties represent metadata about the [@!RFC5322] message, and
are not derived from parsing the message itself.


 * *id*: String (immutable; server-set) The id of the Email object.
   Note, this is the JMAP object id, NOT the [@!RFC5322] Message-Id
   header field value.


 * *blobId*: String (immutable; server-set) The id representing the raw
   bytes of the [@!RFC5322] message. This may be used to download the
   raw original message, or to attach it directly to another Email etc.


 * *threadId*: String (immutable; server-set) The id of the Thread to
   which this Email belongs.


 * *mailboxIds*: String[Boolean] The set of mailbox ids this email
   belongs to. An email MUST belong to one or more mailboxes at all
   times (until it is deleted). The set is represented as an object,
   with each key being a *Mailbox id*. The value for each key in the
   object MUST be true.


 * *keywords*: String[Boolean] (default: {}) A set of keywords that
   apply to the email. The set is represented as an object, with the
   keys being the *keywords*. The value for each key in the object
   MUST be true.


Keywords are shared with IMAP. The six system keywords from IMAP are
treated specially. The following four keywords have their first
character changed from \ in IMAP to $ in JMAP and have particular
semantic meaning:


   * $Draft: The email is a draft the user is composing.
   * $Seen: The email has been read.
   * $Flagged: The email has been flagged for urgent/special attention.
   * $Answered: The email has been replied to. The IMAP \Recent keyword
     is not exposed via JMAP. The IMAP \Deleted keyword is also not
     present: IMAP uses a delete+expunge model, which JMAP does not. Any
     message with the \Deleted keyword MUST NOT be visible via JMAP.


Users may add arbitrary keywords to an email. For compatibility with
IMAP, a keyword is a (case-sensitive) string of 1=E2=80=93255 characters in=
 the
ASCII subset %x21=E2=80=93%x7e (excludes control chars and space), and MUST=
 NOT
include any of these characters: ( ) { ] % * " \


The IANA Keyword Registry[1] as established in [@!RFC5788] assigns
semantic meaning to some other keywords in common use. New keywords may
be established here in the future. In particular, note:


   * $Forwarded: The email has been forwarded.
   * $Phishing: The email is highly likely to be phishing. Clients
     SHOULD warn users to take care when viewing this email and disable
     links and attachments.
   * $Junk: The email is definitely spam. Clients SHOULD set this
     flag when users report spam to help train automated spam-
     detection systems.
   * $NotJunk: The email is definitely not spam. Clients SHOULD set this
     flag when users indicate an email is legitimate, to help train
     automated spam-detection systems.
 * *size*: Number (immutable; server-set) The size in bytes of the whole
   email as counted by the server towards the user's quota.


 * *receivedAt*: UTCDate (immutable; default: time of creation on
   server) The date the email was received by the message store. This is
   the *internal date* in IMAP.Header fields


These properties are derived from the [@!RFC5322] message header fields.
Header fields may be fetched in a variety of forms:


 * *Decoded* The header field value with:


   1. White space unfolded (as defined in [@!RFC5322] section 2.2.3)
   2. The terminating CRLF at the end of the value removed
   3. Any SP characters at the beginning of the value removed
   4. Any [@!RFC2047] encoded sections decoded
   5. Any [@!RFC6532] UTF-8 values decoded If any decodings fail, the
      parser SHOULD insert a unicode replacement character (U+FFFD) and
      attempt to continue as much as possible.


 * *Raw Base64* The raw bytes of the header field value from the first
   byte following the header field name terminating colon, up to but
   excluding the header field terminating CRLF, encoded as Base64
   ([@!RFC4648]). (Note, this is required as the value may not be valid
   UTF-8 if 8-bit values are present.)


 * *Addresses* The header is parsed as an address-list value, as
   specified in [@!RFC5322] section 3.4, into the EmailAddress[] type.
   The *EmailAddress* object has the following properties:


   * *name*: String|null The *display name* of the [@!RFC5322] *mailbox*
     or *group*, or null if none.
   * *email*: String|null The *addr-spec* of the [@!RFC5322] *mailbox*,
     or null if a *group*. Parsing SHOULD be best-effort in the face of
     invalid structure to accommodate invalid messages and semi-complete
     drafts. EmailAddress objects MAY have an *email* property that does
     not conform to the *addr-spec* form (for example, may not contain
     an @ symbol).


 * *Date* The header is parsed as a date-time value, as specified in
   [@!RFC5322] section 3.3, into the Date type.The following *Email* proper=
ties are specified for complete access to
the header data of the message. Where {header-field-name} is specified
within a property name, this means any series of one or more printable
US-ASCII characters (i.e. characters that have values between 33 and
126, inclusive), except colon:


 * *headers*: EmailHeader[] (immutable) This is a list of all
   [@!RFC5322] header fields, in the same order they appear in the
   message. The values are in *Decoded* form.
 * *headers:asRaw*: EmailHeader[] (immutable) This is a list of all
   [@!RFC5322] header fields, in the same order they appear in the
   message. The values are in *Raw Base64* form.
 * *header:{header-field-name}*: String|null (immutable) The value of
   the *last* header field in the message with the given header field
   name (matched case-insensitively), or null if none. The value is in
   *Decoded* form.
 * *header:{header-field-name}:asRaw*: String|null (immutable) The value
   of the *last* header field in the message with the given header field
   name (matched case-insensitively), or null if none. The value is in
   *Raw Base64* form.
 * *header:{header-field-name}:asAddresses*: EmailAddress[]|null
   (immutable) The value of the *last* header field in the message with
   the given header field name (matched case-insensitively), or null if
   none. The value is in *Addresses* form.
 * *header:{header-field-name}:asDate*: Date|null (immutable) The value
   of the *last* header field in the message with the given header field
   name (matched case-insensitively), or null if none. The value is in
   *Date* form.An *EmailHeader* object has the following properties:


 * *name*: String The header *field name* as defined in RFC5322, with
   the same capitalization that it has in the message.
 * *value*: String The header *field value* as defined in RFC5322, in
   either *Decoded* or *Raw Base64* form as determined by the property
   being fetched.The following convenience properties are also specified fo=
r the
*Email* object:


 * *sender*: EmailAddress[]|null (immutable) The value is identical to
   the value of *header:Sender:asAddresses*.
 * *from*: EmailAddress[]|null (immutable) The value is identical to the
   value of *header:From:asAddresses*.
 * *to*: EmailAddress[]|null (immutable) The value is identical to the
   value of *header:To:asAddresses*.
 * *cc*: EmailAddress[]|null (immutable) The value is identical to the
   value of *header:Cc:asAddresses*.
 * *bcc*: EmailAddress[]|null (immutable) The value is identical to the
   value of *header:Bcc:asAddresses*.
 * *replyTo*: EmailAddress[]|null (immutable) The value is identical to
   the value of *header:Reply-To:asAddresses*.
 * *subject*: String|null (immutable) The value is identical to the
   value of *header:Subject*.
 * *sentAt*: Date (immutable; default: time of creation on server) The
   value is identical to the value of *header:Date:asDate*.Body parts


These properties are derived from the [@!RFC5322] message body and its
[@RFC2045] MIME entities.A *EmailBodyPart* object has the following propert=
ies:


 * *partId*: String Identifies this part uniquely within the Email. This
   is scoped to the *emailId* and has no meaning outside of the JMAP
   Email object representation.
 * *blobId*: String The id references the raw bytes of the contents of
   the part after decoding any *Content-Transfer* encoding (as defined
   in [@!RFC2045]). Note, two parts may be transfer-encoded differently
   but have same the same blob id if their decoded bytes are identical
   and the server is using a secure hash of the data for the blob id.
 * *size*: Number The size, in bytes, of the raw data after content-
   transfer decoding (as refrenced by the *blobId*, i.e. the number of
   bytes in the file the user would download).
 * *headers*: EmailHeader[] (immutable) This is a list of all header
   fields in the part, in the order they appear. The values are in
   *Decoded* form.
 * *headers:asRaw*: EmailHeader[] (immutable) This is a list of all
   header fields in the part, in the order they appear. The values are
   in *Raw Base64* form.
 * *name*: String|null This is the [@!RFC2231] decoded *filename*
   parameter of the *Content-Disposition* header field, or (for
   compatibility with existing systems) if not present then the
   [@!RFC2047] decoded *name* property of the *Content-Type* header
   field. For compatibility with the widest array of existing systems,
   both forms should be set if creating a message.
 * *type*: String The value of the *Content-Type* header field of the
   part, excluding any parameters.
 * *charset*: String|null The value of the charset parameter of the *Conten=
t-
   Type* header field, if present.
 * *disposition*: String|null The value of the *Content-Disposition*
   header field of the part, excluding any parameters, if present.
 * *cid*: String|null The value of the *Content-Id* header field of the
   part, if present. This may be used to reference the content from
   within an html body part using the cid: protocol.
 * *language*: String[]|null The list of language tags, as defined in
   [@!RFC3282], in the *Content-Language* header field of the part,
   if present.
 * *location*: String|null The URI, as defined in [@!RFC2557], in the
   *Content-Location* header field of the part, if present.
 * *width*: Number|null The width (in px) of the image, if the type is
   an image and the server is able to determine this information for
   the image. This MAY not be supported for all or any image types on
   some servers.
 * *height*: Number|null The height (in px) of the image, if the type
   is an image and the server is able to determine this information for
   the image. This MAY not be supported for all or any image types on
   some servers.
 * *subParts*: EmailBodyPart[] (optional) If type is multipart/*, this
   contains the body parts of each child.The following *Email* properties a=
re specified for access to the body
data of the message:


 * *bodyStructure*: EmailBodyPart[] (immutable) This is the full MIME
   structure of the message body, including sub parts but not recursing
   into message/rfc822 parts.


 * *bodyValues*: String[BodyValue] (immutable) This is a map of *partId*
   to an *EmailBodyValue* object. Which parts are included and whether
   the value is truncated is determined by various arguments to
   *Email/get* and *Email/parse*.


An *EmailBodyValue* object has the following properties:


   * *value*: String The value of the body part after decoding *Content-
     Transport* encoding and decoding the *Content-Type* charset.
   * *isTruncated* Boolean This is true if the *value* has been
     truncated.
 * *textBody*: EmailBodyPart[] (immutable) A list of text/plain,
   text/html and image/* parts to display (sequentially) as the message
   body, with a preference for text/plain when alternative versions are
   available.


 * *htmlBody*: EmailBodyPart[] (immutable) A list of text/plain,
   text/html and image/* parts to display (sequentially) as the message
   body, with a preference for text/html when alternative versions are
   available.


 * *attachedEmails*: EmailBodyPart[] (immutable) A list of all parts of
   type message/rfc822. Note, this *does not* recurse, so the parts
   within these are not included. The attached message may be fetched
   using the Email/parse method and the blobId.


 * *attachedFiles*: EmailBodyPart[] (immutable) A list of all parts in
   *bodyStructure*, traversing depth-first, not of type multipart/*, and
   not included in any of the *textBody*, *htmlBody* or *attachedEmails*
   properties. Note, an HTML body part may reference image parts in
   attachedFiles using cid: links to reference the *Content-Id* or by
   referencing the *Content-Location*.


 * *hasAttachment*: Boolean (immutable; server-set) This is true if
   there are one or more parts in the message that a client UI should
   offer as downloadable. A server SHOULD set hasAttachment if either:


   * The *attachedEmails* list contains at least one item.
   * The *attachedFiles* list contains at least one item that does not
     have Content-Disposition: attachment. The server MAY ignore parts
     in this list that are processed automatically in some way, or are
     referenced as embedded images in one of the text/html parts of the
     message. The server MAY set hasAttachment based on implementation-
     defined or site configurable heuristics.


 * *preview*: String (immutable; server-set) Up to 256 characters of the
   beginning of a plain text version of the message body. This is
   intended to be shown as a preview line on a mailbox listing, and the
   server may choose to skip quoted sections or salutations to return a
   more useful preview.MIME structures are arbitrary nested trees of docume=
nts, but the
majority of email clients present a model of an email body (normally
plain text or HTML), with a set of attachments. Interpreting the MIME
structure to form this flat model represents considerable difficulty and
causes inconsistency between clients. Therefore in addition to the
*bodyStructure* property, which gives the full tree, the Email object
contains 4 alternate properties with flat lists of body parts:


 * *textBody*/*htmlBody*: These provide a list of parts that should be
   rendered as the "body" of the message. This is a list rather than a
   single part as messages may have headers and/or footers
   appended/prepended as separate parts as they are transmitted, and
   some clients send text and images intended to be displayed inline in
   the body as multiple parts rather than a single HTML part with
   referenced images.


Because MIME allows for multiple representations of the same data (using
multipart/alternative), there is a textBody property (which prefers a
plain text representation) and an htmlBody property (which prefers an
HTML representation) to accommodate the two most common client
requirements. The same part may appear in both lists where there is no
alternative between the two.


 * *attachedEmails*/*attachedFiles*: These provide a list of parts that
   should be presented as "attachments" to the message. Emails are
   presented in a separate list so their contents may be easily fetched
   via a back-reference with the Email/parse method in the same request,
   if the client wishes to. Some images in attachedFiles may be solely
   there for embedding within an HTML body part; clients may wish to not
   present these as attachments in the user interface if they are
   displaying the HTML with the embedded images directly.The *bodyValues* p=
roperty allows for clients to fetch the value of text
parts directly without having to do a second request for the blob, and
have the server handle decoding the charset into unicode. This data is
in a separate property rather than on the EmailBodyPart object to avoid
duplication of large amounts of data, as the same part may be included
twice if the client fetches more than one of bodyStructure, textBody
and htmlBody.The exact algorithm for decomposing bodyStructure into textBod=
y,
htmlBody, attachedEmails and attachedFiles part lists is not mandated,
as this is a quality-of-service implementation issue and likely to
require workarounds for malformed content discovered over time.However, we =
will define a suggested algorithm for the RFC to help
implementors. TODO.Email/get


Standard */get* method, with the following additional arguments:


 * *bodyProperties*: String[] (optional) A list of properties to fetch
   for each EmailBodyPart returned. If omitted, this defaults to:


[ "partId", "blobId", "size", "name", "type", "charset", "disposition",
cid", "language", "location", "width", "height" ]


 * *fetchTextBodyValues*: Boolean (default: false) If true, the
   *bodyValues* property includes any text/* part in the textBody
   property.


 * *fetchHTMLBodyValues*: Boolean (default: false) If true, the
   *bodyValues* property includes any text/* part in the htmlBody
   property.


 * *fetchAllBodyValues*: Boolean (default: false) If true, the
   *bodyValues* property includes any text/* part in the
   bodyStructure property.


 * *maxBodyValueBytes*: Number (optional) If supplied by the client, the
   value MUST be a positive integer greater than 0. If a value outside
   of this range is given, the server MUST reject the call with an
   invalidArguments error. When given, the *value* property of any
   EmailBodyValue object returned in *bodyValues* MUST be truncated if
   necessary so it does not exceed this number of bytes in size. The
   server MUST ensure the truncation results in valid UTF-8 and does not
   occur mid-codepoint. If the part is of type text/html, the server
   SHOULD NOT truncate inside an HTML tag.If the standard *properties* argu=
ment is omitted or null, the following
default MUST be used instead of "all" properties:


[ "id", "blobId", "threadId", "mailboxIds", "keywords", "size",
"receivedAt", "sender", "from", "to", "cc", "bcc", "replyTo", "subject",
"sentAt", "hasAttachment", "preview", "bodyValues", "textBody",
"htmlBody", "attachedFiles", "attachedEmails" ]The following properties are=
 expected to be fast to fetch in a quality
implementation:


 * id
 * blobId
 * threadId
 * mailboxIds
 * keywords
 * size
 * receivedAt
 * sender
 * from
 * to
 * cc
 * bcc
 * replyTo
 * subject
 * sentAt
 * hasAttachment
 * previewClients SHOULD take care when fetching any other properties, as t=
here
may be significantly longer latency in fetching and returning the data.Exam=
ple


Request:


["Email/get", { "ids": [ "f123u456", "f123u457" ], "properties": [
"threadId", "mailboxIds", "from", "subject", "receivedAt", "htmlBody",
"bodyValues" ], "bodyProperties": [ "partId", "blobId", "size", "type"
], "fetchHTMLBodyValues": true, "maxBodyValueBytes": 256 }, "#1"]and respon=
se:


["Email/get", { "accountId": "abc", "state": "41234123231", "list": [ {
"id": "f123u457", "threadId": "ef1314a", "mailboxIds": { "f123": true },
"from": [{name: "Joe Bloggs", email: "joe@bloggs.com"}], "subject":
"Dinner on Thursday?", "receivedAt": "2013-10-13T14:12:00Z", "htmlBody":
[{ "partId": "1", "blobId": "841623871", "size": 283331, "type":
"text/html" }, { "partId": "2", "blobId": "319437193", "size": 10343,
"type": "text/plain" }], "bodyValues": { "1": { "isTruncated": true,
"value": "<html><body><p>Hello ..." }, "2": { "isTruncated": false,
"value": "-- \nSent by your friendly mailing list ..." } } } ],
notFound: [ "f123u456" ] }, "#1"]

Links:

  1. https://www.iana.org/assignments/imap-keywords/imap-keywords.xhtml

--_----------=_15180702851686500
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="utf-8"

<!DOCTYPE html>
<html>
<head>
<title></title>
<style type=3D"text/css">p.MsoNormal,p.MsoNoSpacing{margin:0}</style>
</head>
<body><div>With an eye to closing off all remaining issues before the next =
IETF meeting in March, I have been looking at the issues raised with the JS=
ON representation of an RFC5322 message. This email presents a new proposal=
 that I think resolves the issues presented. In particular, I aim to addres=
s the following goals:<br></div>
<ul><li>Allow access to the full MIME structure without requiring the clien=
t to parse the full message itself.<br></li><li>Allow access to full header=
 field information if required.<br></li><li>Keep a simpler representation a=
vailable for the common case.<br></li><li>Allow the client to only load the=
 data required.<br></li></ul><div>Comments, suggestions and other feedback =
requested. Cheers!<br></div>
<div><div><br></div>
</div>
<div>------<br></div>
<h1 id=3D"emails">Emails<br></h1><p>The <b>Email</b> object is a representa=
tion of an [@!RFC5322] message, which allows clients to avoid the complexit=
ies of MIME parsing, transport encoding and character encoding.<br></p><h2 =
id=3D"propertiesoftheemailobject">Properties of the Email object<br></h2><p=
>Broadly, a message consists of two parts: a list of header fields, then a =
body. The body is normally a MIME-encoded set of documents in a tree struct=
ure. The JMAP Email object provides a way to access the full structure, or =
to use simplified properties and avoid some complexity if this is sufficien=
t for the client application.<br></p><p>Due to the number of properties inv=
olved, the set of <i>Email</i> properties is specified over the following t=
hree sub-sections.<br></p><h3 id=3D"metadata">Metadata<br></h3><p>These pro=
perties represent metadata about the [@!RFC5322] message, and are not deriv=
ed from parsing the message itself.<br></p><ul><li><p><b>id</b>: <code>Stri=
ng</code> (immutable; server-set)
The id of the Email object. Note, this is the JMAP object id, NOT the [@!RF=
C5322] Message-Id header field value.<br></p></li><li><p><b>blobId</b>: <co=
de>String</code> (immutable; server-set)
The id representing the raw bytes of the [@!RFC5322] message. This may be u=
sed to download the raw original message, or to attach it directly to anoth=
er Email etc.<br></p></li><li><p><b>threadId</b>: <code>String</code> (immu=
table; server-set)
The id of the Thread to which this Email belongs.<br></p></li><li><p><b>mai=
lboxIds</b>: <code>String[Boolean]</code> The set of mailbox ids this email=
 belongs to. An email MUST belong to one or more mailboxes at all times (un=
til it is deleted). The set is represented as an object, with each key bein=
g a <i>Mailbox id</i>. The value for each key in the object MUST be <code>t=
rue</code>.<br></p></li><li><p><b>keywords</b>: <code>String[Boolean]</code=
> (default: <code>{}</code>)
A set of keywords that apply to the email. The set is represented as an obj=
ect, with the keys being the <i>keywords</i>. The value for each key in the=
 object MUST be <code>true</code>.<br></p><p>Keywords are shared with IMAP.=
 The six system keywords from IMAP are treated specially. The following fou=
r keywords have their first character changed from <code>\</code> in IMAP t=
o <code>$</code> in JMAP and have particular semantic meaning:<br></p><ul><=
li><code>$Draft</code>: The email is a draft the user is composing.<br></li=
><li><code>$Seen</code>: The email has been read.<br></li><li><code>$Flagge=
d</code>: The email has been flagged for urgent/special attention.<br></li>=
<li><code>$Answered</code>: The email has been replied to.<br></li></ul><p>=
The IMAP <code>\Recent</code> keyword is not exposed via JMAP. The IMAP <co=
de>\Deleted</code> keyword is also not present: IMAP uses a delete+expunge =
model, which JMAP does not. Any message with the <code>\Deleted</code> keyw=
ord MUST NOT be visible via JMAP.<br></p><p>Users may add arbitrary keyword=
s to an email. For compatibility with IMAP, a keyword is a (case-sensitive)=
 string of 1=E2=80=93255 characters in the ASCII subset %x21=E2=80=93%x7e (=
excludes control chars and space), and MUST NOT include any of these charac=
ters: <code>( ) { ] % * " \</code><br></p><p>The <a href=3D"https://www.ian=
a.org/assignments/imap-keywords/imap-keywords.xhtml">IANA Keyword Registry<=
/a> as established in [@!RFC5788] assigns semantic meaning to some other ke=
ywords in common use. New keywords may be established here in the future. I=
n particular, note:<br></p><ul><li><code>$Forwarded</code>: The email has b=
een forwarded.<br></li><li><code>$Phishing</code>: The email is highly like=
ly to be phishing. Clients SHOULD warn users to take care when viewing this=
 email and disable links and attachments.<br></li><li><code>$Junk</code>: T=
he email is definitely spam. Clients SHOULD set this flag when users report=
 spam to help train automated spam-detection systems.<br></li><li><code>$No=
tJunk</code>: The email is definitely not spam. Clients SHOULD set this fla=
g when users indicate an email is legitimate, to help train automated spam-=
detection systems.<br></li></ul></li><li><p><b>size</b>: <code>Number</code=
> (immutable; server-set)
The size in bytes of the whole email as counted by the server towards the u=
ser's quota.<br></p></li><li><p><b>receivedAt</b>: <code>UTCDate</code> (im=
mutable; default: time of creation on server)
The date the email was received by the message store. This is the <i>intern=
al date</i> in IMAP.<br></p></li></ul><h3 id=3D"headerfields">Header fields=
<br></h3><p>These properties are derived from the [@!RFC5322] message heade=
r fields. Header fields may be fetched in a variety of forms:<br></p><ul><l=
i><p><b>Decoded</b> The header field value with:<br></p><ol><li>White space=
 unfolded (as defined in [@!RFC5322] section 2.2.3)<br></li><li>The termina=
ting CRLF at the end of the value removed<br></li><li>Any SP characters at =
the beginning of the value removed<br></li><li>Any [@!RFC2047] encoded sect=
ions decoded<br></li><li>Any [@!RFC6532] UTF-8 values decoded<br></li></ol>=
<p>If any decodings fail, the parser SHOULD insert a unicode replacement
character (U+FFFD) and attempt to continue as much as possible.<br></p></li=
><li><p><b>Raw Base64</b> The raw bytes of the header field value from the =
first byte following the header field name terminating colon, up to but exc=
luding the header field terminating CRLF, encoded as Base64 ([@!RFC4648]). =
(Note, this is required as the value may not be valid UTF-8 if 8-bit values=
 are present.)<br></p></li><li><p><b>Addresses</b> The header is parsed as =
an <code>address-list</code> value, as specified in [@!RFC5322] section 3.4=
, into the <code>EmailAddress[]</code> type. The <b>EmailAddress</b> object=
 has the following properties:<br></p><ul><li><b>name</b>: <code>String|nul=
l</code> The <i>display name</i> of the [@!RFC5322] <i>mailbox</i> or <i>gr=
oup</i>, or <code>null</code> if none.<br></li><li><b>email</b>: <code>Stri=
ng|null</code> The <i>addr-spec</i> of the [@!RFC5322] <i>mailbox</i>, or <=
code>null</code> if a <i>group</i>.<br></li></ul><p>Parsing SHOULD be best-=
effort in the face of invalid structure to accommodate
invalid messages and semi-complete drafts. EmailAddress objects MAY have an=
 <i>email</i> property that does not conform to the <i>addr-spec</i> form (=
for example, may not contain an @ symbol).<br></p></li><li><p><b>Date</b> T=
he header is parsed as a <code>date-time</code> value, as specified in [@!R=
FC5322] section 3.3, into the <code>Date</code> type.<br></p></li></ul><p>T=
he following <b>Email</b> properties are specified for complete access to t=
he header data of the message. Where <code>{header-field-name}</code> is sp=
ecified within a property name, this means any series of one or more printa=
ble US-ASCII characters (i.e. characters that have values between 33 and 12=
6, inclusive), except colon:<br></p><ul><li><b>headers</b>: <code>EmailHead=
er[]</code> (immutable)
This is a list of all [@!RFC5322] header fields, in the same order they app=
ear in the message. The values are in <i>Decoded</i> form.<br></li><li><b>h=
eaders:asRaw</b>: <code>EmailHeader[]</code> (immutable)
This is a list of all [@!RFC5322] header fields, in the same order they app=
ear in the message. The values are in <i>Raw Base64</i> form.<br></li><li><=
b>header:{header-field-name}</b>: <code>String|null</code> (immutable)
The value of the <i>last</i> header field in the message with the given hea=
der field name (matched case-insensitively), or <code>null</code> if none. =
The value is in <i>Decoded</i> form.<br></li><li><b>header:{header-field-na=
me}:asRaw</b>: <code>String|null</code> (immutable)
The value of the <i>last</i> header field in the message with the given hea=
der field name (matched case-insensitively), or <code>null</code> if none. =
The value is in <i>Raw Base64</i> form.<br></li><li><b>header:{header-field=
-name}:asAddresses</b>: <code>EmailAddress[]|null</code> (immutable)
The value of the <i>last</i> header field in the message with the given hea=
der field name (matched case-insensitively), or <code>null</code> if none. =
The value is in <i>Addresses</i> form.<br></li><li><b>header:{header-field-=
name}:asDate</b>: <code>Date|null</code> (immutable)
The value of the <i>last</i> header field in the message with the given hea=
der field name (matched case-insensitively), or <code>null</code> if none. =
The value is in <i>Date</i> form.<br></li></ul><p>An <b>EmailHeader</b> obj=
ect has the following properties:<br></p><ul><li><b>name</b>: <code>String<=
/code> The header <i>field name</i> as defined in RFC5322, with the same ca=
pitalization that it has in the message.<br></li><li><b>value</b>: <code>St=
ring</code> The header <i>field value</i> as defined in RFC5322, in either =
<i>Decoded</i> or <i>Raw Base64</i> form as determined by the property bein=
g fetched.<br></li></ul><p>The following convenience properties are also sp=
ecified for the <b>Email</b> object:<br></p><ul><li><b>sender</b>: <code>Em=
ailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:Sender:asAddresses</i>.<br=
></li><li><b>from</b>: <code>EmailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:From:asAddresses</i>.<br><=
/li><li><b>to</b>: <code>EmailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:To:asAddresses</i>.<br></l=
i><li><b>cc</b>: <code>EmailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:Cc:asAddresses</i>.<br></l=
i><li><b>bcc</b>: <code>EmailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:Bcc:asAddresses</i>.<br></=
li><li><b>replyTo</b>: <code>EmailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:Reply-To:asAddresses</i>.<=
br></li><li><b>subject</b>: <code>String|null</code> (immutable)
The value is identical to the value of <i>header:Subject</i>.<br></li><li><=
b>sentAt</b>: <code>Date</code> (immutable; default: time of creation on se=
rver)
The value is identical to the value of <i>header:Date:asDate</i>.<br></li><=
/ul><h3 id=3D"bodyparts">Body parts<br></h3><p>These properties are derived=
 from the [@!RFC5322] message body and its [@RFC2045] MIME entities.<br></p=
><p>A <b>EmailBodyPart</b> object has the following properties:<br></p><ul>=
<li><b>partId</b>: <code>String</code> Identifies this part uniquely within=
 the Email. This is scoped to the <i>emailId</i> and has no meaning outside=
 of the JMAP Email object representation.<br></li><li><b>blobId</b>: <code>=
String</code> The id references the raw bytes of the contents of the part a=
fter decoding any <i>Content-Transfer</i> encoding (as defined in [@!RFC204=
5]). Note, two parts may be transfer-encoded differently but have same the =
same blob id if their decoded bytes are identical and the server is using a=
 secure hash of the data for the blob id.<br></li><li><b>size</b>: <code>Nu=
mber</code> The size, in bytes, of the raw data after content-transfer deco=
ding (as refrenced by the <i>blobId</i>, i.e. the number of bytes in the fi=
le the user would download).<br></li><li><b>headers</b>: <code>EmailHeader[=
]</code> (immutable)
This is a list of all header fields in the part, in the order they appear. =
The values are in <i>Decoded</i> form.<br></li><li><b>headers:asRaw</b>: <c=
ode>EmailHeader[]</code> (immutable)
This is a list of all header fields in the part, in the order they appear. =
The values are in <i>Raw Base64</i> form.<br></li><li><b>name</b>: <code>St=
ring|null</code> This is the [@!RFC2231] decoded <i>filename</i> parameter =
of the <i>Content-Disposition</i> header field, or (for compatibility with =
existing systems) if not present then the [@!RFC2047] decoded <i>name</i> p=
roperty of the <i>Content-Type</i> header field. For compatibility with the=
 widest array of existing systems, both forms should be set if creating a m=
essage.<br></li><li><b>type</b>: <code>String</code> The value of the <i>Co=
ntent-Type</i> header field of the part, excluding any parameters.<br></li>=
<li><b>charset</b>: <code>String|null</code> The value of the charset param=
eter of the <i>Content-Type</i> header field, if present.<br></li><li><b>di=
sposition</b>: <code>String|null</code> The value of the <i>Content-Disposi=
tion</i> header field of the part, excluding any parameters, if present.<br=
></li><li><b>cid</b>: <code>String|null</code> The value of the <i>Content-=
Id</i> header field of the part, if present. This may be used to reference =
the content from within an html body part using the <code>cid:</code> proto=
col.<br></li><li><b>language</b>: <code>String[]|null</code> The list of la=
nguage tags, as defined in [@!RFC3282], in the <i>Content-Language</i> head=
er field of the part, if present.<br></li><li><b>location</b>: <code>String=
|null</code> The URI, as defined in [@!RFC2557], in the <i>Content-Location=
</i> header field of the part, if present.<br></li><li><b>width</b>: <code>=
Number|null</code> The width (in px) of the image, if the type is an image =
and the server is able to determine this information for the image. This MA=
Y not be supported for all or any image types on some servers.<br></li><li>=
<b>height</b>: <code>Number|null</code> The height (in px) of the image, if=
 the type is an image and the server is able to determine this information =
for the image. This MAY not be supported for all or any image types on some=
 servers.<br></li><li><b>subParts</b>: <code>EmailBodyPart[]</code> (option=
al)
If type is <code>multipart/*</code>, this contains the body parts of each c=
hild.<br></li></ul><p>The following <b>Email</b> properties are specified f=
or access to the body data of the message:<br></p><ul><li><p><b>bodyStructu=
re</b>: <code>EmailBodyPart[]</code> (immutable)
This is the full MIME structure of the message body, including sub parts bu=
t not recursing into <code>message/rfc822</code> parts.<br></p></li><li><p>=
<b>bodyValues</b>: <code>String[BodyValue]</code> (immutable)
This is a map of <i>partId</i> to an <b>EmailBodyValue</b> object. Which pa=
rts are included and whether the value is truncated is determined by variou=
s arguments to <i>Email/get</i> and <i>Email/parse</i>.<br></p><p>An <b>Ema=
ilBodyValue</b> object has the following properties:<br></p><ul><li><b>valu=
e</b>: <code>String</code> The value of the body part after decoding <i>Con=
tent-Transport</i> encoding and
decoding the <i>Content-Type</i> charset.<br></li><li><b>isTruncated</b> <c=
ode>Boolean</code> This is <code>true</code> if the <i>value</i> has been t=
runcated.<br></li></ul></li><li><p><b>textBody</b>: <code>EmailBodyPart[]</=
code> (immutable)
A list of <code>text/plain</code>, <code>text/html</code> and <code>image/*=
</code> parts to display (sequentially) as the message body, with a prefere=
nce for <code>text/plain</code> when alternative versions are available.<br=
></p></li><li><p><b>htmlBody</b>: <code>EmailBodyPart[]</code> (immutable)
A list of <code>text/plain</code>, <code>text/html</code> and <code>image/*=
</code> parts to display (sequentially) as the message body, with a prefere=
nce for <code>text/html</code> when alternative versions are available.<br>=
</p></li><li><p><b>attachedEmails</b>: <code>EmailBodyPart[]</code> (immuta=
ble)
A list of all parts of type <code>message/rfc822</code>. Note, this <b>does=
 not</b> recurse, so the parts within these are not included. The attached =
message may be fetched using the Email/parse method and the blobId.<br></p>=
</li><li><p><b>attachedFiles</b>: <code>EmailBodyPart[]</code> (immutable)
A list of all parts in <i>bodyStructure</i>, traversing depth-first, not of=
 type <code>multipart/*</code>, and not included in any of the <i>textBody<=
/i>, <i>htmlBody</i> or <i>attachedEmails</i> properties. Note, an HTML bod=
y part may reference image parts in attachedFiles using <code>cid:</code> l=
inks to reference the <i>Content-Id</i> or by referencing the <i>Content-Lo=
cation</i>.<br></p></li><li><p><b>hasAttachment</b>: <code>Boolean</code> (=
immutable; server-set)
This is <code>true</code> if there are one or more parts in the message tha=
t a client UI should offer as downloadable. A server SHOULD set hasAttachme=
nt if either:<br></p><ul><li>The <i>attachedEmails</i> list contains at lea=
st one item.<br></li><li>The <i>attachedFiles</i> list contains at least on=
e item that does not have <code>Content-Disposition: attachment</code>. The=
 server MAY ignore parts in this list that are processed automatically in s=
ome way, or are referenced as embedded images in one of the <code>text/html=
</code> parts of the message.<br></li></ul><p>The server MAY set hasAttachm=
ent based on implementation-defined or site configurable heuristics.<br></p=
></li><li><p><b>preview</b>: <code>String</code> (immutable; server-set)
Up to 256 characters of the beginning of a plain text version of the messag=
e body. This is intended to be shown as a preview line on a mailbox listing=
, and the server may choose to skip quoted sections or salutations to retur=
n a more useful preview.<br></p></li></ul><p>MIME structures are arbitrary =
nested trees of documents, but the majority of email clients present a mode=
l of an email body (normally plain text or HTML), with a set of attachments=
. Interpreting the MIME structure to form this flat model represents consid=
erable difficulty and causes inconsistency between clients. Therefore in ad=
dition to the <i>bodyStructure</i> property, which gives the full tree, the=
 Email object contains 4 alternate properties with flat lists of body parts=
:<br></p><ul><li><p><i>textBody</i>/<i>htmlBody</i>: These provide a list o=
f parts that should be
rendered as the "body" of the message. This is a list rather than a single =
part as messages may have headers and/or footers appended/prepended as sepa=
rate parts as they are transmitted, and some clients send text and images i=
ntended to be displayed inline in the body as multiple parts rather than a =
single HTML part with referenced images.<br></p><p>Because MIME allows for =
multiple representations of the same data (using <code>multipart/alternativ=
e</code>), there is a textBody property (which prefers a plain text represe=
ntation) and an htmlBody property (which prefers an HTML representation) to=
 accommodate the two most common client requirements. The same part may app=
ear in both lists where there is no alternative between the two.<br></p></l=
i><li><p><i>attachedEmails</i>/<i>attachedFiles</i>: These provide a list o=
f parts that should
be presented as "attachments" to the message. Emails are presented in a sep=
arate list so their contents may be easily fetched via a back-reference wit=
h the <code>Email/parse</code> method in the same request, if the client wi=
shes to. Some images in attachedFiles may be solely there for embedding wit=
hin an HTML body part; clients may wish to not present these as attachments=
 in the user interface if they are displaying the HTML with the embedded im=
ages directly.<br></p></li></ul><p>The <i>bodyValues</i> property allows fo=
r clients to fetch the value of text parts directly without having to do a =
second request for the blob, and have the server handle decoding the charse=
t into unicode. This data is in a separate property rather than on the Emai=
lBodyPart object to avoid duplication of large amounts of data, as the same=
 part may be included twice if the client fetches more than one of bodyStru=
cture, textBody and htmlBody.<br></p><p>The exact algorithm for decomposing=
 bodyStructure into textBody, htmlBody, attachedEmails and attachedFiles pa=
rt lists is not mandated, as this is a quality-of-service implementation is=
sue and likely to require workarounds for malformed content discovered over=
 time.<br></p><p>However, we will define a suggested algorithm for the RFC =
to help implementors. TODO.<br></p><h2 id=3D"emailget">Email/get<br></h2><p=
>Standard <i>/get</i> method, with the following additional arguments:<br><=
/p><ul><li><p><b>bodyProperties</b>: <code>String[]</code> (optional)
A list of properties to fetch for each EmailBodyPart returned. If omitted, =
this defaults to:<br></p><p>[ "partId", "blobId", "size", "name", "type", "=
charset", "disposition", cid", "language", "location", "width", "height" ]<=
br></p></li><li><p><b>fetchTextBodyValues</b>: <code>Boolean</code> (defaul=
t: <code>false</code>)
If <code>true</code>, the <i>bodyValues</i> property includes any <code>tex=
t/*</code> part in the <code>textBody</code> property.<br></p></li><li><p><=
b>fetchHTMLBodyValues</b>: <code>Boolean</code> (default: <code>false</code=
>)
If <code>true</code>, the <i>bodyValues</i> property includes any <code>tex=
t/*</code> part in the <code>htmlBody</code> property.<br></p></li><li><p><=
b>fetchAllBodyValues</b>: <code>Boolean</code> (default: <code>false</code>)
If <code>true</code>, the <i>bodyValues</i> property includes any <code>tex=
t/*</code> part in the <code>bodyStructure</code> property.<br></p></li><li=
><p><b>maxBodyValueBytes</b>: <code>Number</code> (optional)
If supplied by the client, the value MUST be a positive integer greater tha=
n 0. If a value outside of this range is given, the server MUST reject the =
call with an <code>invalidArguments</code> error. When given, the <i>value<=
/i> property of any EmailBodyValue object returned in <i>bodyValues</i> MUS=
T be truncated if necessary so it does not exceed this number of bytes in s=
ize. The server MUST ensure the truncation results in valid UTF-8 and does =
not occur mid-codepoint. If the part is of type <code>text/html</code>, the=
 server SHOULD NOT truncate inside an HTML tag.<br></p></li></ul><p>If the =
standard <i>properties</i> argument is omitted or <code>null</code>, the fo=
llowing default MUST be used instead of "all" properties:<br></p><pre><code=
>[ "id", "blobId", "threadId", "mailboxIds", "keywords", "size", "receivedA=
t", "sender", "from", "to", "cc", "bcc", "replyTo", "subject", "sentAt", "h=
asAttachment", "preview", "bodyValues", "textBody", "htmlBody", "attachedFi=
les", "attachedEmails" ]
</code><br></pre><p>The following properties are expected to be fast to fet=
ch in a quality implementation:<br></p><ul><li>id<br></li><li>blobId<br></l=
i><li>threadId<br></li><li>mailboxIds<br></li><li>keywords<br></li><li>size=
<br></li><li>receivedAt<br></li><li>sender<br></li><li>from<br></li><li>to<=
br></li><li>cc<br></li><li>bcc<br></li><li>replyTo<br></li><li>subject<br><=
/li><li>sentAt<br></li><li>hasAttachment<br></li><li>preview<br></li></ul><=
p>Clients SHOULD take care when fetching any other properties, as there may=
 be significantly longer latency in fetching and returning the data.<br></p=
><h3 id=3D"example">Example<br></h3><p>Request:<br></p><pre><code>["Email/g=
et", {
  "ids": [ "f123u456", "f123u457" ],
  "properties": [ "threadId", "mailboxIds", "from", "subject", "receivedAt"=
, "htmlBody", "bodyValues" ],
  "bodyProperties": [ "partId", "blobId", "size", "type" ],
  "fetchHTMLBodyValues": true,
  "maxBodyValueBytes": 256
}, "#1"]
</code><br></pre><p>and response:<br></p><pre><code>["Email/get", {
  "accountId": "abc",
  "state": "41234123231",
  "list": [
    {
      "id": "f123u457",
      "threadId": "ef1314a",
      "mailboxIds": { "f123": true },
      "from": [{name: "Joe Bloggs", email: "joe@bloggs.com"}],
      "subject": "Dinner on Thursday?",
      "receivedAt": "2013-10-13T14:12:00Z",
      "htmlBody": [{
        "partId": "1",
        "blobId": "841623871",
        "size": 283331,
        "type": "text/html"
      }, {
        "partId": "2",
        "blobId": "319437193",
        "size": 10343,
        "type": "text/plain"
      }],
      "bodyValues": {
        "1": {
          "isTruncated": true,
          "value": "&lt;html&gt;&lt;body&gt;&lt;p&gt;Hello ..."
        },
        "2": {
          "isTruncated": false,
          "value": "-- \nSent by your friendly mailing list ..."
        }
      }
    }
  ],
  notFound: [ "f123u456" ]
}, "#1"]
</code><br></pre><div><br></div>
</body>
</html>

--_----------=_15180702851686500--



From nobody Fri Feb  9 03:41:58 2018
Return-Path: <alexey.melnikov@isode.com>
X-Original-To: jmap@ietfa.amsl.com
Delivered-To: jmap@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 5D876126E01 for <jmap@ietfa.amsl.com>; Fri,  9 Feb 2018 03:41:56 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.01
X-Spam-Level: 
X-Spam-Status: No, score=-2.01 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, SPF_PASS=-0.001, T_RP_MATCHES_RCVD=-0.01] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (1024-bit key) header.d=isode.com
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ewXu7LhQe5wW for <jmap@ietfa.amsl.com>; Fri,  9 Feb 2018 03:41:54 -0800 (PST)
Received: from waldorf.isode.com (waldorf.isode.com [62.232.206.188]) by ietfa.amsl.com (Postfix) with ESMTP id B2689126BF0 for <jmap@ietf.org>; Fri,  9 Feb 2018 03:41:54 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1518176513; d=isode.com; s=june2016; i=@isode.com; bh=utNpzEjFq+qNmJXPFmUPNyCvKD+ipYMsrmX62GujoYs=; h=From:Sender:Reply-To:Subject:Date:Message-ID:To:Cc:MIME-Version: In-Reply-To:References:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description; b=UYBQzih+7SHwqlpnP2Q37JlRaN16PmMYHKg0LymeA66hGIGNef7OhL0DhcOXG253vF5KA5 fc5tNsgtOjn9iiiXarkr5v1ZZyZk7gIWBlzXf8q7gdsXxX5vwKQa+jjz00jCO1xqhqcJVi LP/gXDG3kQXQtN/f6jUxo0K+hX+GZGU=;
Received: from [172.20.1.215] (dhcp-215.isode.net [172.20.1.215])  by waldorf.isode.com (submission channel) via TCP with ESMTPSA  id <Wn2JAQBJjUEk@waldorf.isode.com>; Fri, 9 Feb 2018 11:41:53 +0000
From: Alexey Melnikov <alexey.melnikov@isode.com>
To: Neil Jenkins <neilj@fastmailteam.com>, IETF JMAP Mailing List <jmap@ietf.org>
References: <1518070284.168650.1263633200.05C7397A@webmail.messagingengine.com>
Message-ID: <0bb7d2f4-bcba-86ea-12f7-43a59a2f951e@isode.com>
Date: Fri, 9 Feb 2018 11:41:27 +0000
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.5.2
In-Reply-To: <1518070284.168650.1263633200.05C7397A@webmail.messagingengine.com>
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="------------DEF1A268E23D1481DA1CD017"
Content-Language: en-GB
Archived-At: <https://mailarchive.ietf.org/arch/msg/jmap/pSvaTKnGyMjohW9WtV8pfh4BzgA>
Subject: Re: [Jmap] New JSON message representation
X-BeenThere: jmap@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: JSON Message Access Protocol <jmap.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/jmap>, <mailto:jmap-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/jmap/>
List-Post: <mailto:jmap@ietf.org>
List-Help: <mailto:jmap-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/jmap>, <mailto:jmap-request@ietf.org?subject=subscribe>
X-List-Received-Date: Fri, 09 Feb 2018 11:41:56 -0000

--------------DEF1A268E23D1481DA1CD017
Content-Type: text/plain; charset=utf-8; format=flowed
Content-transfer-encoding: quoted-printable

Hi Neal,

I haven't digested your whole email yet, but a very quick comment about=20
keywords:

On 08/02/2018 06:11, Neil Jenkins wrote:

>  *
>
>     *keywords*: |String[Boolean]| (default: |{}|) A set of keywords
>     that apply to the email. The set is represented as an object, with
>     the keys being the /keywords/. The value for each key in the
>     object MUST be |true|.
>
>     Keywords are shared with IMAP. The six system keywords from IMAP
>     are treated specially. The following four keywords have their
>     first character changed from |\| in IMAP to |$| in JMAP and have
>     particular semantic meaning:
>
>       o |$Draft|: The email is a draft the user is composing.
>       o |$Seen|: The email has been read.
>       o |$Flagged|: The email has been flagged for urgent/special
>         attention.
>       o |$Answered|: The email has been replied to.
>
>     The IMAP |\Recent| keyword is not exposed via JMAP. The IMAP
>     |\Deleted| keyword is also not present: IMAP uses a delete+expunge
>     model, which JMAP does not. Any message with the |\Deleted|
>     keyword MUST NOT be visible via JMAP.
>
>     Users may add arbitrary keywords to an email. For compatibility
>     with IMAP, a keyword is a (case-sensitive)
>
IMAP keywords are case insensitive. So $MDNSent and $mdnsent are the same.
>
>  *
>
>     string of 1=E2=80=93255 characters in the ASCII subset %x21=E2=80=93%x=
7e (excludes
>     control chars and space), and MUST NOT include any of these
>     characters: |( ) { ] % * " \|
>
|Probably not including } and [ as well. But I need to double check.

Best Regards,
Alexey

|

--------------DEF1A268E23D1481DA1CD017
Content-Type: text/html; charset=utf-8
Content-transfer-encoding: quoted-printable

<html>
  <head>
    <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8"=
>
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <p>Hi Neal,</p>
    <p>I haven't digested your whole email yet, but a very quick comment
      about keywords:<br>
    </p>
    <p>On 08/02/2018 06:11, Neil Jenkins wrote:</p>
    <blockquote type=3D"cite"
cite=3D"mid:1518070284.168650.1263633200.05C7397A@webmail.messagingengine.co=
m">
      <ul>
        <li>
          <p><b>keywords</b>: <code>String[Boolean]</code> (default: <code>{=
}</code>)
            A set of keywords that apply to the email. The set is
            represented as an object, with the keys being the <i>keywords</i=
>.
            The value for each key in the object MUST be <code>true</code>.<=
br>
          </p>
          <p>Keywords are shared with IMAP. The six system keywords from
            IMAP are treated specially. The following four keywords have
            their first character changed from <code>\</code> in IMAP
            to <code>$</code> in JMAP and have particular semantic
            meaning:<br>
          </p>
          <ul>
            <li><code>$Draft</code>: The email is a draft the user is
              composing.<br>
            </li>
            <li><code>$Seen</code>: The email has been read.<br>
            </li>
            <li><code>$Flagged</code>: The email has been flagged for
              urgent/special attention.<br>
            </li>
            <li><code>$Answered</code>: The email has been replied to.<br>
            </li>
          </ul>
          <p>The IMAP <code>\Recent</code> keyword is not exposed via
            JMAP. The IMAP <code>\Deleted</code> keyword is also not
            present: IMAP uses a delete+expunge model, which JMAP does
            not. Any message with the <code>\Deleted</code> keyword
            MUST NOT be visible via JMAP.<br>
          </p>
          <p>Users may add arbitrary keywords to an email. For
            compatibility with IMAP, a keyword is a (case-sensitive) </p>
        </li>
      </ul>
    </blockquote>
    IMAP keywords are case insensitive. So $MDNSent and $mdnsent are the
    same.<br>
    <blockquote type=3D"cite"
cite=3D"mid:1518070284.168650.1263633200.05C7397A@webmail.messagingengine.co=
m">
      <ul>
        <li>
          <p>string of 1=E2=80=93255 characters in the ASCII subset %x21=E2=
=80=93%x7e
            (excludes control chars and space), and MUST NOT include any
            of these characters: <code>( ) { ] % * " \</code><br>
          </p>
        </li>
      </ul>
    </blockquote>
    <code>Probably not including } and [ as well. But I need to double
      check.<br>
      <br>
      Best Regards,<br>
      Alexey<br>
      <br>
    </code>
  </body>
</html>

--------------DEF1A268E23D1481DA1CD017--


From nobody Fri Feb  9 09:48:08 2018
Return-Path: <barryleiba.mailing.lists@gmail.com>
X-Original-To: jmap@ietfa.amsl.com
Delivered-To: jmap@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 879B412D7E7 for <jmap@ietfa.amsl.com>; Fri,  9 Feb 2018 09:48:07 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.7
X-Spam-Level: 
X-Spam-Status: No, score=-1.7 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.199, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001] autolearn=no autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id bsYPLajZCD8i for <jmap@ietfa.amsl.com>; Fri,  9 Feb 2018 09:48:06 -0800 (PST)
Received: from mail-qt0-x232.google.com (mail-qt0-x232.google.com [IPv6:2607:f8b0:400d:c0d::232]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 2561A1201F8 for <jmap@ietf.org>; Fri,  9 Feb 2018 09:48:06 -0800 (PST)
Received: by mail-qt0-x232.google.com with SMTP id g14so11552317qti.2 for <jmap@ietf.org>; Fri, 09 Feb 2018 09:48:06 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;  h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc:content-transfer-encoding; bh=N4huwTjWHxfh8bgbBfRsm1kaV0JlYjD86/lHp7QAzXI=; b=bHFdAWj26bFpGUpe9XYs8jzU2PuK01b8cr2vEv/uQId+aDLMeryK+IOsO5UMKVdXpy CFEk6WELTrc3Q/IKMbNfqhAtI3SzRft3nFC5fwDGFPkzZ/eSlKmRIAzQM9iLkZMlZlcV a9YGtmWVg/JMSip2vGgnb6H9JObpYEyzcbDy6TqcdLrcOS7Cit/TidVDbHij2K22gVtk FVlXL72QLIzZNPNIH320GgLKbGajBx58MawEf1Fr5OjRj4JnVFip08oQygCVgSeBI/3S aEZX9d488l7FAxvFSoAjH+PMuDUdWQU1hjaBMk4CPkAR03xzDCZpDeNt4GJw04iRdaNE qY0g==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:sender:in-reply-to:references:from :date:message-id:subject:to:cc:content-transfer-encoding; bh=N4huwTjWHxfh8bgbBfRsm1kaV0JlYjD86/lHp7QAzXI=; b=rnnaxHpt/GR4/BJnYVheG2iCwVg2aLh0Gd9C89BUKgZkXR6tErcNMBnysmepqi8CtH ddW44zGDLvUpOo9y/USwahZsZ/RGYG5dNZbGBOwBgqvG0FQFLsB3uczXZXeX0uzzHlpz zfTrET7UahuvmEZ9X3qfBwoRtnMVIed5G6O3rsh3dGs0TnhNR5c0KWCv1zuGDY/RylJi g5/fwFlsG8xX0am22RxJ+WTAWcVToJap1ancFSVQiww6hHe4fDpkoS+Ipm5TKGwOHnKF 4lcIe0i/20zhk2tKPA0hCVoAq3mNGdXS19wx5nh8wTF/YUEFJvskvhTn0XoA6mjF2IpB Bsyw==
X-Gm-Message-State: APf1xPDgQIL1ivHYMJctA8RKV9wN13cKaNQSwq0rw9qNZRbB41KnWI4+ sc8+8MTbM8P2uSPwU4FnoCraybDEXDRXBJ81uvA=
X-Google-Smtp-Source: AH8x227etsSidePRjKWB6S9wI5lZ27NAiefH3YITYskNFK4GHb6f0XqNk3K6Xyu/kNclKVLUyb3WO5/fjR5AGsgFDrY=
X-Received: by 10.200.56.162 with SMTP id f31mr864773qtc.9.1518198485316; Fri, 09 Feb 2018 09:48:05 -0800 (PST)
MIME-Version: 1.0
Sender: barryleiba.mailing.lists@gmail.com
Received: by 10.200.35.199 with HTTP; Fri, 9 Feb 2018 09:48:04 -0800 (PST)
In-Reply-To: <0bb7d2f4-bcba-86ea-12f7-43a59a2f951e@isode.com>
References: <1518070284.168650.1263633200.05C7397A@webmail.messagingengine.com> <0bb7d2f4-bcba-86ea-12f7-43a59a2f951e@isode.com>
From: Barry Leiba <barryleiba@computer.org>
Date: Fri, 9 Feb 2018 12:48:04 -0500
X-Google-Sender-Auth: b_8EvIa0dRz32ASjQdd3OSjpdZ0
Message-ID: <CAC4RtVDCdHYuhg4beQ8jf4y1jHY9qaRfh1SYU8n6StiacvYLEw@mail.gmail.com>
To: Alexey Melnikov <alexey.melnikov@isode.com>
Cc: Neil Jenkins <neilj@fastmailteam.com>, IETF JMAP Mailing List <jmap@ietf.org>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Archived-At: <https://mailarchive.ietf.org/arch/msg/jmap/UkvOqjMxBtwYqAXl6Z1SFKPIHtE>
Subject: Re: [Jmap] New JSON message representation
X-BeenThere: jmap@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: JSON Message Access Protocol <jmap.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/jmap>, <mailto:jmap-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/jmap/>
List-Post: <mailto:jmap@ietf.org>
List-Help: <mailto:jmap-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/jmap>, <mailto:jmap-request@ietf.org?subject=subscribe>
X-List-Received-Date: Fri, 09 Feb 2018 17:48:07 -0000

>> string of 1=E2=80=93255 characters in the ASCII subset %x21=E2=80=93%x7e=
 (excludes control
>> chars and space), and MUST NOT include any of these characters:
>>   ( ) { ] % * " \
>
> Probably not including } and [ as well. But I need to double check.

According to the IMAP grammar, that's the complete list: } and [ are
not forbidden in IMAP.

b


From nobody Fri Feb  9 11:08:34 2018
Return-Path: <chris.newman@oracle.com>
X-Original-To: jmap@ietfa.amsl.com
Delivered-To: jmap@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id D36BF12D7EC for <jmap@ietfa.amsl.com>; Fri,  9 Feb 2018 11:08:32 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.031
X-Spam-Level: 
X-Spam-Status: No, score=-2.031 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_PASS=-0.001, T_RP_MATCHES_RCVD=-0.01] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=oracle.com
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 4V9F4rKPQmT9 for <jmap@ietfa.amsl.com>; Fri,  9 Feb 2018 11:08:30 -0800 (PST)
Received: from aserp2120.oracle.com (aserp2120.oracle.com [141.146.126.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id B4EFD12D7E9 for <jmap@ietf.org>; Fri,  9 Feb 2018 11:08:30 -0800 (PST)
Received: from pps.filterd (aserp2120.oracle.com [127.0.0.1]) by aserp2120.oracle.com (8.16.0.22/8.16.0.22) with SMTP id w19J7JdJ110376; Fri, 9 Feb 2018 19:08:26 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=corp-2017-10-26; bh=vPeTqmSBzsL7kT2cgxb/Le8mVGaGXnm4KPh0VJCi0zg=; b=a6scWEw28LL3Z2/FKGr8npHpOo25fEGBzIXHkV5NB31E6StwdZkjQp3sKAHAdk5w8E48 9tQvWuS1FqiC2i3db9V2sTmtrY2FoYUYp0e0fwHKMhPxdB4c4WDKxm9Ww8T5fr5ULx+o OdEF2goLwqilF1D6fA6mw0qIUsSYjKgyTL2PPxTxCEKBReXnPzRqy8Sk2wTBMneAZkM6 KeHgcEni07DL9crYG0m+quevTCY2yGnEv26ATEPNX64a3oiuMIlm3WroP4/SuXpVwb6P zYeiwFhWGhlp+Cd9lj1yqGBl0sqnWR40/JvYyyIZ/p2BiYkQyGytUaLQ120E/UFPIaZK 2Q== 
Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp2120.oracle.com with ESMTP id 2g1gyy05en-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 09 Feb 2018 19:08:26 +0000
Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.14.4/8.14.4) with ESMTP id w19J8Pt2007153 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 9 Feb 2018 19:08:25 GMT
Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id w19J8Ots006869; Fri, 9 Feb 2018 19:08:24 GMT
Received: from [10.145.239.148] (/10.145.239.148) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 09 Feb 2018 11:08:24 -0800
From: "Chris Newman" <chris.newman@oracle.com>
To: "Neil Jenkins" <neilj@fastmailteam.com>
Cc: "IETF JMAP Mailing List" <jmap@ietf.org>
Date: Fri, 09 Feb 2018 11:08:22 -0800
X-Mailer: MailMate (1.10r5443)
Message-ID: <500E0B79-200E-4DFA-939A-C3419559743E@oracle.com>
In-Reply-To: <1518070284.168650.1263633200.05C7397A@webmail.messagingengine.com>
References: <1518070284.168650.1263633200.05C7397A@webmail.messagingengine.com>
MIME-Version: 1.0
Content-Type: text/plain; format=flowed
X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8800 signatures=668666
X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1711220000 definitions=main-1802090242
Archived-At: <https://mailarchive.ietf.org/arch/msg/jmap/wzXMCAx3sYQg7XmulSuqxQ7bBuo>
Subject: Re: [Jmap] New JSON message representation
X-BeenThere: jmap@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: JSON Message Access Protocol <jmap.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/jmap>, <mailto:jmap-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/jmap/>
List-Post: <mailto:jmap@ietf.org>
List-Help: <mailto:jmap-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/jmap>, <mailto:jmap-request@ietf.org?subject=subscribe>
X-List-Received-Date: Fri, 09 Feb 2018 19:08:33 -0000

Overall I'm supportive of this approach. Detailed comments:

I concur with Alexey's comment about keywords being case-insensitive.

On 7 Feb 2018, at 22:11, Neil Jenkins wrote:
>  * *size*: Number (immutable; server-set) The size in bytes of the 
> whole
>    email as counted by the server towards the user's quota.

The problem with a quota-based size measurement is "0" is a reasonable 
answer for single-copy message stores that allow multiple Email objects 
that refer to the same message (particularly if a reference to the 
message in a trash folder is not the only reference). Also, some number 
substantially less than what the user might want to see in a UI is 
possible in a single-attachment-copy mail store where each attachment is 
charged only once against the user's quota.

One option is to define *size* as the RFC822 size of the message (same 
definition as IMAP RFC 3501). Another option is that *size* is a number 
that would be appropriate to display to a user representing the size of 
the message content and attachments. This allows use of RFC 5322 size, 
RFC 6532 size or a binary MIME variation of either.

>  * *receivedAt*: UTCDate (immutable; default: time of creation on
>    server) The date the email was received by the message store. This 
> is
>    the *internal date* in IMAP.Header fields

I note the IMAP APPEND command allows this to be client-specified. This 
is very useful in practice when migrating mail between mail stores. The 
date the user really wants is when the mail first entered a mailstore 
owned by the user (or operated on behalf of the user). The date when the 
mail first entered this particular mailstore is less useful to the end 
user.

> These properties are derived from the [@!RFC5322] message header 
> fields.

It's also fine to allow [@!RFC6532] message header fields, I believe.

> Header fields may be fetched in a variety of forms:
>
>
>  * *Decoded* The header field value with:
>
>
>    1. White space unfolded (as defined in [@!RFC5322] section 2.2.3)
>    2. The terminating CRLF at the end of the value removed
>    3. Any SP characters at the beginning of the value removed
>    4. Any [@!RFC2047] encoded sections decoded

This is a security design error. I suggest:

Any syntactically correct [@!RFC2047] encoded sections with a known 
character set are decoded and re-encoded as a UTF-8 string with proper 
quoting and escaping for the active RFC 5322 syntactic context 
appropriate for the specific header field. Any [@!RFC2047] encoded NUL 
octets or control characters are dropped from the decoded value. Any 
text that looks like [@!RFC2047] syntax but violates [@!RFC2047] 
placement or whitespace rules MUST NOT be decoded. Any [@!RFC2047] 
content in an unrecognized header MUST NOT be decoded. Same rules apply 
to [@!RFC2231] decoding.

The alternative is to not do 2047/2231 decoding for *decoded* form, or 
only do it for unstructured headers like Subject & Content-Description.

>    5. Any [@!RFC6532] UTF-8 values decoded If any decodings fail, the
>       parser SHOULD insert a unicode replacement character (U+FFFD) 
> and
>       attempt to continue as much as possible.

We might also want to add 6. require the server to convert denormalized 
Unicode to NFC. This is easy enough for a server to do and makes it 
easier for clients to comply with RFC 5198.

>  * *Raw Base64* The raw bytes of the header field value from the first
>    byte following the header field name terminating colon, up to but
>    excluding the header field terminating CRLF, encoded as Base64
>    ([@!RFC4648]). (Note, this is required as the value may not be 
> valid
>    UTF-8 if 8-bit values are present.)

Are non-UTF-8 headers so prevalent that it merits corruption of JMAP? 
There has never been a standard allowing non-UTF-8 content with the 
high-bit set in email headers. I think it's fine to drop (or use Unicode 
replacement character) for any octet or octet run with the high bit set 
that violates UTF-8 syntax. Avoiding the unnecessary base64 step will 
simplify clients. NUL octets should also be dropped, although most mail 
stores will drop them on ingress since they became illegal in generated 
email on April 2001.

>  * *Addresses* The header is parsed as an address-list value, as
>    specified in [@!RFC5322] section 3.4, into the EmailAddress[] type.
>    The *EmailAddress* object has the following properties:
>
>
>    * *name*: String|null The *display name* of the [@!RFC5322] 
> *mailbox*
>      or *group*, or null if none.

It's important for 2047 decoding (as described previously) to be applied 
to this when possible.

>    * *email*: String|null The *addr-spec* of the [@!RFC5322] 
> *mailbox*,
>      or null if a *group*. Parsing SHOULD be best-effort in the face 
> of
>      invalid structure to accommodate invalid messages and 
> semi-complete
>      drafts. EmailAddress objects MAY have an *email* property that 
> does
>      not conform to the *addr-spec* form (for example, may not contain
>      an @ symbol).

Should this allow non-punycode IDN? Should this allow RFC 6532?

>  * *name*: String|null This is the [@!RFC2231] decoded *filename*
>    parameter of the *Content-Disposition* header field, or (for
>    compatibility with existing systems) if not present then the
>    [@!RFC2047] decoded *name* property of the *Content-Type* header
>    field. For compatibility with the widest array of existing systems,
>    both forms should be set if creating a message.

I think this is the wrong place to include rules for generating email. I 
note that setting a "name" parameter on a MIME content type which 
doesn't explicitly register a "name" parameter is a violation of the 
MIME model. Advice to violate the model may be fine as an implementation 
suggestion, but I wouldn't make it a standards-level recommendation.

>  * *type*: String The value of the *Content-Type* header field of the
>    part, excluding any parameters.

Should this have CFWS removed? I think it should.
>  * *bodyStructure*: EmailBodyPart[] (immutable) This is the full MIME
>    structure of the message body, including sub parts but not 
> recursing
>    into message/rfc822 parts.

make that "message/rfc822 or message/global parts."

>    * *value*: String The value of the body part after decoding 
> *Content-
>      Transport* encoding and decoding the *Content-Type* charset.

I think you mean *Content-Transfer-Encoding*, and decoding it is fine. 
Decoding the charset unconditionally in this way violates the MIME model 
as the charset parameter has no strictly defined meaning outside the 
top-level text media-type.

I think there are three design options here:
1. CTE only
2. CTE, plus charset decoding of text/ and other recognized media types 
the server knows have a registered and defined meaning for charset.
3. allow the server to be helpful and briefly describe what it did.

If you choose option 3, I'd add a third "decodingKind" field to 
EmailBodyValue that explains the value. It could be:

*decodingKind*

This is an enumerated type indicating what decoding the server applied 
to the content. I suggest the following options:
*text*: The server decoded any content-transfer-encoding, recognized the 
declared media type as a textual type (regardless of whether it's a 
"text/" or "application/" media type), correctly interpreted the charset 
according to that media type's documented rules and converted it to 
UTF-8. No NUL code points were found in the content.
*UTF8*: The server decoded any content-transfer-encoding and determined 
that the content follows UTF-8 syntax and contains no NUL octets. This 
is never used on standards-compliant body parts with a top-level text 
type. However, if a body part with a top-level text type contains 
non-ASCII UTF-8 content and has no charset parameter (a violation of RFC 
2046), this may be used.
*base64*: The server decoded any content-transfer-encoding but the 
resulting content contains a NUL octet or does not meet UTF-8 syntax 
rules, the value will be base64-encoded without additional modification.
*heuristic*: The server applied some heuristic to convert the content 
charset to UTF-8 text (and no NUL code points were found). For example, 
the server looked at the magic number in an application/octet-stream and 
identified the content as a structured textual type with a known charset 
that could be converted to UTF-8. This may also be used, for example, if 
the charset media type parameter does not match a charset attribute in 
HTML/XML but the content matches the latter parameter.

>  * *attachedEmails*: EmailBodyPart[] (immutable) A list of all parts 
> of
>    type message/rfc822. Note, this *does not* recurse, so the parts

or type message/global.

>    * The *attachedFiles* list contains at least one item that does not
>      have Content-Disposition: attachment. The server MAY ignore parts

I think you mean "Content-Disposition: inline".

		- Chris


From nobody Sun Feb 11 20:08:34 2018
Return-Path: <brong@fastmailteam.com>
X-Original-To: jmap@ietfa.amsl.com
Delivered-To: jmap@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 7C444124207 for <jmap@ietfa.amsl.com>; Sun, 11 Feb 2018 20:08:32 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.72
X-Spam-Level: 
X-Spam-Status: No, score=-2.72 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=fastmailteam.com header.b=M2CTwsxn; dkim=pass (2048-bit key) header.d=messagingengine.com header.b=C9JiiHS6
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nXTKadeGZ4gE for <jmap@ietfa.amsl.com>; Sun, 11 Feb 2018 20:08:28 -0800 (PST)
Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 55E851205F0 for <jmap@ietf.org>; Sun, 11 Feb 2018 20:08:28 -0800 (PST)
Received: from compute6.internal (compute6.nyi.internal [10.202.2.46]) by mailout.nyi.internal (Postfix) with ESMTP id 8F70520D3A for <jmap@ietf.org>; Sun, 11 Feb 2018 23:08:27 -0500 (EST)
Received: from web5 ([10.202.2.215]) by compute6.internal (MEProxy); Sun, 11 Feb 2018 23:08:27 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= fastmailteam.com; h=content-transfer-encoding:content-type:date :from:in-reply-to:message-id:mime-version:references:subject:to :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=JMwQBJVO8lHpW2i6H PNhDAGikyL5V9u55JVPF5JcVlw=; b=M2CTwsxnaxDHBYCc4EFbRmUan0ay3BUu8 K2murlilnCXNbafaKiPJxr+Z0cFB+cjt9VG/MUX6h2K7qd8jZKPTOllAbePhdEMN l4Ne093Iqju3p2OM8fMG76dnxQs7wDursXjJi4PyNCSrkliNVzRH3E0tzPTVEiBc DJv3i/ye09Q3yfxIbtHjtZ8sEtOaiMz9J7MGdAxhnRHf4mAdnupX6pzHP9tQc7N8 6RHmXYQ4pbRZEpNrgEOJShMURVYdiKuI1zeK5krlclSGKsI3sFuDNiT2tXxc31pf Rp17lR0GfIv4n6ASyOGoEVOozaE/XADx0scJEsi2yrfejvA++SezA==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; bh=JMwQBJ VO8lHpW2i6HPNhDAGikyL5V9u55JVPF5JcVlw=; b=C9JiiHS6xVYQRfolXf5kRa YMZovte/Noo2mihO3/SEavQSlKB9Piyxu7D+iuYAoSRmBsB2rsMLCEN37rn3w8D0 EQQZmLFmJqc8Yucd5eI+MR5JBut1z8J8BX7zts3/yK5ZKxW/0aDRRl8ye/mfsQpA O2HyPsi6zwjfvFYgoMC62JKUn3gpDLhh63Z5muzcFwrMlU/eQdWugEXP8tYJ3s/o 0zCJi1IBvwJ8gqdRM14G8l1kxp2nYzFvVUwg4erT+rxsehDt0Sk84wdkO3vx6l2o I6x9V22p/8Nri5mRmacpozxAApq33Ng7/UxoxEbzc3XrpO64JMwjexSGj+IZWCmA ==
X-ME-Sender: <xms:OxOBWgP4OLd_FdzP01pe-KJiwpuP8HBYzCXLz2rswOQwAOirHrrm_w>
Received: by mailuser.nyi.internal (Postfix, from userid 99) id 253029E0D3; Sun, 11 Feb 2018 23:08:27 -0500 (EST)
Message-Id: <1518408506.1699741.1267466096.17DCF605@webmail.messagingengine.com>
From: Bron Gondwana <brong@fastmailteam.com>
To: jmap@ietf.org
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Type: multipart/alternative; boundary="_----------=_151840850716997411"
X-Mailer: MessagingEngine.com Webmail Interface - ajax-fde26eb3
References: <1518070284.168650.1263633200.05C7397A@webmail.messagingengine.com>
In-Reply-To: <1518070284.168650.1263633200.05C7397A@webmail.messagingengine.com>
Date: Mon, 12 Feb 2018 15:08:26 +1100
Archived-At: <https://mailarchive.ietf.org/arch/msg/jmap/Cm63dpQu6wr8TQOmtIojqaL8-nA>
Subject: Re: [Jmap] New JSON message representation
X-BeenThere: jmap@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: JSON Message Access Protocol <jmap.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/jmap>, <mailto:jmap-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/jmap/>
List-Post: <mailto:jmap@ietf.org>
List-Help: <mailto:jmap-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/jmap>, <mailto:jmap-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 12 Feb 2018 04:08:32 -0000

This is a multi-part message in MIME format.

--_----------=_151840850716997411
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"

On Thu, 8 Feb 2018, at 17:11, Neil Jenkins wrote:
> With an eye to closing off all remaining issues before the next IETF
> meeting in March, I have been looking at the issues raised with the
> JSON representation of an RFC5322 message. This email presents a new
> proposal that I think resolves the issues presented. In particular, I
> aim to address the following goals:
>  * Allow access to the full MIME structure without requiring the
>    client to parse the full message itself.
>  * Allow access to full header field information if required.
>  * Keep a simpler representation available for the common case.
>  * Allow the client to only load the data required.> Comments, suggestion=
s and other feedback requested. Cheers!

Sorry, saw this on my phone for the first read-through, so I didn't
reply.  I see Chris already caught some of this, but I'll do my read-
through again and reply as well.
> ------
> Emails


> The *Email* object is a representation of an [@!RFC5322] message,
> which allows clients to avoid the complexities of MIME parsing,
> transport encoding and character encoding.> Properties of the Email object


> Broadly, a message consists of two parts: a list of header fields,
> then a body. The body is normally a MIME-encoded set of documents in a
> tree structure. The JMAP Email object provides a way to access the
> full structure, or to use simplified properties and avoid some
> complexity if this is sufficient for the client application.> Due to the =
number of properties involved, the set of *Email*
> properties is specified over the following three sub-sections.> Metadata


> These properties represent metadata about the [@!RFC5322] message, and
> are not derived from parsing the message itself.


>  * *id*: String (immutable; server-set) The id of the Email object.
>    Note, this is the JMAP object id, NOT the [@!RFC5322] Message-Id
>    header field value.


>  * *blobId*: String (immutable; server-set) The id representing the
>    raw bytes of the [@!RFC5322] message. This may be used to download
>    the raw original message, or to attach it directly to another
>    Email etc.


>  * *threadId*: String (immutable; server-set) The id of the Thread to
>    which this Email belongs.


>  * *mailboxIds*: String[Boolean] The set of mailbox ids this email
>    belongs to. An email MUST belong to one or more mailboxes at all
>    times (until it is deleted). The set is represented as an object,
>    with each key being a *Mailbox id*. The value for each key in the
>    object MUST be true.


>  * *keywords*: String[Boolean] (default: {}) A set of keywords that
>    apply to the email. The set is represented as an object, with the
>    keys being the *keywords*. The value for each key in the object
>    MUST be true.


> Keywords are shared with IMAP. The six system keywords from IMAP are
> treated specially. The following four keywords have their first
> character changed from \ in IMAP to $ in JMAP and have particular
> semantic meaning:


>    * $Draft: The email is a draft the user is composing.
>    * $Seen: The email has been read.
>    * $Flagged: The email has been flagged for urgent/special
>      attention.
>    * $Answered: The email has been replied to. The IMAP \Recent
>      keyword is not exposed via JMAP. The IMAP \Deleted keyword is
>      also not present: IMAP uses a delete+expunge model, which JMAP
>      does not. Any message with the \Deleted keyword MUST NOT be
>      visible via JMAP.


> Users may add arbitrary keywords to an email. For compatibility with
> IMAP, a keyword is a (case-sensitive) string of 1=E2=80=93255 characters =
in
> the ASCII subset %x21=E2=80=93%x7e (excludes control chars and space), and
> MUST NOT include any of these characters: ( ) { ] % * " \


> The IANA Keyword Registry[1] as established in [@!RFC5788] assigns
> semantic meaning to some other keywords in common use. New keywords
> may be established here in the future. In particular, note:


>    * $Forwarded: The email has been forwarded.
>    * $Phishing: The email is highly likely to be phishing. Clients
>      SHOULD warn users to take care when viewing this email and
>      disable links and attachments.
>    * $Junk: The email is definitely spam. Clients SHOULD set this flag
>      when users report spam to help train automated spam-detection
>      systems.
>    * $NotJunk: The email is definitely not spam. Clients SHOULD set
>      this flag when users indicate an email is legitimate, to help
>      train automated spam-detection systems.
did we want to talk about $HasAttachment and friend as well?

>  * *size*: Number (immutable; server-set) The size in bytes of the
>    whole email as counted by the server towards the user's quota.
I noticed this inconsistency as well - matching blobId size is by far
the most useful thing to do here.
>  * *receivedAt*: UTCDate (immutable; default: time of creation on
>    server) The date the email was received by the message store. This
>    is the *internal date* in IMAP.> Header fields


> These properties are derived from the [@!RFC5322] message header
> fields. Header fields may be fetched in a variety of forms:


>  * *Decoded* The header field value with:


>    1. White space unfolded (as defined in [@!RFC5322] section 2.2.3)
>    2. The terminating CRLF at the end of the value removed
>    3. Any SP characters at the beginning of the value removed
>    4. Any [@!RFC2047] encoded sections decoded
>    5. Any [@!RFC6532] UTF-8 values decoded If any decodings fail, the
>       parser SHOULD insert a unicode replacement character (U+FFFD)
>       and attempt to continue as much as possible.


>  * *Raw Base64* The raw bytes of the header field value from the first
>    byte following the header field name terminating colon, up to but
>    excluding the header field terminating CRLF, encoded as Base64
>    ([@!RFC4648]). (Note, this is required as the value may not be
>    valid UTF-8 if 8-bit values are present.)


>  * *Addresses* The header is parsed as an address-list value, as
>    specified in [@!RFC5322] section 3.4, into the EmailAddress[] type.
>    The *EmailAddress* object has the following properties:


>    * *name*: String|null The *display name* of the [@!RFC5322]
>      *mailbox* or *group*, or null if none.
>    * *email*: String|null The *addr-spec* of the [@!RFC5322]
>      *mailbox*, or null if a *group*.
I don't know enough about the group syntax, but I thought it was
nestable in a way that makes it hard to flatten.  Maybe just a null
group is enough, but the example in RFC5322 shows a group with 3
addresses in it:
Appendix A.1.3[2].  Group Addresses  ---- From: Pete
<pete@silly.example> To: A Group:Ed Jones <c@a.test>,joe@where.test,John
<jdoe@one.test>; Cc: Undisclosed recipients:; Date: Thu, 13 Feb 1969
23:32:54 -0330 Message-ID: <testabcd.1234@silly.example>  Testing. ----
In this message, the "To:" field has a single group recipient named "A
Group", which contains 3 addresses, and a "Cc:" field with an empty
group recipient named Undisclosed recipients.And I have a horrible sinking =
feeling that the group could contain
nested groups in the full RFC5322 syntax, meaning you could have an
arbitrarily deep tree of addresses.
>  * Parsing SHOULD be best-effort in the face of invalid structure to
>    accommodate invalid messages and semi-complete drafts. EmailAddress
>    objects MAY have an *email* property that does not conform to the
>    *addr-spec* form (for example, may not contain an @ symbol).
>  * *Date* The header is parsed as a date-time value, as specified in
>    [@!RFC5322] section 3.3, into the Date type.> The following *Email* pr=
operties are specified for complete access to
> the header data of the message. Where {header-field-name} is specified
> within a property name, this means any series of one or more printable
> US-ASCII characters (i.e. characters that have values between 33 and
> 126, inclusive), except colon:


>  * *headers*: EmailHeader[] (immutable) This is a list of all
>    [@!RFC5322] header fields, in the same order they appear in the
>    message. The values are in *Decoded* form.
>  * *headers:asRaw*: EmailHeader[] (immutable) This is a list of all
>    [@!RFC5322] header fields, in the same order they appear in the
>    message. The values are in *Raw Base64* form.
>  * *header:{header-field-name}*: String|null (immutable) The value of
>    the *last* header field in the message with the given header field
>    name (matched case-insensitively), or null if none. The value is in
>    *Decoded* form.
This does seem to mean that it's impossible to ask for all instances of
a particular named header.  You either get the whole lot, or you get
just the last of a particular named one.  I don't know that it's likely
to be a big problem, but I do note the limitation.
>  * *header:{header-field-name}:asRaw*: String|null (immutable) The
>    value of the *last* header field in the message with the given
>    header field name (matched case-insensitively), or null if none.
>    The value is in *Raw Base64* form.
>  * *header:{header-field-name}:asAddresses*: EmailAddress[]|null
>    (immutable) The value of the *last* header field in the message
>    with the given header field name (matched case-insensitively), or
>    null if none. The value is in *Addresses* form.
>  * *header:{header-field-name}:asDate*: Date|null (immutable) The
>    value of the *last* header field in the message with the given
>    header field name (matched case-insensitively), or null if none.
>    The value is in *Date* form.> An *EmailHeader* object has the followin=
g properties:


>  * *name*: String The header *field name* as defined in RFC5322, with
>    the same capitalization that it has in the message.
>  * *value*: String The header *field value* as defined in RFC5322, in
>    either *Decoded* or *Raw Base64* form as determined by the property
>    being fetched.> The following convenience properties are also specifie=
d for the
> *Email* object:


>  * *sender*: EmailAddress[]|null (immutable) The value is identical to
>    the value of *header:Sender:asAddresses*.
>  * *from*: EmailAddress[]|null (immutable) The value is identical to
>    the value of *header:From:asAddresses*.
>  * *to*: EmailAddress[]|null (immutable) The value is identical to the
>    value of *header:To:asAddresses*.
>  * *cc*: EmailAddress[]|null (immutable) The value is identical to the
>    value of *header:Cc:asAddresses*.
>  * *bcc*: EmailAddress[]|null (immutable) The value is identical to
>    the value of *header:Bcc:asAddresses*.
>  * *replyTo*: EmailAddress[]|null (immutable) The value is identical
>    to the value of *header:Reply-To:asAddresses*.
>  * *subject*: String|null (immutable) The value is identical to the
>    value of *header:Subject*.
>  * *sentAt*: Date (immutable; default: time of creation on server) The
>    value is identical to the value of *header:Date:asDate*.> Body parts


> These properties are derived from the [@!RFC5322] message body and its
> [@RFC2045] MIME entities.> A *EmailBodyPart* object has the following pro=
perties:


>  * *partId*: String Identifies this part uniquely within the Email.
>    This is scoped to the *emailId* and has no meaning outside of the
>    JMAP Email object representation.
>  * *blobId*: String The id references the raw bytes of the contents of
>    the part after decoding any *Content-Transfer* encoding (as defined
>    in [@!RFC2045]). Note, two parts may be transfer-encoded
>    differently but have same the same blob id if their decoded bytes
>    are identical and the server is using a secure hash of the data for
>    the blob id.
>  * *size*: Number The size, in bytes, of the raw data after content-
>    transfer decoding (as refrenced by the *blobId*, i.e. the number of
>    bytes in the file the user would download).
>  * *headers*: EmailHeader[] (immutable) This is a list of all header
>    fields in the part, in the order they appear. The values are in
>    *Decoded* form.
>  * *headers:asRaw*: EmailHeader[] (immutable) This is a list of all
>    header fields in the part, in the order they appear. The values are
>    in *Raw Base64* form.
>  * *name*: String|null This is the [@!RFC2231] decoded *filename*
>    parameter of the *Content-Disposition* header field, or (for
>    compatibility with existing systems) if not present then the
>    [@!RFC2047] decoded *name* property of the *Content-Type* header
>    field. For compatibility with the widest array of existing systems,
>    both forms should be set if creating a message.
>  * *type*: String The value of the *Content-Type* header field of the
>    part, excluding any parameters.
>  * *charset*: String|null The value of the charset parameter of the
>    *Content-Type* header field, if present.
>  * *disposition*: String|null The value of the *Content-Disposition*
>    header field of the part, excluding any parameters, if present.
>  * *cid*: String|null The value of the *Content-Id* header field of
>    the part, if present. This may be used to reference the content
>    from within an html body part using the cid: protocol.
>  * *language*: String[]|null The list of language tags, as defined in
>    [@!RFC3282], in the *Content-Language* header field of the part, if
>    present.
>  * *location*: String|null The URI, as defined in [@!RFC2557], in the
>    *Content-Location* header field of the part, if present.
>  * *width*: Number|null The width (in px) of the image, if the type is
>    an image and the server is able to determine this information for
>    the image. This MAY not be supported for all or any image types on
>    some servers.
>  * *height*: Number|null The height (in px) of the image, if the type
>    is an image and the server is able to determine this information
>    for the image. This MAY not be supported for all or any image types
>    on some servers.
>  * *subParts*: EmailBodyPart[] (optional) If type is multipart/*, this
>    contains the body parts of each child.> The following *Email* properti=
es are specified for access to the body
> data of the message:


>  * *bodyStructure*: EmailBodyPart[] (immutable) This is the full MIME
>    structure of the message body, including sub parts but not
>    recursing into message/rfc822 parts.


>  * *bodyValues*: String[BodyValue] (immutable) This is a map of
>    *partId* to an *EmailBodyValue* object. Which parts are included
>    and whether the value is truncated is determined by various
>    arguments to *Email/get* and *Email/parse*.


> An *EmailBodyValue* object has the following properties:


>    * *value*: String The value of the body part after decoding *Content-
>      Transport* encoding and decoding the *Content-Type* charset.
>    * *isTruncated* Boolean This is true if the *value* has been
>      truncated.
>  * *textBody*: EmailBodyPart[] (immutable) A list of text/plain,
>    text/html and image/* parts to display (sequentially) as the
>    message body, with a preference for text/plain when alternative
>    versions are available.


>  * *htmlBody*: EmailBodyPart[] (immutable) A list of text/plain,
>    text/html and image/* parts to display (sequentially) as the
>    message body, with a preference for text/html when alternative
>    versions are available.
There was some discussion about how to handle RFC 8255
multipart/multilingual or other things here - whether we add something
along the lines of "the server will choose which representation to
include based on the original language plus what it knows about the
user's preferred language" - plus of course the full information is
available in the bodyStructure if the client wants to be smart about it.
This is also a good place for a JMAP extension which could give a more
powerful query language for choosing specific parts in multipart.
>  * *attachedEmails*: EmailBodyPart[] (immutable) A list of all parts
>    of type message/rfc822. Note, this *does not* recurse, so the parts
>    within these are not included. The attached message may be fetched
>    using the Email/parse method and the blobId.
Might be worth having an example of this - it's going to be one of the
tricky bits for people to understand.
>  * *attachedFiles*: EmailBodyPart[] (immutable) A list of all parts in
>    *bodyStructure*, traversing depth-first, not of type multipart/*,
>    and not included in any of the *textBody*, *htmlBody* or
>    *attachedEmails* properties. Note, an HTML body part may reference
>    image parts in attachedFiles using cid: links to reference the *Conten=
t-
>    Id* or by referencing the *Content-Location*.
This could do with being a little clearer that "even if referenced by an
HTML body part, attached files will be included in this list" - or
something like that.
>  * *hasAttachment*: Boolean (immutable; server-set) This is true if
>    there are one or more parts in the message that a client UI should
>    offer as downloadable. A server SHOULD set hasAttachment if either:


>    * The *attachedEmails* list contains at least one item.
>    * The *attachedFiles* list contains at least one item that does not
>      have Content-Disposition: attachment. The server MAY ignore parts
>      in this list that are processed automatically in some way, or are
>      referenced as embedded images in one of the text/html parts of
>      the message.
It's already been noted that the logic is reversed here, should be "does
have" or maybe even "does not have Content-Disposition: inline" instead.
>  * The server MAY set hasAttachment based on implementation-defined or
>    site configurable heuristics.


>  * *preview*: String (immutable; server-set) Up to 256 characters of
>    the beginning of a plain text version of the message body. This is
>    intended to be shown as a preview line on a mailbox listing, and
>    the server may choose to skip quoted sections or salutations to
>    return a more useful preview.
I wouldn't even say "of the beginning" - it's up to 256 characters
that provide a good summary of the content of the message.  I would
say something like: This is intended to be shown as a preview line on
a mailbox listing, and not all characters may be shown.  The server
may choose which part of the message to include in the preview, for
example skipping quoted sections and salutations can result in a more
useful preview.
> MIME structures are arbitrary nested trees of documents, but the
> majority of email clients present a model of an email body (normally
> plain text or HTML), with a set of attachments. Interpreting the MIME
> structure to form this flat model represents considerable difficulty
> and causes inconsistency between clients. Therefore in addition to the
> *bodyStructure* property, which gives the full tree, the Email object
> contains 4 alternate properties with flat lists of body parts:


>  * *textBody*/*htmlBody*: These provide a list of parts that should be
>    rendered as the "body" of the message. This is a list rather than a
>    single part as messages may have headers and/or footers
>    appended/prepended as separate parts as they are transmitted, and
>    some clients send text and images intended to be displayed inline
>    in the body as multiple parts rather than a single HTML part with
>    referenced images.


> Because MIME allows for multiple representations of the same data
> (using multipart/alternative), there is a textBody property (which
> prefers a plain text representation) and an htmlBody property (which
> prefers an HTML representation) to accommodate the two most common
> client requirements. The same part may appear in both lists where
> there is no alternative between the two.


>  * *attachedEmails*/*attachedFiles*: These provide a list of parts
>    that should be presented as "attachments" to the message. Emails
>    are presented in a separate list so their contents may be easily
>    fetched via a back-reference with the Email/parse method in the
>    same request, if the client wishes to. Some images in attachedFiles
>    may be solely there for embedding within an HTML body part; clients
>    may wish to not present these as attachments in the user interface
>    if they are displaying the HTML with the embedded images directly.> Th=
e *bodyValues* property allows for clients to fetch the value of
> text parts directly without having to do a second request for the
> blob, and have the server handle decoding the charset into unicode.
> This data is in a separate property rather than on the EmailBodyPart
> object to avoid duplication of large amounts of data, as the same part
> may be included twice if the client fetches more than one of
> bodyStructure, textBody and htmlBody.> The exact algorithm for decomposin=
g bodyStructure into textBody,
> htmlBody, attachedEmails and attachedFiles part lists is not mandated,
> as this is a quality-of-service implementation issue and likely to
> require workarounds for malformed content discovered over time.> However,=
 we will define a suggested algorithm for the RFC to help
> implementors. TODO.> Email/get


> Standard */get* method, with the following additional arguments:


>  * *bodyProperties*: String[] (optional) A list of properties to fetch
>    for each EmailBodyPart returned. If omitted, this defaults to:


> [ "partId", "blobId", "size", "name", "type", "charset",
> "disposition", cid", "language", "location", "width", "height" ]


>  * *fetchTextBodyValues*: Boolean (default: false) If true, the
>    *bodyValues* property includes any text/* part in the textBody
>    property.


>  * *fetchHTMLBodyValues*: Boolean (default: false) If true, the
>    *bodyValues* property includes any text/* part in the htmlBody
>    property.


>  * *fetchAllBodyValues*: Boolean (default: false) If true, the
>    *bodyValues* property includes any text/* part in the bodyStructure
>    property.


>  * *maxBodyValueBytes*: Number (optional) If supplied by the client,
>    the value MUST be a positive integer greater than 0. If a value
>    outside of this range is given, the server MUST reject the call
>    with an invalidArguments error. When given, the *value* property of
>    any EmailBodyValue object returned in *bodyValues* MUST be
>    truncated if necessary so it does not exceed this number of bytes
>    in size. The server MUST ensure the truncation results in valid UTF-
>    8 and does not occur mid-codepoint. If the part is of type
>    text/html, the server SHOULD NOT truncate inside an HTML tag.> If the =
standard *properties* argument is omitted or null, the
> following default MUST be used instead of "all" properties:


> [ "id", "blobId", "threadId", "mailboxIds", "keywords", "size",
> "receivedAt", "sender", "from", "to", "cc", "bcc", "replyTo",
> "subject", "sentAt", "hasAttachment", "preview", "bodyValues",
> "textBody", "htmlBody", "attachedFiles", "attachedEmails" ]
>> The following properties are expected to be fast to fetch in a quality
> implementation:


>  * id
>  * blobId
>  * threadId
>  * mailboxIds
>  * keywords
>  * size
>  * receivedAt
>  * sender
>  * from
>  * to
>  * cc
>  * bcc
>  * replyTo
>  * subject
>  * sentAt
>  * hasAttachment
>  * preview> Clients SHOULD take care when fetching any other properties, =
as
> there may be significantly longer latency in fetching and returning
> the data.> Example


> Request:


> ["Email/get", { "ids": [ "f123u456", "f123u457" ], "properties": [
> "threadId", "mailboxIds", "from", "subject", "receivedAt", "htmlBody",
> "bodyValues" ], "bodyProperties": [ "partId", "blobId", "size", "type"
> ], "fetchHTMLBodyValues": true, "maxBodyValueBytes": 256 }, "#1"]
>> and response:


> ["Email/get", { "accountId": "abc", "state": "41234123231", "list": [
> { "id": "f123u457", "threadId": "ef1314a", "mailboxIds": { "f123":
> true }, "from": [{name: "Joe Bloggs", email: "joe@bloggs.com"}],
> "subject": "Dinner on Thursday?", "receivedAt": "2013-10-
> 13T14:12:00Z", "htmlBody": [{ "partId": "1", "blobId": "841623871",
> "size": 283331, "type": "text/html" }, { "partId": "2", "blobId":
> "319437193", "size": 10343, "type": "text/plain" }], "bodyValues": {
> "1": { "isTruncated": true, "value": "<html><body><p>Hello ..." },
> "2": { "isTruncated": false, "value": "-- \nSent by your friendly
> mailing list ..." } } } ], notFound: [ "f123u456" ] }, "#1"]
>>=20
> _________________________________________________
> Jmap mailing list
> Jmap@ietf.org
> https://www.ietf.org/mailman/listinfo/jmap

--
  Bron Gondwana, CEO, FastMail Pty Ltd
  brong@fastmailteam.com



Links:

  1. https://www.iana.org/assignments/imap-keywords/imap-keywords.xhtml
  2. https://tools.ietf.org/html/rfc5322#appendix-A.1.3

--_----------=_151840850716997411
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="utf-8"

<!DOCTYPE html>
<html>
<head>
<title></title>
<style type=3D"text/css">p.MsoNormal,p.MsoNoSpacing{margin:0}</style>
</head>
<body><div style=3D"font-family:Arial;">On Thu, 8 Feb 2018, at 17:11, Neil =
Jenkins wrote:<br></div>
<blockquote type=3D"cite"><div>With an eye to closing off all remaining iss=
ues before the next IETF meeting in March, I have been looking at the issue=
s raised with the JSON representation of an RFC5322 message. This email pre=
sents a new proposal that I think resolves the issues presented. In particu=
lar, I aim to address the following goals:<br></div>
<ul><li>Allow access to the full MIME structure without requiring the clien=
t to parse the full message itself.<br></li><li>Allow access to full header=
 field information if required.<br></li><li>Keep a simpler representation a=
vailable for the common case.<br></li><li>Allow the client to only load the=
 data required.<br></li></ul><div>Comments, suggestions and other feedback =
requested. Cheers!<br></div>
</blockquote><div style=3D"font-family:Arial;"><br></div>
<div style=3D"font-family:Arial;">Sorry, saw this on my phone for the first=
 read-through, so I didn't reply.&nbsp; I see Chris already caught some of =
this, but I'll do my read-through again and reply as well.<br></div>
<div style=3D"font-family:Arial;"><br></div>
<blockquote type=3D"cite"><div>------<br></div>
<h1>Emails<br></h1><p>The <b>Email</b> object is a representation of an [@!=
RFC5322] message, which allows clients to avoid the complexities of MIME pa=
rsing, transport encoding and character encoding.<br></p><h2>Properties of =
the Email object<br></h2><p>Broadly, a message consists of two parts: a lis=
t of header fields, then a body. The body is normally a MIME-encoded set of=
 documents in a tree structure. The JMAP Email object provides a way to acc=
ess the full structure, or to use simplified properties and avoid some comp=
lexity if this is sufficient for the client application.<br></p><p>Due to t=
he number of properties involved, the set of <i>Email</i> properties is spe=
cified over the following three sub-sections.<br></p><h3>Metadata<br></h3><=
p>These properties represent metadata about the [@!RFC5322] message, and ar=
e not derived from parsing the message itself.<br></p><ul><li><p><b>id</b>:=
 <code>String</code> (immutable; server-set)
The id of the Email object. Note, this is the JMAP object id, NOT the [@!RF=
C5322] Message-Id header field value.<br></p></li><li><p><b>blobId</b>: <co=
de>String</code> (immutable; server-set)
The id representing the raw bytes of the [@!RFC5322] message. This may be u=
sed to download the raw original message, or to attach it directly to anoth=
er Email etc.<br></p></li><li><p><b>threadId</b>: <code>String</code> (immu=
table; server-set)
The id of the Thread to which this Email belongs.<br></p></li><li><p><b>mai=
lboxIds</b>: <code>String[Boolean]</code> The set of mailbox ids this email=
 belongs to. An email MUST belong to one or more mailboxes at all times (un=
til it is deleted). The set is represented as an object, with each key bein=
g a <i>Mailbox id</i>. The value for each key in the object MUST be <code>t=
rue</code>.<br></p></li><li><p><b>keywords</b>: <code>String[Boolean]</code=
> (default: <code>{}</code>)
A set of keywords that apply to the email. The set is represented as an obj=
ect, with the keys being the <i>keywords</i>. The value for each key in the=
 object MUST be <code>true</code>.<br></p><p>Keywords are shared with IMAP.=
 The six system keywords from IMAP are treated specially. The following fou=
r keywords have their first character changed from <code>\</code> in IMAP t=
o <code>$</code> in JMAP and have particular semantic meaning:<br></p><ul><=
li><code>$Draft</code>: The email is a draft the user is composing.<br></li=
><li><code>$Seen</code>: The email has been read.<br></li><li><code>$Flagge=
d</code>: The email has been flagged for urgent/special attention.<br></li>=
<li><code>$Answered</code>: The email has been replied to.<br></li></ul><p>=
The IMAP <code>\Recent</code> keyword is not exposed via JMAP. The IMAP <co=
de>\Deleted</code> keyword is also not present: IMAP uses a delete+expunge =
model, which JMAP does not. Any message with the <code>\Deleted</code> keyw=
ord MUST NOT be visible via JMAP.<br></p><p>Users may add arbitrary keyword=
s to an email. For compatibility with IMAP, a keyword is a (case-sensitive)=
 string of 1=E2=80=93255 characters in the ASCII subset %x21=E2=80=93%x7e (=
excludes control chars and space), and MUST NOT include any of these charac=
ters: <code>( ) { ] % * " \</code><br></p><p>The <a href=3D"https://www.ian=
a.org/assignments/imap-keywords/imap-keywords.xhtml">IANA Keyword Registry<=
/a> as established in [@!RFC5788] assigns semantic meaning to some other ke=
ywords in common use. New keywords may be established here in the future. I=
n particular, note:<br></p><ul><li><code>$Forwarded</code>: The email has b=
een forwarded.<br></li><li><code>$Phishing</code>: The email is highly like=
ly to be phishing. Clients SHOULD warn users to take care when viewing this=
 email and disable links and attachments.<br></li><li><code>$Junk</code>: T=
he email is definitely spam. Clients SHOULD set this flag when users report=
 spam to help train automated spam-detection systems.<br></li><li><code>$No=
tJunk</code>: The email is definitely not spam. Clients SHOULD set this fla=
g when users indicate an email is legitimate, to help train automated spam-=
detection systems.<br></li></ul></li></ul></blockquote><div style=3D"font-f=
amily:Arial;"><br></div>
<div style=3D"font-family:Arial;">did we want to talk about $HasAttachment =
and friend as well?<br></div>
<div style=3D"font-family:Arial;"><br></div>
<blockquote type=3D"cite"><ul><li><p><b>size</b>: <code>Number</code> (immu=
table; server-set)
The size in bytes of the whole email as counted by the server towards the u=
ser's quota.<br></p></li></ul></blockquote><div style=3D"font-family:Arial;=
"><br></div>
<div style=3D"font-family:Arial;">I noticed this inconsistency as well - ma=
tching blobId size is by far the most useful thing to do here.<br></div>
<div style=3D"font-family:Arial;"><br></div>
<blockquote type=3D"cite"><ul><li><p><b>receivedAt</b>: <code>UTCDate</code=
> (immutable; default: time of creation on server)
The date the email was received by the message store. This is the <i>intern=
al date</i> in IMAP.<br></p></li></ul><h3>Header fields<br></h3><p>These pr=
operties are derived from the [@!RFC5322] message header fields. Header fie=
lds may be fetched in a variety of forms:<br></p><ul><li><p><b>Decoded</b> =
The header field value with:<br></p><ol><li>White space unfolded (as define=
d in [@!RFC5322] section 2.2.3)<br></li><li>The terminating CRLF at the end=
 of the value removed<br></li><li>Any SP characters at the beginning of the=
 value removed<br></li><li>Any [@!RFC2047] encoded sections decoded<br></li=
><li>Any [@!RFC6532] UTF-8 values decoded<br></li></ol><p>If any decodings =
fail, the parser SHOULD insert a unicode replacement
character (U+FFFD) and attempt to continue as much as possible.<br></p></li=
><li><p><b>Raw Base64</b> The raw bytes of the header field value from the =
first byte following the header field name terminating colon, up to but exc=
luding the header field terminating CRLF, encoded as Base64 ([@!RFC4648]). =
(Note, this is required as the value may not be valid UTF-8 if 8-bit values=
 are present.)<br></p></li><li><p><b>Addresses</b> The header is parsed as =
an <code>address-list</code> value, as specified in [@!RFC5322] section 3.4=
, into the <code>EmailAddress[]</code> type. The <b>EmailAddress</b> object=
 has the following properties:<br></p><ul><li><b>name</b>: <code>String|nul=
l</code> The <i>display name</i> of the [@!RFC5322] <i>mailbox</i> or <i>gr=
oup</i>, or <code>null</code> if none.<br></li><li><b>email</b>: <code>Stri=
ng|null</code> The <i>addr-spec</i> of the [@!RFC5322] <i>mailbox</i>, or <=
code>null</code> if a <i>group</i>.<br></li></ul></li></ul></blockquote><di=
v style=3D"font-family:Arial;"><br></div>
<div style=3D"font-family:Arial;">I don't know enough about the group synta=
x, but I thought it was nestable in a way that makes it hard to flatten.&nb=
sp; Maybe just a null group is enough, but the example in RFC5322 shows a g=
roup with 3 addresses in it:<br></div>
<div style=3D"font-family:Arial;"><br></div>
<pre class=3D"newpage"><span class=3D"h4"><h4><a href=3D"https://tools.ietf=
.org/html/rfc5322#appendix-A.1.3" name=3D"appendix-A.1.3" class=3D"selflink=
">Appendix A.1.3</a>.  Group Addresses

   ----
   From: Pete &lt;<a href=3D"mailto:pete@silly.example">pete@silly.example<=
/a>&gt;
   To: A Group:Ed Jones &lt;<a href=3D"mailto:c@a.test">c@a.test</a>&gt;,<a=
 href=3D"mailto:joe@where.test">joe@where.test</a>,John &lt;<a href=3D"mail=
to:jdoe@one.test">jdoe@one.test</a>&gt;;
   Cc: Undisclosed recipients:;
   Date: Thu, 13 Feb 1969 23:32:54 -0330
   Message-ID: &lt;<a href=3D"mailto:testabcd.1234@silly.example">testabcd.=
1234@silly.example</a>&gt;

   Testing.
   ----

   In this message, the "To:" field has a single group recipient named
   "A Group", which contains 3 addresses, and a "Cc:" field with an
   empty group recipient named Undisclosed recipients.
<br></h4><div style=3D"font-family:Arial;">And I have a horrible sinking fe=
eling that the group could contain nested groups in the full RFC5322 syntax=
, meaning you could have an arbitrarily deep tree of addresses.<br></div>
</span></pre><div style=3D"font-family:Arial;"><br></div>
<blockquote type=3D"cite"><ul><li><div style=3D"font-family:Arial;">Parsing=
 SHOULD be best-effort in the face of invalid structure to accommodate
invalid messages and semi-complete drafts. EmailAddress objects MAY have an=
 <i>email</i> property that does not conform to the <i>addr-spec</i> form (=
for example, may not contain an @ symbol).<br></div>
</li><li><p><b>Date</b> The header is parsed as a <code>date-time</code> va=
lue, as specified in [@!RFC5322] section 3.3, into the <code>Date</code> ty=
pe.<br></p></li></ul><p>The following <b>Email</b> properties are specified=
 for complete access to the header data of the message. Where <code>{header=
-field-name}</code> is specified within a property name, this means any ser=
ies of one or more printable US-ASCII characters (i.e. characters that have=
 values between 33 and 126, inclusive), except colon:<br></p><ul><li><b>hea=
ders</b>: <code>EmailHeader[]</code> (immutable)
This is a list of all [@!RFC5322] header fields, in the same order they app=
ear in the message. The values are in <i>Decoded</i> form.<br></li><li><b>h=
eaders:asRaw</b>: <code>EmailHeader[]</code> (immutable)
This is a list of all [@!RFC5322] header fields, in the same order they app=
ear in the message. The values are in <i>Raw Base64</i> form.<br></li><li><=
b>header:{header-field-name}</b>: <code>String|null</code> (immutable)
The value of the <i>last</i> header field in the message with the given hea=
der field name (matched case-insensitively), or <code>null</code> if none. =
The value is in <i>Decoded</i> form.<br></li></ul></blockquote><div style=
=3D"font-family:Arial;"><br></div>
<div style=3D"font-family:Arial;">This does seem to mean that it's impossib=
le to ask for all instances of a particular named header.&nbsp; You either =
get the whole lot, or you get just the last of a particular named one.&nbsp=
; I don't know that it's likely to be a big problem, but I do note the limi=
tation.<br></div>
<div style=3D"font-family:Arial;"><br></div>
<blockquote type=3D"cite"><ul><li><b>header:{header-field-name}:asRaw</b>: =
<code>String|null</code> (immutable)
The value of the <i>last</i> header field in the message with the given hea=
der field name (matched case-insensitively), or <code>null</code> if none. =
The value is in <i>Raw Base64</i> form.<br></li><li><b>header:{header-field=
-name}:asAddresses</b>: <code>EmailAddress[]|null</code> (immutable)
The value of the <i>last</i> header field in the message with the given hea=
der field name (matched case-insensitively), or <code>null</code> if none. =
The value is in <i>Addresses</i> form.<br></li><li><b>header:{header-field-=
name}:asDate</b>: <code>Date|null</code> (immutable)
The value of the <i>last</i> header field in the message with the given hea=
der field name (matched case-insensitively), or <code>null</code> if none. =
The value is in <i>Date</i> form.<br></li></ul><p>An <b>EmailHeader</b> obj=
ect has the following properties:<br></p><ul><li><b>name</b>: <code>String<=
/code> The header <i>field name</i> as defined in RFC5322, with the same ca=
pitalization that it has in the message.<br></li><li><b>value</b>: <code>St=
ring</code> The header <i>field value</i> as defined in RFC5322, in either =
<i>Decoded</i> or <i>Raw Base64</i> form as determined by the property bein=
g fetched.<br></li></ul><p>The following convenience properties are also sp=
ecified for the <b>Email</b> object:<br></p><ul><li><b>sender</b>: <code>Em=
ailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:Sender:asAddresses</i>.<br=
></li><li><b>from</b>: <code>EmailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:From:asAddresses</i>.<br><=
/li><li><b>to</b>: <code>EmailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:To:asAddresses</i>.<br></l=
i><li><b>cc</b>: <code>EmailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:Cc:asAddresses</i>.<br></l=
i><li><b>bcc</b>: <code>EmailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:Bcc:asAddresses</i>.<br></=
li><li><b>replyTo</b>: <code>EmailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:Reply-To:asAddresses</i>.<=
br></li><li><b>subject</b>: <code>String|null</code> (immutable)
The value is identical to the value of <i>header:Subject</i>.<br></li><li><=
b>sentAt</b>: <code>Date</code> (immutable; default: time of creation on se=
rver)
The value is identical to the value of <i>header:Date:asDate</i>.<br></li><=
/ul><h3>Body parts<br></h3><p>These properties are derived from the [@!RFC5=
322] message body and its [@RFC2045] MIME entities.<br></p><p>A <b>EmailBod=
yPart</b> object has the following properties:<br></p><ul><li><b>partId</b>=
: <code>String</code> Identifies this part uniquely within the Email. This =
is scoped to the <i>emailId</i> and has no meaning outside of the JMAP Emai=
l object representation.<br></li><li><b>blobId</b>: <code>String</code> The=
 id references the raw bytes of the contents of the part after decoding any=
 <i>Content-Transfer</i> encoding (as defined in [@!RFC2045]). Note, two pa=
rts may be transfer-encoded differently but have same the same blob id if t=
heir decoded bytes are identical and the server is using a secure hash of t=
he data for the blob id.<br></li><li><b>size</b>: <code>Number</code> The s=
ize, in bytes, of the raw data after content-transfer decoding (as refrence=
d by the <i>blobId</i>, i.e. the number of bytes in the file the user would=
 download).<br></li><li><b>headers</b>: <code>EmailHeader[]</code> (immutab=
le)
This is a list of all header fields in the part, in the order they appear. =
The values are in <i>Decoded</i> form.<br></li><li><b>headers:asRaw</b>: <c=
ode>EmailHeader[]</code> (immutable)
This is a list of all header fields in the part, in the order they appear. =
The values are in <i>Raw Base64</i> form.<br></li><li><b>name</b>: <code>St=
ring|null</code> This is the [@!RFC2231] decoded <i>filename</i> parameter =
of the <i>Content-Disposition</i> header field, or (for compatibility with =
existing systems) if not present then the [@!RFC2047] decoded <i>name</i> p=
roperty of the <i>Content-Type</i> header field. For compatibility with the=
 widest array of existing systems, both forms should be set if creating a m=
essage.<br></li><li><b>type</b>: <code>String</code> The value of the <i>Co=
ntent-Type</i> header field of the part, excluding any parameters.<br></li>=
<li><b>charset</b>: <code>String|null</code> The value of the charset param=
eter of the <i>Content-Type</i> header field, if present.<br></li><li><b>di=
sposition</b>: <code>String|null</code> The value of the <i>Content-Disposi=
tion</i> header field of the part, excluding any parameters, if present.<br=
></li><li><b>cid</b>: <code>String|null</code> The value of the <i>Content-=
Id</i> header field of the part, if present. This may be used to reference =
the content from within an html body part using the <code>cid:</code> proto=
col.<br></li><li><b>language</b>: <code>String[]|null</code> The list of la=
nguage tags, as defined in [@!RFC3282], in the <i>Content-Language</i> head=
er field of the part, if present.<br></li><li><b>location</b>: <code>String=
|null</code> The URI, as defined in [@!RFC2557], in the <i>Content-Location=
</i> header field of the part, if present.<br></li><li><b>width</b>: <code>=
Number|null</code> The width (in px) of the image, if the type is an image =
and the server is able to determine this information for the image. This MA=
Y not be supported for all or any image types on some servers.<br></li><li>=
<b>height</b>: <code>Number|null</code> The height (in px) of the image, if=
 the type is an image and the server is able to determine this information =
for the image. This MAY not be supported for all or any image types on some=
 servers.<br></li><li><b>subParts</b>: <code>EmailBodyPart[]</code> (option=
al)
If type is <code>multipart/*</code>, this contains the body parts of each c=
hild.<br></li></ul><p>The following <b>Email</b> properties are specified f=
or access to the body data of the message:<br></p><ul><li><p><b>bodyStructu=
re</b>: <code>EmailBodyPart[]</code> (immutable)
This is the full MIME structure of the message body, including sub parts bu=
t not recursing into <code>message/rfc822</code> parts.<br></p></li><li><p>=
<b>bodyValues</b>: <code>String[BodyValue]</code> (immutable)
This is a map of <i>partId</i> to an <b>EmailBodyValue</b> object. Which pa=
rts are included and whether the value is truncated is determined by variou=
s arguments to <i>Email/get</i> and <i>Email/parse</i>.<br></p><p>An <b>Ema=
ilBodyValue</b> object has the following properties:<br></p><ul><li><b>valu=
e</b>: <code>String</code> The value of the body part after decoding <i>Con=
tent-Transport</i> encoding and
decoding the <i>Content-Type</i> charset.<br></li><li><b>isTruncated</b> <c=
ode>Boolean</code> This is <code>true</code> if the <i>value</i> has been t=
runcated.<br></li></ul></li><li><p><b>textBody</b>: <code>EmailBodyPart[]</=
code> (immutable)
A list of <code>text/plain</code>, <code>text/html</code> and <code>image/*=
</code> parts to display (sequentially) as the message body, with a prefere=
nce for <code>text/plain</code> when alternative versions are available.<br=
></p></li><li><p><b>htmlBody</b>: <code>EmailBodyPart[]</code> (immutable)
A list of <code>text/plain</code>, <code>text/html</code> and <code>image/*=
</code> parts to display (sequentially) as the message body, with a prefere=
nce for <code>text/html</code> when alternative versions are available.<br>=
</p></li></ul></blockquote><div style=3D"font-family:Arial;"><br></div>
<div style=3D"font-family:Arial;">There was some discussion about how to ha=
ndle RFC 8255 multipart/multilingual or other things here - whether we add =
something along the lines of "the server will choose which representation t=
o include based on the original language plus what it knows about the user'=
s preferred language" - plus of course the full information is available in=
 the bodyStructure if the client wants to be smart about it.&nbsp; This is =
also a good place for a JMAP extension which could give a more powerful que=
ry language for choosing specific parts in multipart.<br></div>
<div style=3D"font-family:Arial;"><br></div>
<blockquote type=3D"cite"><ul><li><p><b>attachedEmails</b>: <code>EmailBody=
Part[]</code> (immutable)
A list of all parts of type <code>message/rfc822</code>. Note, this <b>does=
 not</b> recurse, so the parts within these are not included. The attached =
message may be fetched using the Email/parse method and the blobId.<br></p>=
</li></ul></blockquote><div style=3D"font-family:Arial;"><br></div>
<div style=3D"font-family:Arial;">Might be worth having an example of this =
- it's going to be one of the tricky bits for people to understand.<br></di=
v>
<div style=3D"font-family:Arial;"><br></div>
<blockquote type=3D"cite"><ul><li><p><b>attachedFiles</b>: <code>EmailBodyP=
art[]</code> (immutable)
A list of all parts in <i>bodyStructure</i>, traversing depth-first, not of=
 type <code>multipart/*</code>, and not included in any of the <i>textBody<=
/i>, <i>htmlBody</i> or <i>attachedEmails</i> properties. Note, an HTML bod=
y part may reference image parts in attachedFiles using <code>cid:</code> l=
inks to reference the <i>Content-Id</i> or by referencing the <i>Content-Lo=
cation</i>.<br></p></li></ul></blockquote><div style=3D"font-family:Arial;"=
><br></div>
<div style=3D"font-family:Arial;">This could do with being a little clearer=
 that "even if referenced by an HTML body part, attached files will be incl=
uded in this list" - or something like that.<br></div>
<div style=3D"font-family:Arial;"><br></div>
<blockquote type=3D"cite"><ul><li><p><b>hasAttachment</b>: <code>Boolean</c=
ode> (immutable; server-set)
This is <code>true</code> if there are one or more parts in the message tha=
t a client UI should offer as downloadable. A server SHOULD set hasAttachme=
nt if either:<br></p><ul><li>The <i>attachedEmails</i> list contains at lea=
st one item.<br></li><li>The <i>attachedFiles</i> list contains at least on=
e item that does not have <code>Content-Disposition: attachment</code>. The=
 server MAY ignore parts in this list that are processed automatically in s=
ome way, or are referenced as embedded images in one of the <code>text/html=
</code> parts of the message.<br></li></ul></li></ul></blockquote><div styl=
e=3D"font-family:Arial;"><br></div>
<div style=3D"font-family:Arial;">It's already been noted that the logic is=
 reversed here, should be "does have" or maybe even "does not have Content-=
Disposition: inline" instead.<br></div>
<div style=3D"font-family:Arial;"><br></div>
<blockquote type=3D"cite"><ul><li><p>The server MAY set hasAttachment based=
 on implementation-defined or site configurable heuristics.<br></p></li><li=
><p><b>preview</b>: <code>String</code> (immutable; server-set)
Up to 256 characters of the beginning of a plain text version of the messag=
e body. This is intended to be shown as a preview line on a mailbox listing=
, and the server may choose to skip quoted sections or salutations to retur=
n a more useful preview.<br></p></li></ul></blockquote><div style=3D"font-f=
amily:Arial;"><br></div>
<div style=3D"font-family:Arial;">I wouldn't even say "of the beginning" - =
it's up to 256 characters that provide a good summary of the content of the=
 message.&nbsp; I would say something like: This is intended to be shown as=
 a preview line on a mailbox listing, and not all characters may be shown.&=
nbsp; The server may choose which part of the message to include in the pre=
view, for example skipping quoted sections and salutations can result in a =
more useful preview.<br></div>
<div style=3D"font-family:Arial;"><br></div>
<blockquote type=3D"cite"><p>MIME structures are arbitrary nested trees of =
documents, but the majority of email clients present a model of an email bo=
dy (normally plain text or HTML), with a set of attachments. Interpreting t=
he MIME structure to form this flat model represents considerable difficult=
y and causes inconsistency between clients. Therefore in addition to the <i=
>bodyStructure</i> property, which gives the full tree, the Email object co=
ntains 4 alternate properties with flat lists of body parts:<br></p><ul><li=
><p><i>textBody</i>/<i>htmlBody</i>: These provide a list of parts that sho=
uld be
rendered as the "body" of the message. This is a list rather than a single =
part as messages may have headers and/or footers appended/prepended as sepa=
rate parts as they are transmitted, and some clients send text and images i=
ntended to be displayed inline in the body as multiple parts rather than a =
single HTML part with referenced images.<br></p><p>Because MIME allows for =
multiple representations of the same data (using <code>multipart/alternativ=
e</code>), there is a textBody property (which prefers a plain text represe=
ntation) and an htmlBody property (which prefers an HTML representation) to=
 accommodate the two most common client requirements. The same part may app=
ear in both lists where there is no alternative between the two.<br></p></l=
i><li><p><i>attachedEmails</i>/<i>attachedFiles</i>: These provide a list o=
f parts that should
be presented as "attachments" to the message. Emails are presented in a sep=
arate list so their contents may be easily fetched via a back-reference wit=
h the <code>Email/parse</code> method in the same request, if the client wi=
shes to. Some images in attachedFiles may be solely there for embedding wit=
hin an HTML body part; clients may wish to not present these as attachments=
 in the user interface if they are displaying the HTML with the embedded im=
ages directly.<br></p></li></ul><p>The <i>bodyValues</i> property allows fo=
r clients to fetch the value of text parts directly without having to do a =
second request for the blob, and have the server handle decoding the charse=
t into unicode. This data is in a separate property rather than on the Emai=
lBodyPart object to avoid duplication of large amounts of data, as the same=
 part may be included twice if the client fetches more than one of bodyStru=
cture, textBody and htmlBody.<br></p><p>The exact algorithm for decomposing=
 bodyStructure into textBody, htmlBody, attachedEmails and attachedFiles pa=
rt lists is not mandated, as this is a quality-of-service implementation is=
sue and likely to require workarounds for malformed content discovered over=
 time.<br></p><p>However, we will define a suggested algorithm for the RFC =
to help implementors. TODO.<br></p><h2>Email/get<br></h2><p>Standard <i>/ge=
t</i> method, with the following additional arguments:<br></p><ul><li><p><b=
>bodyProperties</b>: <code>String[]</code> (optional)
A list of properties to fetch for each EmailBodyPart returned. If omitted, =
this defaults to:<br></p><p>[ "partId", "blobId", "size", "name", "type", "=
charset", "disposition", cid", "language", "location", "width", "height" ]<=
br></p></li><li><p><b>fetchTextBodyValues</b>: <code>Boolean</code> (defaul=
t: <code>false</code>)
If <code>true</code>, the <i>bodyValues</i> property includes any <code>tex=
t/*</code> part in the <code>textBody</code> property.<br></p></li><li><p><=
b>fetchHTMLBodyValues</b>: <code>Boolean</code> (default: <code>false</code=
>)
If <code>true</code>, the <i>bodyValues</i> property includes any <code>tex=
t/*</code> part in the <code>htmlBody</code> property.<br></p></li><li><p><=
b>fetchAllBodyValues</b>: <code>Boolean</code> (default: <code>false</code>)
If <code>true</code>, the <i>bodyValues</i> property includes any <code>tex=
t/*</code> part in the <code>bodyStructure</code> property.<br></p></li><li=
><p><b>maxBodyValueBytes</b>: <code>Number</code> (optional)
If supplied by the client, the value MUST be a positive integer greater tha=
n 0. If a value outside of this range is given, the server MUST reject the =
call with an <code>invalidArguments</code> error. When given, the <i>value<=
/i> property of any EmailBodyValue object returned in <i>bodyValues</i> MUS=
T be truncated if necessary so it does not exceed this number of bytes in s=
ize. The server MUST ensure the truncation results in valid UTF-8 and does =
not occur mid-codepoint. If the part is of type <code>text/html</code>, the=
 server SHOULD NOT truncate inside an HTML tag.<br></p></li></ul><p>If the =
standard <i>properties</i> argument is omitted or <code>null</code>, the fo=
llowing default MUST be used instead of "all" properties:<br></p><pre><code=
>[ "id", "blobId", "threadId", "mailboxIds", "keywords", "size", "receivedA=
t", "sender", "from", "to", "cc", "bcc", "replyTo", "subject", "sentAt", "h=
asAttachment", "preview", "bodyValues", "textBody", "htmlBody", "attachedFi=
les", "attachedEmails" ]
</code><br></pre><p>The following properties are expected to be fast to fet=
ch in a quality implementation:<br></p><ul><li>id<br></li><li>blobId<br></l=
i><li>threadId<br></li><li>mailboxIds<br></li><li>keywords<br></li><li>size=
<br></li><li>receivedAt<br></li><li>sender<br></li><li>from<br></li><li>to<=
br></li><li>cc<br></li><li>bcc<br></li><li>replyTo<br></li><li>subject<br><=
/li><li>sentAt<br></li><li>hasAttachment<br></li><li>preview<br></li></ul><=
p>Clients SHOULD take care when fetching any other properties, as there may=
 be significantly longer latency in fetching and returning the data.<br></p=
><h3>Example<br></h3><p>Request:<br></p><pre><code>["Email/get", {
  "ids": [ "f123u456", "f123u457" ],
  "properties": [ "threadId", "mailboxIds", "from", "subject", "receivedAt"=
, "htmlBody", "bodyValues" ],
  "bodyProperties": [ "partId", "blobId", "size", "type" ],
  "fetchHTMLBodyValues": true,
  "maxBodyValueBytes": 256
}, "#1"]
</code><br></pre><p>and response:<br></p><pre><code>["Email/get", {
  "accountId": "abc",
  "state": "41234123231",
  "list": [
    {
      "id": "f123u457",
      "threadId": "ef1314a",
      "mailboxIds": { "f123": true },
      "from": [{name: "Joe Bloggs", email: "joe@bloggs.com"}],
      "subject": "Dinner on Thursday?",
      "receivedAt": "2013-10-13T14:12:00Z",
      "htmlBody": [{
        "partId": "1",
        "blobId": "841623871",
        "size": 283331,
        "type": "text/html"
      }, {
        "partId": "2",
        "blobId": "319437193",
        "size": 10343,
        "type": "text/plain"
      }],
      "bodyValues": {
        "1": {
          "isTruncated": true,
          "value": "&lt;html&gt;&lt;body&gt;&lt;p&gt;Hello ..."
        },
        "2": {
          "isTruncated": false,
          "value": "-- \nSent by your friendly mailing list ..."
        }
      }
    }
  ],
  notFound: [ "f123u456" ]
}, "#1"]
</code><br></pre><div><br></div>
<div><u>_______________________________________________</u><br></div>
<div>Jmap mailing list<br></div>
<div><a href=3D"mailto:Jmap@ietf.org">Jmap@ietf.org</a><br></div>
<div><a href=3D"https://www.ietf.org/mailman/listinfo/jmap">https://www.iet=
f.org/mailman/listinfo/jmap</a><br></div>
</blockquote><div style=3D"font-family:Arial;"><br></div>
<div id=3D"sig56629417"><div class=3D"signature">--<br></div>
<div class=3D"signature">&nbsp; Bron Gondwana, CEO, FastMail Pty Ltd<br></d=
iv>
<div class=3D"signature">&nbsp; brong@fastmailteam.com<br></div>
<div class=3D"signature"><br></div>
</div>
<div style=3D"font-family:Arial;"><br></div>
</body>
</html>

--_----------=_151840850716997411--


From nobody Sun Feb 11 23:06:00 2018
Return-Path: <neilj@fastmailteam.com>
X-Original-To: jmap@ietfa.amsl.com
Delivered-To: jmap@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 29652126CF6 for <jmap@ietfa.amsl.com>; Sun, 11 Feb 2018 23:05:59 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.72
X-Spam-Level: 
X-Spam-Status: No, score=-2.72 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=fastmailteam.com header.b=V17zqsQ9; dkim=pass (2048-bit key) header.d=messagingengine.com header.b=hAaDV9le
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id iRmOcDRInO3t for <jmap@ietfa.amsl.com>; Sun, 11 Feb 2018 23:05:55 -0800 (PST)
Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id C4036124BE8 for <jmap@ietf.org>; Sun, 11 Feb 2018 23:05:55 -0800 (PST)
Received: from betaweb1.internal (betaweb1.nyi.internal [10.202.2.10]) by mailout.nyi.internal (Postfix) with ESMTP id 1869320A47; Mon, 12 Feb 2018 02:05:55 -0500 (EST)
Received: from betaweb1 ([::ffff:10.202.2.10]) by betaweb1.internal (MEProxy); Mon, 12 Feb 2018 02:05:55 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= fastmailteam.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=J8cID/ taIvWd5JxJJS/2uLpHDqtfuLEK5EkSfwdUI6U=; b=V17zqsQ9hGO54+tseEkocU kMPQysFoQHe5NilVdRgqY/lSDfhToiIoS4cgPqW1RdEKCjizM8BDg57LSuyScoF5 ix75ttZhfjFLie9UCi8/IZRngouJ0qCuvfunOZuE7mE751hGsVobz5wmtZ6U+tHx XQvoaPWe9Bh5zk7vvKdqqpkXOAFd7C+bQyJX2VWc4g6UoLqAfDXdubQ+3skFCsAr rqYHJsgO8CCA9bQV7C6JXi9YUhzvCRXaYAjKKJz+P6GSFAJS7RvE6eVl0ZqpIAD5 Dx9rf0jLygVCfg5IAAurblEV16kxDbTg+CiOp83uIXQmCFmtvSH5PUJDaLxMU7dA ==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; bh=J8cID/ taIvWd5JxJJS/2uLpHDqtfuLEK5EkSfwdUI6U=; b=hAaDV9le7mfYbHSHtOdCVy LxWuCflvttGGNf5A5qS+/zJU8VhMjBWgW4ZKsts60KG90i2kTBrb4UGwZP7erITI 8SqSVYCQTlJ29HNnKoZ8zaopjJ+dRLh2XgrWY9Rk3aHlA3IfpN1KIYrVpPw/bkdO xpaiK6DQlZEE5fmv+3PspBCAMuVvCamsRr54tRugskaOZ8vGIP9x+XYkufhJ15eQ 92x3eR5fhfncGJa7f/gAZuYI3lJOLb35ae8hFTWE46iah6Vwk0XU0P8S1roX5v/V igm4nvvn8Rkw/BQZdJINJj21CX5XLdNJP/ZRtMf3VLyJMIz/OupJCgpK5ia/qfqg ==
X-ME-Sender: <xms:0jyBWr-nCa-esUEVjJ_uG58MIwCydH7fdVT5ltunDA5nCVBlE-gGGA>
Received: by mailuser.nyi.internal (Postfix, from userid 99) id B27A3E21FA; Mon, 12 Feb 2018 02:05:54 -0500 (EST)
Message-Id: <1518419154.999872.1267587168.461E9F6F@webmail.messagingengine.com>
From: Neil Jenkins <neilj@fastmailteam.com>
To: Chris Newman <chris.newman@oracle.com>
Cc: IETF JMAP Mailing List <jmap@ietf.org>
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Type: multipart/alternative; boundary="_----------=_15184191549998720"
X-Mailer: MessagingEngine.com Webmail Interface - ajax-2ce04827
Date: Mon, 12 Feb 2018 18:05:54 +1100
References: <1518070284.168650.1263633200.05C7397A@webmail.messagingengine.com> <500E0B79-200E-4DFA-939A-C3419559743E@oracle.com>
In-Reply-To: <500E0B79-200E-4DFA-939A-C3419559743E@oracle.com>
Archived-At: <https://mailarchive.ietf.org/arch/msg/jmap/1kJ4Yu3Pg1e3MWGmcXMax7iM5qQ>
Subject: Re: [Jmap] New JSON message representation
X-BeenThere: jmap@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: JSON Message Access Protocol <jmap.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/jmap>, <mailto:jmap-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/jmap/>
List-Post: <mailto:jmap@ietf.org>
List-Help: <mailto:jmap-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/jmap>, <mailto:jmap-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 12 Feb 2018 07:05:59 -0000

This is a multi-part message in MIME format.

--_----------=_15184191549998720
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset="utf-8"

Thanks for the great feedback!

> I concur with Alexey's comment about keywords being case-insensitive.
I've changed it so they are case-insensitive but the server MUST
return them lower-cased (as JSON is case-sensitive and it's a pain to
have to iterate through keys in an object rather than be able to do a
direct lookup).
> On 7 Feb 2018, at 22:11, Neil Jenkins wrote:
>> * **size**: Number (immutable; server-set) The size in bytes of the
>> whole
>>   email as counted by the server towards the user's quota.
> 
> The problem with a quota-based size measurement is "0" is a reasonable> answer for single-copy message stores that allow multiple Email
> objects> that refer to the same message (particularly if a reference to the
> message in a trash folder is not the only reference).

Yep, this is also inconsistent with everywhere else there are
blobId/size properties on an object. I've changed it so it's the size
of the file you get if you download the blob (i.e. the size of the
RFC5322 message), which is then consistent with the rest of the spec
and with IMAP.
>> * **receivedAt**: UTCDate
> I note the IMAP APPEND command allows this to be client-specified.

This is also already client-specifiable in JMAP (see the Email/import
method, which is the equivalent of APPEND). It's just the *default*
that's the time the message is inserted in the mail store if no other
date is supplied.
>> These properties are derived from the [@!RFC5322] message header
>> fields.
> It's also fine to allow [@!RFC6532] message header fields, I believe.
Yep, I'll note this in the spec.

>> * **Decoded** The header field value with:
>>   1. White space unfolded (as defined in [@!RFC5322] section 2.2.3)
>>   2. The terminating CRLF at the end of the value removed
>>   3. Any SP characters at the beginning of the value removed
>>   4. Any [@!RFC2047] encoded sections decoded
> 
> This is a security design error. I suggest:
> 
> Any syntactically correct [@!RFC2047] encoded sections with a known
> character set are decoded and re-encoded as a UTF-8 string with proper> quoting and escaping for the active RFC 5322 syntactic context
> appropriate for the specific header field. Any [@!RFC2047] encoded NUL> octets or control characters are dropped from the decoded value. Any
> text that looks like [@!RFC2047] syntax but violates [@!RFC2047]
> placement or whitespace rules MUST NOT be decoded. Any [@!RFC2047]
> content in an unrecognized header MUST NOT be decoded. Same
> rules apply> to [@!RFC2231] decoding.

Yes, looking at this again we have come to the conclusion that allowing
clients to request arbitrary headers be parsed in arbitrary forms is
allowing them to shoot themselves in the foot too much, and going to
lead to security and/or interoperability errors.
My new suggestion:
 * Raw form doesn't base64 (as you say, any standards-compliant email
   should be valid ASCII or UTF-8), and becomes the default, and the
   only form in which you can request any header.
 * A number of parsed forms are defined. These may only be fetched/set
   for appropriate header fields from RFC5322 or fields not defined in
   this spec (which allows for more future proofing, if someone defines
   a new header field that contains a date for example).I'll send another email with the full revised spec shortly.

> We might also want to add 6. require the server to convert
> denormalized> Unicode to NFC. This is easy enough for a server to do and makes it
> easier for clients to comply with RFC 5198.

Seems reasonable.

>> * **Addresses** The header is parsed as an address-list value, as
>>   specified in [@!RFC5322] section 3.4, into the EmailAddress[] type.>>   The **EmailAddress** object has the following properties:
>> 
>> 
>>   * **name**: String|null The *display name* of the [@!RFC5322]
>> **mailbox**
>>     or **group**, or null if none.
> 
> It's important for 2047 decoding (as described previously) to
> be applied> to this when possible.

Yes, this was meant to be the case, looks like I missed specifying that.
>> EmailAddress objects MAY have an **email** property that
>> does not conform to the **addr-spec** form (for example, may not
>> contain an @ symbol).> Should this allow non-punycode IDN? 

I think the value there should be automatically converted to or from
punycode, but other than that I don't think we should be rejecting
anything, just doing best-effort parsing into a form that's easier for
the client to handle. The client can convert or analyse for phishing
issues with the domain.
> Should this allow RFC 6532?

Yes, I've now noted this.

>> * **name**: String|null This is the [@!RFC2231] decoded **filename**>>   parameter of the **Content-Disposition** header field, or (for
>>   compatibility with existing systems) if not present then the
>>   [@!RFC2047] decoded **name** property of the **Content-Type**
>>   header>>   field. For compatibility with the widest array of existing systems,>>   both forms should be set if creating a message.
> 
> I think this is the wrong place to include rules for generating
> email. I> note that setting a "name" parameter on a MIME content type which
> doesn't explicitly register a "name" parameter is a violation of the
> MIME model. Advice to violate the model may be fine as an
> implementation> suggestion, but I wouldn't make it a standards-level recommendation.

OK. I'll remove the last sentence and add a note to the server
implementation guide[1].
>> * **type**: String The value of the **Content-Type** header field
>>   of the>>   part, excluding any parameters.
> Should this have CFWS removed? I think it should.

Yes.

>> * **bodyStructure**: EmailBodyPart[] (immutable) This is the
>>   full MIME>>   structure of the message body, including sub parts but not
>> recursing
>>   into message/rfc822 parts.
> make that "message/rfc822 or message/global parts."

Yep.

>>   * **value**: String The value of the body part after decoding
>> *Content-
>>     Transport* encoding and decoding the **Content-Type** charset.
> 
> I think you mean **Content-Transfer-Encoding**, and decoding it
> is fine.> Decoding the charset unconditionally in this way violates the
> MIME model> as the charset parameter has no strictly defined meaning outside the
> top-level text media-type.
> 
> I think there are three design options here:
> 1. CTE only
> 2. CTE, plus charset decoding of text/ and other recognized media
>    types> the server knows have a registered and defined meaning for charset.

The bodyValues property is *only* used to return text/* parts.
(Anything else, the client has to download the blob, which does CTE
decoding only).
> 3. allow the server to be helpful and briefly describe what it did.
> 
> If you choose option 3, I'd add a third "decodingKind" field to
> EmailBodyValue that explains the value.

I feel this is overkill. The main purpose of this property is to let
clients fetch the message text/html body without having to deal with
charset decoding. I think what we want here are:
1. A best-effort decoded value.
2. A flag to tell the client if the charset was unknown, or invalid data
   was found for the charset. The client can then choose what to do
   (download the blob and try to decode it itself, or more likely show a
   warning to the user that the message may display incorrectly, or even
   just not show the message at all and  say it could not be
   understood).
With that in mind, here's a new suggestion:

An *EmailBodyValue* object has the following properties:

 * *value*: String The value of the body part after decoding *Content-Transport-
   Encoding* and decoding the *Content-Type* charset, if known to the
   server. The server MAY use heuristics to determine the charset to use
   for decoding if the charset is unknown, or if no charset is given, or
   if it believes the charset given is incorrect. Decoding is best-
   effort and SHOULD insert the unicode replacement character (U+FFFD)
   and continue when a malformed section is encountered.
 * *isEncodingProblem*: Boolean This is true if malformed sections were
   found while decoding the charset, or the charset was unknown.
 * *isTruncated*: Boolean This is true if the *value* has been
   truncated.
>> * **attachedEmails**: EmailBodyPart[] (immutable) A list of all parts>> of  type message/rfc822. Note, this *does not* recurse, so the parts> or type message/global.

Yes

>>   * The **attachedFiles** list contains at least one item that does
>>     not>>     have Content-Disposition: attachment. The server MAY ignore parts> I think you mean "Content-Disposition: inline".

Oops, yes.

Neil.

Links:

  1. http://jmap.io/server.html

--_----------=_15184191549998720
Content-Transfer-Encoding: 7bit
Content-Type: text/html; charset="utf-8"

<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">p.MsoNormal,p.MsoNoSpacing{margin:0}</style>
</head>
<body><div>Thanks for the great feedback!<br></div>
<div><br></div>
<blockquote type="cite"><div>I concur with Alexey's comment about keywords being case-insensitive.<br></div>
</blockquote><div><br></div>
<div>I've changed it so they are case-insensitive but the server MUST return them lower-cased (as JSON is case-sensitive and it's a pain to have to iterate through keys in an object rather than be able to do a direct lookup).<br></div>
<div><br></div>
<blockquote type="cite"><div>On 7 Feb 2018, at 22:11, Neil Jenkins wrote:<br></div>
<blockquote><div>* <b>*size*</b>: Number (immutable; server-set) The size in bytes of the<br></div>
<div>whole<br></div>
<div>&nbsp; email as counted by the server towards the user's quota.<br></div>
</blockquote><div><br></div>
<div>The problem with a quota-based size measurement is "0" is a reasonable<br></div>
<div>answer for single-copy message stores that allow multiple Email objects<br></div>
<div>that refer to the same message (particularly if a reference to the<br></div>
<div>message in a trash folder is not the only reference).<br></div>
</blockquote><div><br></div>
<div>Yep, this is also inconsistent with everywhere else there are blobId/size properties on an object. I've changed it so it's the size of the file you get if you download the blob (i.e. the size of the RFC5322 message), which is then consistent with the rest of the spec and with IMAP.<br></div>
<div><br></div>
<blockquote type="cite"><blockquote><div>* <b>*receivedAt*</b>: UTCDate<br></div>
</blockquote><div>I note the IMAP APPEND command allows this to be client-specified.<br></div>
</blockquote><div><br></div>
<div>This is also already client-specifiable in JMAP (see the Email/import method, which is the equivalent of APPEND). It's just the <i>default</i> that's the time the message is inserted in the mail store if no other date is supplied.<br></div>
<div><br></div>
<blockquote type="cite"><blockquote><div>These properties are derived from the [@!RFC5322] message header<br></div>
<div>fields.<br></div>
</blockquote><div>It's also fine to allow [@!RFC6532] message header fields, I believe.<br></div>
</blockquote><div><br></div>
<div>Yep, I'll note this in the spec.<br></div>
<div><br></div>
<blockquote type="cite"><blockquote><div>* <b>*Decoded*</b> The header field value with:<br></div>
<div>&nbsp; 1. White space unfolded (as defined in [@!RFC5322] section 2.2.3)<br></div>
<div>&nbsp; 2. The terminating CRLF at the end of the value removed<br></div>
<div>&nbsp; 3. Any SP characters at the beginning of the value removed<br></div>
<div>&nbsp; 4. Any [@!RFC2047] encoded sections decoded<br></div>
</blockquote><div><br></div>
<div>This is a security design error. I suggest:<br></div>
<div><br></div>
<div>Any syntactically correct [@!RFC2047] encoded sections with a known<br></div>
<div>character set are decoded and re-encoded as a UTF-8 string with proper<br></div>
<div>quoting and escaping for the active RFC 5322 syntactic context<br></div>
<div>appropriate for the specific header field. Any [@!RFC2047] encoded NUL<br></div>
<div>octets or control characters are dropped from the decoded value. Any<br></div>
<div>text that looks like [@!RFC2047] syntax but violates [@!RFC2047]<br></div>
<div>placement or whitespace rules MUST NOT be decoded. Any [@!RFC2047]<br></div>
<div>content in an unrecognized header MUST NOT be decoded. Same rules apply<br></div>
<div>to [@!RFC2231] decoding.<br></div>
</blockquote><div><br></div>
<div>Yes, looking at this again we have come to the conclusion that allowing clients to request arbitrary headers be parsed in arbitrary forms is allowing them to shoot themselves in the foot too much, and going to lead to security and/or interoperability errors.<br></div>
<div><br></div>
<div>My new suggestion:<br></div>
<ul><li>Raw form doesn't base64 (as you say, any standards-compliant email should be valid ASCII or UTF-8), and becomes the default, and the only form in which you can request any header.<br></li><li>A number of parsed forms are defined. These may only be fetched/set for appropriate header fields from RFC5322 or fields not defined in this spec (which allows for more future proofing, if someone defines a new header field that contains a date for example).<br></li></ul><div>I'll send another email with the full revised spec shortly.</div>
<div><br></div>
<blockquote type="cite"><div>We might also want to add 6. require the server to convert denormalized<br></div>
<div>Unicode to NFC. This is easy enough for a server to do and makes it<br></div>
<div>easier for clients to comply with RFC 5198.<br></div>
</blockquote><div><br></div>
<div>Seems reasonable.<br></div>
<div><br></div>
<blockquote><blockquote><div>* <b>*Addresses*</b> The header is parsed as an address-list value, as<br></div>
<div>&nbsp; specified in [@!RFC5322] section 3.4, into the EmailAddress[] type.<br></div>
<div>&nbsp; The <b>*EmailAddress*</b> object has the following properties:<br></div>
<div><br></div>
<div><br></div>
<div>&nbsp; * <b>*name*</b>: String|null The *display name* of the [@!RFC5322]<br></div>
<div><b>*mailbox*</b><br></div>
<div>&nbsp; &nbsp; or <b>*group*</b>, or null if none.<br></div>
</blockquote><div><br></div>
<div>It's important for 2047 decoding (as described previously) to be applied<br></div>
<div>to this when possible.<br></div>
</blockquote><div><br></div>
<div>Yes, this was meant to be the case, looks like I missed specifying that.<br></div>
<div><br></div>
<blockquote><blockquote><div>EmailAddress objects MAY have an <b>*email*</b> property that<br></div>
<div>does not conform to the <b>*addr-spec*</b> form (for example, may not contain an @ symbol).<br></div>
</blockquote><div>Should this allow non-punycode IDN? <br></div>
</blockquote><div><br></div>
<div>I think the value there should be automatically converted to or from punycode, but other than that I don't think we should be rejecting anything, just doing best-effort parsing into a form that's easier for the client to handle. The client can convert or analyse for phishing issues with the domain.<br></div>
<div><br></div>
<blockquote><div>Should this allow RFC 6532?<br></div>
</blockquote><div><br></div>
<div>Yes, I've now noted this.<br></div>
<div><br></div>
<blockquote><blockquote><div>* <b>*name*</b>: String|null This is the [@!RFC2231] decoded <b>*filename*</b><br></div>
<div>&nbsp; parameter of the <b>*Content-Disposition*</b> header field, or (for<br></div>
<div>&nbsp; compatibility with existing systems) if not present then the<br></div>
<div>&nbsp; [@!RFC2047] decoded <b>*name*</b> property of the <b>*Content-Type*</b> header<br></div>
<div>&nbsp; field. For compatibility with the widest array of existing systems,<br></div>
<div>&nbsp; both forms should be set if creating a message.<br></div>
</blockquote><div><br></div>
<div>I think this is the wrong place to include rules for generating email. I<br></div>
<div>note that setting a "name" parameter on a MIME content type which<br></div>
<div>doesn't explicitly register a "name" parameter is a violation of the<br></div>
<div>MIME model. Advice to violate the model may be fine as an implementation<br></div>
<div>suggestion, but I wouldn't make it a standards-level recommendation.<br></div>
</blockquote><div><br></div>
<div>OK. I'll remove the last sentence and add a note to the <a href="http://jmap.io/server.html">server implementation guide</a>.<br></div>
<div><br></div>
<blockquote><blockquote><div>* <b>*type*</b>: String The value of the <b>*Content-Type*</b> header field of the<br></div>
<div>&nbsp; part, excluding any parameters.<br></div>
</blockquote><div>Should this have CFWS removed? I think it should.<br></div>
</blockquote><div><br></div>
<div>Yes.<br></div>
<div><br></div>
<blockquote><blockquote><div>* <b>*bodyStructure*</b>: EmailBodyPart[] (immutable) This is the full MIME<br></div>
<div>&nbsp; structure of the message body, including sub parts but not<br></div>
<div>recursing<br></div>
<div>&nbsp; into message/rfc822 parts.<br></div>
</blockquote><div>make that "message/rfc822 or message/global parts."<br></div>
</blockquote><div><br></div>
<div>Yep.<br></div>
<div><br></div>
<blockquote><blockquote><div>&nbsp; * <b>*value*</b>: String The value of the body part after decoding<br></div>
<div>*Content-<br></div>
<div>&nbsp; &nbsp; Transport* encoding and decoding the <b>*Content-Type*</b> charset.<br></div>
</blockquote><div><br></div>
<div>I think you mean <b>*Content-Transfer-Encoding*</b>, and decoding it is fine.<br></div>
<div>Decoding the charset unconditionally in this way violates the MIME model<br></div>
<div>as the charset parameter has no strictly defined meaning outside the<br></div>
<div>top-level text media-type.<br></div>
<div><br></div>
<div>I think there are three design options here:<br></div>
<div>1. CTE only<br></div>
<div>2. CTE, plus charset decoding of text/ and other recognized media types<br></div>
<div>the server knows have a registered and defined meaning for charset.<br></div>
</blockquote><div><br></div>
<div>The bodyValues property is <i>only</i> used to return text/* parts. (Anything else, the client has to download the blob, which does CTE decoding only).<br></div>
<div><br></div>
<blockquote><div>3. allow the server to be helpful and briefly describe what it did.<br></div>
<div><br></div>
<div>If you choose option 3, I'd add a third "decodingKind" field to<br></div>
<div>EmailBodyValue that explains the value.<br></div>
</blockquote><div><br></div>
<div>I feel this is overkill. The main purpose of this property is to let clients fetch the message text/html body without having to deal with charset decoding. I think what we want here are:<br></div>
<div><br></div>
<div>1. A best-effort decoded value.<br></div>
<div>2. A flag to tell the client if the charset was unknown, or invalid data was found for the charset. The client can then choose what to do (download the blob and try to decode it itself, or more likely show a warning to the user that the message may display incorrectly, or even just not show the message at all and  say it could not be understood).<br></div>
<div><br></div>
<div>With that in mind, here's a new suggestion:<br></div>
<div><br></div>
<div>An <b>EmailBodyValue</b> object has the following properties:<br></div>
<div><br></div>
<ul><li><b>value</b>: String<br>The value of the body part after decoding <i>Content-Transport-Encoding</i>&nbsp;and decoding the <i>Content-Type</i> charset, if known to the server. The server MAY use heuristics to determine the charset to use for decoding if the charset is unknown, or if no charset is given, or if it believes the charset given is incorrect. Decoding is best-effort and SHOULD insert the unicode replacement character (U+FFFD) and continue when a malformed section is encountered.<br></li><li><b>isEncodingProblem</b>: Boolean<br>This is true if malformed sections were found while decoding the charset, or the charset was unknown.<br></li><li><b>isTruncated</b>: Boolean<br>This is true if the *value* has been truncated.</li></ul><div><br></div>
<blockquote><blockquote><div>* <b>*attachedEmails*</b>: EmailBodyPart[] (immutable) A list of all parts<br></div>
<div>of&nbsp; type message/rfc822. Note, this *does not* recurse, so the parts<br></div>
</blockquote><div>or type message/global.<br></div>
</blockquote><div><br></div>
<div>Yes<br></div>
<div><br></div>
<blockquote><blockquote><div>&nbsp; * The <b>*attachedFiles*</b> list contains at least one item that does not<br></div>
<div>&nbsp; &nbsp; have Content-Disposition: attachment. The server MAY ignore parts<br></div>
</blockquote><div>I think you mean "Content-Disposition: inline".<br></div>
</blockquote><div><br></div>
<div>Oops, yes.<br></div>
<div><br></div>
<div>Neil.<br></div>
</body>
</html>

--_----------=_15184191549998720--


From nobody Sun Feb 11 23:15:13 2018
Return-Path: <neilj@fastmailteam.com>
X-Original-To: jmap@ietfa.amsl.com
Delivered-To: jmap@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id BFA62126CD8 for <jmap@ietfa.amsl.com>; Sun, 11 Feb 2018 23:15:10 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.72
X-Spam-Level: 
X-Spam-Status: No, score=-2.72 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=fastmailteam.com header.b=UqQ1qTDF; dkim=pass (2048-bit key) header.d=messagingengine.com header.b=PJTpl5uC
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id hB-YvD6XE5El for <jmap@ietfa.amsl.com>; Sun, 11 Feb 2018 23:15:09 -0800 (PST)
Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 2176A124BE8 for <jmap@ietf.org>; Sun, 11 Feb 2018 23:15:09 -0800 (PST)
Received: from betaweb1.internal (betaweb1.nyi.internal [10.202.2.10]) by mailout.nyi.internal (Postfix) with ESMTP id 8A3602090A for <jmap@ietf.org>; Mon, 12 Feb 2018 02:15:08 -0500 (EST)
Received: from betaweb1 ([::ffff:10.202.2.10]) by betaweb1.internal (MEProxy); Mon, 12 Feb 2018 02:15:08 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= fastmailteam.com; h=content-transfer-encoding:content-type:date :from:in-reply-to:message-id:mime-version:references:subject:to :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=MTVAlGiyTBVxYkEbZ 8NVHcUvKMGgbW1bTg9nXo9KfnY=; b=UqQ1qTDFfQ/5P8iRlNxzYA/sFA0q9TUnv Xt0Q+1+oKsV/5+/YUe6DCvwogzUP49Ovyyo71rc2+ISrV474izS1GcVGFGfhU99e +L/DVYmHQKHvOX5T7oHk0q0ciQoivuOiHxOEb2UbFcZM1twGPnTxQ3Tqg0PeMHAb cHuFZeX9QxrSbFPyFApAONB88FR3DuEtBjVgfiP7dXjmueGFidpZXnpLPAteYVok HFFh9+cA0goB/aPDfa08gRIEEkD8rGU8GcgaqqdZIckuxp7BTWEgd+XYK1G1bSbo 4/Z6a+MGME7gbxzdq0+ETuBplIt6gmxyXzgMAzkcA0AcDxGZIxBJw==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; bh=MTVAlG iyTBVxYkEbZ8NVHcUvKMGgbW1bTg9nXo9KfnY=; b=PJTpl5uCe5bFJ51EJQuE6l nlTnezMAQOijbxQUSXz7K3yiCHXuRVYyB/267UMEepo/bV8g0THBQZK8bjuGaDhZ 0KD7CXx9tXkONAwVlCNFy1KmBrgmQbSHREGmCRh+PIJuBO3//gdmQfb+qWaa7gCd p/W4RXb97BcvQDqbj25C3vSyS3YlvyctdofGgFlwxN/RfylomlF3YzzB7/+2CYbO XqP6BAjk1WjshETvvxRpyMHri18rwJPl8JxhCBUpbj6TsJz1dN4RdyYHZ6oNFCI6 /at+0o6ck4dQ10dbgS+BALOw2nx2AH3WAJvYrC5bM/WkAFrehVdrdMu/yAV+PXOQ ==
X-ME-Sender: <xms:_D6BWlY3YjyCBVS9oDHRzpu2f2pGpPXxhxY5CRacYRdNmaNvMvB0eg>
Received: by mailuser.nyi.internal (Postfix, from userid 99) id 47C02E2479; Mon, 12 Feb 2018 02:15:08 -0500 (EST)
Message-Id: <1518419708.1006757.1267595536.799BEEC0@webmail.messagingengine.com>
From: Neil Jenkins <neilj@fastmailteam.com>
To: IETF JMAP Mailing List <jmap@ietf.org>
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Type: multipart/alternative; boundary="_----------=_151841970810067573"
X-Mailer: MessagingEngine.com Webmail Interface - ajax-2ce04827
In-Reply-To: <1518408506.1699741.1267466096.17DCF605@webmail.messagingengine.com>
References: <1518070284.168650.1263633200.05C7397A@webmail.messagingengine.com> <1518408506.1699741.1267466096.17DCF605@webmail.messagingengine.com>
Date: Mon, 12 Feb 2018 18:15:08 +1100
Archived-At: <https://mailarchive.ietf.org/arch/msg/jmap/ywbaSeeRM6JDVfYUb2BcBKy-mh8>
Subject: Re: [Jmap] New JSON message representation
X-BeenThere: jmap@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: JSON Message Access Protocol <jmap.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/jmap>, <mailto:jmap-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/jmap/>
List-Post: <mailto:jmap@ietf.org>
List-Help: <mailto:jmap-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/jmap>, <mailto:jmap-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 12 Feb 2018 07:15:11 -0000

This is a multi-part message in MIME format.

--_----------=_151841970810067573
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset="utf-8"

On Mon, 12 Feb 2018, at 3:08 PM, Bron Gondwana wrote:
> did we want to talk about $HasAttachment and friend as well?

I believe it is worthwhile having a hasAttachment property in JMAP
despite the existence of this keyword, because the keyword is not
guaranteed to be set when appropriate, so the client cannot rely on it,
and it's an important feature for building a good client.
> I don't know enough about the group syntax, but I thought it was
> nestable in a way that makes it hard to flatten.
No, if you look at the syntax[1], you can't nest groups.

> This does seem to mean that it's impossible to ask for all instances
> of a particular named header.  You either get the whole lot, or you
> get just the last of a particular named one.  I don't know that it's
> likely to be a big problem, but I do note the limitation.
I think this is still a reasonable balance between power and complexity.
>>  * *attachedEmails*: EmailBodyPart[] (immutable) A list of all parts
>>    of type message/rfc822. Note, this *does not* recurse, so the
>>    parts within these are not included. The attached message may be
>>    fetched using the Email/parse method and the blobId.> 
> Might be worth having an example of this - it's going to be one of the
> tricky bits for people to understand.
Yeh, we need a lot more examples in general.

>>  * *attachedFiles*: EmailBodyPart[] (immutable) A list of all parts
>>    in *bodyStructure*, traversing depth-first, not of type
>>    multipart/*, and not included in any of the *textBody*, *htmlBody*
>>    or *attachedEmails* properties. Note, an HTML body part may
>>    reference image parts in attachedFiles using cid: links to
>>    reference the *Content-Id* or by referencing the *Content-
>>    Location*.> 
> This could do with being a little clearer that "even if referenced by
> an HTML body part, attached files will be included in this list" - or
> something like that.
I'm not sure I think that's clearer than the current description. 

>>  * *preview*: String (immutable; server-set) Up to 256 characters of
>>    the beginning of a plain text version of the message body. This is
>>    intended to be shown as a preview line on a mailbox listing, and
>>    the server may choose to skip quoted sections or salutations to
>>    return a more useful preview.> 
> I wouldn't even say "of the beginning" - it's up to 256 characters
> that provide a good summary of the content of the message.  I would
> say something like: This is intended to be shown as a preview line on
> a mailbox listing, and not all characters may be shown.  The server
> may choose which part of the message to include in the preview, for
> example skipping quoted sections and salutations can result in a more
> useful preview.
Yep, good point, I've updated this.

Neil.

Links:

  1. https://tools.ietf.org/html/rfc5322#section-3.4

--_----------=_151841970810067573
Content-Transfer-Encoding: 7bit
Content-Type: text/html; charset="utf-8"

<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">p.MsoNormal,p.MsoNoSpacing{margin:0}</style>
</head>
<body><div>On Mon, 12 Feb 2018, at 3:08 PM, Bron Gondwana wrote:<br></div>
<blockquote type="cite"><div style="font-family:Arial;">did we want to talk about $HasAttachment and friend as well?<br></div>
</blockquote><div><br></div>
<div>I believe it is worthwhile having a hasAttachment property in JMAP despite the existence of this keyword, because the keyword is not guaranteed to be set when appropriate, so the client cannot rely on it, and it's an important feature for building a good client.<br></div>
<div><br></div>
<blockquote type="cite"><div style="font-family:Arial;">I don't know enough about the group syntax, but I thought it was nestable in a way that makes it hard to flatten.<br></div>
</blockquote><div><br></div>
<div>No, if you look at <a href="https://tools.ietf.org/html/rfc5322#section-3.4">the syntax</a>, you can't nest groups.<br></div>
<div><br></div>
<blockquote type="cite"><div>This does seem to mean that it's impossible to ask for all instances of a particular named header.&nbsp; You either get the whole lot, or you get just the last of a particular named one.&nbsp; I don't know that it's likely to be a big problem, but I do note the limitation.<br></div>
</blockquote><div><br></div>
<div>I think this is still a reasonable balance between power and complexity.</div>
<div><br></div>
<blockquote type="cite"><blockquote type="cite"><ul><li><p><b>attachedEmails</b>: <code>EmailBodyPart[]</code> (immutable)
A list of all parts of type <code>message/rfc822</code>. Note, this <b>does not</b> recurse, so the parts within these are not included. The attached message may be fetched using the Email/parse method and the blobId.<br></p></li></ul></blockquote><div style="font-family:Arial;"><br></div>
<div style="font-family:Arial;">Might be worth having an example of this - it's going to be one of the tricky bits for people to understand.<br></div>
</blockquote><div><br></div>
<div>Yeh, we need a lot more examples in general.<br></div>
<div><br></div>
<blockquote type="cite"><blockquote type="cite"><ul><li><p><b>attachedFiles</b>: <code>EmailBodyPart[]</code> (immutable)
A list of all parts in <i>bodyStructure</i>, traversing depth-first, not of type <code>multipart/*</code>, and not included in any of the <i>textBody</i>, <i>htmlBody</i> or <i>attachedEmails</i> properties. Note, an HTML body part may reference image parts in attachedFiles using <code>cid:</code> links to reference the <i>Content-Id</i> or by referencing the <i>Content-Location</i>.<br></p></li></ul></blockquote><div style="font-family:Arial;"><br></div>
<div style="font-family:Arial;">This could do with being a little clearer that "even if referenced by an HTML body part, attached files will be included in this list" - or something like that.<br></div>
</blockquote><div><br></div>
<div>I'm not sure I think that's clearer than the current description.&nbsp;</div>
<div><br></div>
<blockquote type="cite"><blockquote type="cite"><ul><li><p><b>preview</b>: <code>String</code> (immutable; server-set)
Up to 256 characters of the beginning of a plain text version of the message body. This is intended to be shown as a preview line on a mailbox listing, and the server may choose to skip quoted sections or salutations to return a more useful preview.<br></p></li></ul></blockquote><div style="font-family:Arial;"><br></div>
<div style="font-family:Arial;">I wouldn't even say "of the beginning" - it's up to 256 characters that provide a good summary of the content of the message.&nbsp; I would say something like: This is intended to be shown as a preview line on a mailbox listing, and not all characters may be shown.&nbsp; The server may choose which part of the message to include in the preview, for example skipping quoted sections and salutations can result in a more useful preview.<br></div>
</blockquote><div><br></div>
<div>Yep, good point, I've updated this.</div>
<div><br></div>
<div>Neil.</div>
</body>
</html>

--_----------=_151841970810067573--


From nobody Sun Feb 11 23:26:54 2018
Return-Path: <neilj@fastmailteam.com>
X-Original-To: jmap@ietfa.amsl.com
Delivered-To: jmap@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id ED6FC124BE8 for <jmap@ietfa.amsl.com>; Sun, 11 Feb 2018 23:26:52 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.72
X-Spam-Level: 
X-Spam-Status: No, score=-2.72 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=fastmailteam.com header.b=EGPXo5VY; dkim=pass (2048-bit key) header.d=messagingengine.com header.b=XdbzQcDz
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id TEhvktHBG3eU for <jmap@ietfa.amsl.com>; Sun, 11 Feb 2018 23:26:48 -0800 (PST)
Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 9A9F81201F8 for <jmap@ietf.org>; Sun, 11 Feb 2018 23:26:48 -0800 (PST)
Received: from betaweb1.internal (betaweb1.nyi.internal [10.202.2.10]) by mailout.nyi.internal (Postfix) with ESMTP id 0C3D820BF9 for <jmap@ietf.org>; Mon, 12 Feb 2018 02:26:48 -0500 (EST)
Received: from betaweb1 ([::ffff:10.202.2.10]) by betaweb1.internal (MEProxy); Mon, 12 Feb 2018 02:26:48 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= fastmailteam.com; h=content-transfer-encoding:content-type:date :from:in-reply-to:message-id:mime-version:references:subject:to :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=gLqhxdHH1Eaich3wE ZE8kiDGxyXSqL/H6o8g0h8BOHE=; b=EGPXo5VYEbbTkI1J1c8RAiUA+/c+tk4PT WYC3JZ6CW4JgccwdlR81cdI9FFGlQd+V3Wv1RLDQBWcz8g/XEoHYjlykLEcNm3+V jtZrT/l5pcZQJX8C1um3kNPSh4O9kZdMQB+S2wAW7D+t/NffxvP4KEzwOMfIxhT4 N9qVaJo7SSYu3GELipMkzsxVut4B4TmqGQEeXkBd+ztnN9lSEhfr9P6rroYCjLND yX393s1UH8PRNnwNoIBXj36VGsQ3pY+hL75RnPD5PY/EqGw37BGAw1rwZtmwHFwb B/BoxhlIhIMHpOK1VCMDcwngFH3tRJIslYRzUWFxvzSERDxM5ueZg==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; bh=gLqhxd HH1Eaich3wEZE8kiDGxyXSqL/H6o8g0h8BOHE=; b=XdbzQcDz2w7uejdn5d4frn FXy2JokKgl+X1+b3X2KZThFwbfv9Dl/mE5B7omx+HmIb3CT5CTJaPkN/RSGGJCp0 tQ86RVzv8OHNN76yFihRbvJ4ee1Bw//oPEXzWH9jl3ULz+jensKxkxvLz1CH4qQ6 oYmgc5ELm4rdFLheqEHfKDt9IHU5J8oY0lBaDkEKEwHgHF2yaj7WFl67uT0K6eHB uHOhfJUTmIEeu0JSFi/dLCLimc2SXGefHhw1wgKrSeQ/lN8LY6AOOJjaOndcMW1A N+9HLDK9RNWgSThoc1edG62IJpAra1EYxmNm3lSBzAAPxOpLiIXEIz+r7wCaZeBw ==
X-ME-Sender: <xms:t0GBWufW49k9sCPM7Cspc0_TNuarEWgcXhHhqDu8_eA_W450qKvWOA>
Received: by mailuser.nyi.internal (Postfix, from userid 99) id 9B989E2479; Mon, 12 Feb 2018 02:26:47 -0500 (EST)
Message-Id: <1518420407.1012131.1267607120.3E7422B3@webmail.messagingengine.com>
From: Neil Jenkins <neilj@fastmailteam.com>
To: IETF JMAP Mailing List <jmap@ietf.org>
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Type: multipart/alternative; boundary="_----------=_151842040710121310"
X-Mailer: MessagingEngine.com Webmail Interface - ajax-2ce04827
In-Reply-To: <1518419708.1006757.1267595536.799BEEC0@webmail.messagingengine.com>
References: <1518070284.168650.1263633200.05C7397A@webmail.messagingengine.com> <1518408506.1699741.1267466096.17DCF605@webmail.messagingengine.com> <1518419708.1006757.1267595536.799BEEC0@webmail.messagingengine.com>
Date: Mon, 12 Feb 2018 18:26:47 +1100
Archived-At: <https://mailarchive.ietf.org/arch/msg/jmap/K2SIH9RkNHRz8XfiQkFuHsCypKc>
Subject: Re: [Jmap] New JSON message representation
X-BeenThere: jmap@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: JSON Message Access Protocol <jmap.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/jmap>, <mailto:jmap-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/jmap/>
List-Post: <mailto:jmap@ietf.org>
List-Help: <mailto:jmap-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/jmap>, <mailto:jmap-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 12 Feb 2018 07:26:53 -0000

This is a multi-part message in MIME format.

--_----------=_151842040710121310
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"

Revised text below for further review/comment. (You can also look at the
emailformat branch commits on GitHub[1] for diffs).
Cheers,
Neil.

-------
The *Email* object is a representation of an [@!RFC5322] message, which
allows clients to avoid the complexities of MIME parsing, transport
encoding and character encoding.Properties of the Email object


Broadly, a message consists of two parts: a list of header fields, then
a body. The body is normally a MIME-encoded set of documents in a tree
structure. The JMAP Email object provides a way to access the full
structure, or to use simplified properties and avoid some complexity if
this is sufficient for the client application.Due to the number of properti=
es involved, the set of *Email* properties
is specified over the following three sub-sections.Metadata


These properties represent metadata about the [@!RFC5322] message, and
are not derived from parsing the message itself.


 * *id*: String (immutable; server-set) The id of the Email object.
   Note, this is the JMAP object id, NOT the [@!RFC5322] Message-ID
   header field value.


 * *blobId*: String (immutable; server-set) The id representing the raw
   octets of the [@!RFC5322] message. This may be used to download the
   raw original message, or to attach it directly to another Email etc.


 * *threadId*: String (immutable; server-set) The id of the Thread to
   which this Email belongs.


 * *mailboxIds*: String[Boolean] The set of mailbox ids this email
   belongs to. An email MUST belong to one or more mailboxes at all
   times (until it is deleted). The set is represented as an object,
   with each key being a *Mailbox id*. The value for each key in the
   object MUST be true.


 * *keywords*: String[Boolean] (default: {}) A set of keywords that
   apply to the email. The set is represented as an object, with the
   keys being the *keywords*. The value for each key in the object
   MUST be true.


Keywords are shared with IMAP. The six system keywords from IMAP are
treated specially. The following four keywords have their first
character changed from \ in IMAP to $ in JMAP and have particular
semantic meaning:


   * $draft: The email is a draft the user is composing.
   * $seen: The email has been read.
   * $flagged: The email has been flagged for urgent/special attention.
   * $answered: The email has been replied to. The IMAP \Recent keyword
     is not exposed via JMAP. The IMAP \Deleted keyword is also not
     present: IMAP uses a delete+expunge model, which JMAP does not. Any
     message with the \Deleted keyword MUST NOT be visible via JMAP.


Users may add arbitrary keywords to an email. For compatibility with
IMAP, a keyword is a case-insensitive string of 1=E2=80=93255 characters in=
 the
ASCII subset %x21=E2=80=93%x7e (excludes control chars and space), and MUST=
 NOT
include any of these characters: ( ) { ] % * " \


Because JSON is case-sensitive, servers MUST return keywords in
lower-case.


The IANA Keyword Registry[2] as established in [@!RFC5788] assigns
semantic meaning to some other keywords in common use. New keywords may
be established here in the future. In particular, note:


   * $forwarded: The email has been forwarded.
   * $phishing: The email is highly likely to be phishing. Clients
     SHOULD warn users to take care when viewing this email and disable
     links and attachments.
   * $junk: The email is definitely spam. Clients SHOULD set this
     flag when users report spam to help train automated spam-
     detection systems.
   * $notjunk: The email is definitely not spam. Clients SHOULD set this
     flag when users indicate an email is legitimate, to help train
     automated spam-detection systems.
 * *size*: Number (immutable; server-set) The size, in octets, of the
   raw data for the RFC5322 message (as referenced by the *blobId*, i.e.
   the number of octets in the file the user would download).


 * *receivedAt*: UTCDate (immutable; default: time of creation on
   server) The date the email was received by the message store. This is
   the *internal date* in IMAP.Header fields


These properties are derived from the [@!RFC5322] and [@!RFC6532]
message header fields. All header fields may be fetched in a raw
form. Some headers may also be fetched in a parsed form. The
structured form that may be fetched depends on the header. The
following forms are defined:


 * *Raw* The raw octets of the header field value from the first octet
   following the header field name terminating colon, up to but
   excluding the header field terminating CRLF. Any standards-
   compliant message MUST be either ASCII (RFC5322) or UTF-8
   (RFC6532), however other encodings exist in the wild. A server MAY
   use heuristics to determine a charset and decode the octets, or MAY
   replace any octet or octet run with the high bit set that violates
   UTF-8 syntax with the unicode replacement character (U+FFFD). Any
   NUL octet MUST be dropped.


 * *Text* The header field value with:


   1. White space unfolded (as defined in [@!RFC5322] section 2.2.3)
   2. The terminating CRLF at the end of the value removed
   3. Any SP characters at the beginning of the value removed
   4. Any syntactically correct [@!RFC2047] encoded sections with a
      known character set are decoded. Any [@!RFC2047] encoded NUL
      octets or control characters are dropped from the decoded value.
      Any text that looks like [@!RFC2047] syntax but violates
      [@!RFC2047] placement or whitespace rules MUST NOT be decoded.
   5. Any [@!RFC6532] UTF-8 values decoded.
   6. The resulting unicode is converted to NFC form. If any decodings
      fail, the parser SHOULD insert a unicode replacement character
      (U+FFFD) and attempt to continue as much as possible.


To prevent obviously nonsense behaviour, which can lead to
interoperability issues, this form may only be fetched or set for the
following header fields:


   * Subject
   * Comment
   * Any header not defined in [@!RFC5322] or [@!RFC2369]
 * *Addresses* The header is parsed as an address-list value, as
   specified in [@!RFC5322] section 3.4, into the EmailAddress[] type.
   The *EmailAddress* object has the following properties:


   * *name*: String|null The *display name* of the [@!RFC5322] *mailbox*
     or *group*, or null if none.
   * *email*: String|null The *addr-spec* of the [@!RFC5322] *mailbox*,
     or null if a *group*. Any syntactically correct [@!RFC2047]
     encoded sections with a known encoding MUST be decoded, following
     the same rules as for the *Text* form. Any [@!RFC6532] UTF-8
     values MUST be decoded.


Parsing SHOULD be best-effort in the face of invalid structure to
accommodate invalid messages and semi-complete drafts. EmailAddress
objects MAY have an *email* property that does not conform to the *addr-
spec* form (for example, may not contain an @ symbol).


To prevent obviously nonsense behaviour, which can lead to
interoperability issues, this form may only be fetched or set for the
following header fields:


   * From
   * Sender
   * Reply-To
   * To
   * Cc
   * Bcc
   * Resent-From
   * Resent-Sender
   * Resent-Reply-To
   * Resent-To
   * Resent-Cc
   * Resent-Bcc
   * Any header not defined in [@!RFC5322] or [@!RFC2369]
 * *MessageIds* The header is parsed as a list of msg-id values, as
   specified in [@!RFC5322] section 3.6.5, into the String[] type.


To prevent obviously nonsense behaviour, which can lead to
interoperability issues, this form may only be fetched or set for the
following header fields:


   * Message-ID
   * In-Reply-To
   * References
   * Resent-Message-ID
   * Any header not defined in [@!RFC5322] or [@!RFC2369]
 * *Date* The header is parsed as a date-time value, as specified in
   [@!RFC5322] section 3.3, into the Date type.


To prevent obviously nonsense behaviour, which can lead to
interoperability issues, this form may only be fetched or set for the
following header fields:


   * Date
   * Resent-Date
   * Any header not defined in [@!RFC5322] or [@!RFC2369]
 * *URL* The header is parsed as a URL, as described in [@!RFC2369].
   This does not include the surrounding angle brackets or any comments
   in the header with the URL.


To prevent obviously nonsense behaviour, which can lead to
interoperability issues, this form may only be fetched or set for the
following header fields:


   * List-Help
   * List-Unsubscribe
   * List-Subscribe
   * List-Post
   * List-Owner
   * List-Archive
   * Any header not defined in [@!RFC5322] or [@!RFC2369]The following low-=
level *Email* properties are specified for complete
access to the header data of the message. Where {header-field-name} is
specified within a property name, this means any series of one or more
printable ASCII characters (i.e. characters that have values between 33
and 126, inclusive), except colon. Where {header-form} is specified
within a property name, this means one of the parsed-form name
specified above.


 * *headers*: EmailHeader[] (immutable) This is a list of all
   [@!RFC5322] header fields, in the same order they appear in the
   message. An *EmailHeader* object has the following properties:


   * *name*: String The header *field name* as defined in RFC5322, with
     the same capitalization that it has in the message.
   * *value*: String The header *field value* as defined in RFC5322, in
     *Raw* form.
 * *header:{header-field-name}*: String|null (immutable) The value of
   the *last* header field in the message with the given header field
   name (matched case-insensitively), or null if none. The value is in
   *Raw* form.


 * *header:{header-field-name}:as{header-form}*: String|null (immutable)
   The value of the *last* header field in the message with the given
   header field name (matched case-insensitively), or null if none,
   decoded according to the parsing algorithm given.The following convenien=
ce properties are also specified for the
*Email* object:


 * *messageId*: MsgIds[] (immutable) The value is identical to the value
   of *header:Message-ID:asMessageIds*.
 * *inReplyTo*: MsgIds[] (immutable) The value is identical to the value
   of *header:In-Reply-To:asMessageIds*.
 * *references*: MsgIds[] (immutable) The value is identical to the
   value of *header:References:asMessageIds*.
 * *sender*: EmailAddress[]|null (immutable) The value is identical to
   the value of *header:Sender:asAddresses*.
 * *from*: EmailAddress[]|null (immutable) The value is identical to the
   value of *header:From:asAddresses*.
 * *to*: EmailAddress[]|null (immutable) The value is identical to the
   value of *header:To:asAddresses*.
 * *cc*: EmailAddress[]|null (immutable) The value is identical to the
   value of *header:Cc:asAddresses*.
 * *bcc*: EmailAddress[]|null (immutable) The value is identical to the
   value of *header:Bcc:asAddresses*.
 * *replyTo*: EmailAddress[]|null (immutable) The value is identical to
   the value of *header:Reply-To:asAddresses*.
 * *subject*: String|null (immutable) The value is identical to the
   value of *header:Subject:asText*.
 * *sentAt*: Date (immutable; default on creation: current time on
   server) The value is identical to the value of *header:Date:asDate*.Body=
 parts


These properties are derived from the [@!RFC5322] message body and its
[@RFC2045] MIME entities.A *EmailBodyPart* object has the following propert=
ies:


 * *partId*: String Identifies this part uniquely within the Email. This
   is scoped to the *emailId* and has no meaning outside of the JMAP
   Email object representation.
 * *blobId*: String The id references the raw octets of the contents of
   the part after decoding any *Content-Transfer* encoding (as defined
   in [@!RFC2045]). Note, two parts may be transfer-encoded differently
   but have same the same blob id if their decoded octets are identical
   and the server is using a secure hash of the data for the blob id.
 * *size*: Number The size, in octets, of the raw data after content-
   transfer decoding (as referenced by the *blobId*, i.e. the number of
   octets in the file the user would download).
 * *headers*: EmailHeader[] (immutable) This is a list of all header
   fields in the part, in the order they appear. The values are in
   *Raw* form.
 * *name*: String|null This is the [@!RFC2231] decoded *filename*
   parameter of the *Content-Disposition* header field, or (for
   compatibility with existing systems) if not present then the
   [@!RFC2047] decoded *name* parameter of the *Content-Type*
   header field.
 * *type*: String The value of the *Content-Type* header field of the
   part, if present, otherwise null. CFWS is removed and any parameters
   are stripped.
 * *charset*: String|null The value of the charset parameter of the *Conten=
t-
   Type* header field, if present.
 * *disposition*: String|null The value of the *Content-Disposition*
   header field of the part, if present, otherwise null. CFWS is removed
   and any parameters are stripped.
 * *cid*: String|null The value of the *Content-Id* header field of the
   part, if present, otherwise null. CFWS is removed. This may be used
   to reference the content from within an html body part using the
   cid: protocol.
 * *language*: String[]|null The list of language tags, as defined in
   [@!RFC3282], in the *Content-Language* header field of the part,
   if present.
 * *location*: String|null The URI, as defined in [@!RFC2557], in the
   *Content-Location* header field of the part, if present.
 * *width*: Number|null The width (in px) of the image, if the type is
   an image and the server is able to determine this information for
   the image. This MAY not be supported for all or any image types on
   some servers.
 * *height*: Number|null The height (in px) of the image, if the type
   is an image and the server is able to determine this information for
   the image. This MAY not be supported for all or any image types on
   some servers.
 * *subParts*: EmailBodyPart[] (optional) If type is multipart/*, this
   contains the body parts of each child.The following *Email* properties a=
re specified for access to the body
data of the message:


 * *bodyStructure*: EmailBodyPart[] (immutable) This is the full MIME
   structure of the message body, including sub parts but not recursing
   into message/rfc822 or message/global parts.


 * *bodyValues*: String[BodyValue] (immutable) This is a map of *partId*
   to an *EmailBodyValue* object for none, some or all text/* parts.
   Which parts are included and whether the value is truncated is
   determined by various arguments to *Email/get* and *Email/parse*.


An *EmailBodyValue* object has the following properties:


   * *value*: String The value of the body part after decoding *Content-Tra=
nsport-
     Encoding* and decoding the *Content-Type* charset, if known to the
     server. The server MAY use heuristics to determine the charset to
     use for decoding if the charset is unknown, or if no charset is
     given, or if it believes the charset given is incorrect. Decoding
     is best-effort and SHOULD insert the unicode replacement character
     (U+FFFD) and continue when a malformed section is encountered.
   * *isEncodingProblem*: Boolean This is true if malformed sections
     were found while decoding the charset, or the charset was unknown.
   * *isTruncated*: Boolean This is true if the *value* has been
     truncated.
 * *textBody*: EmailBodyPart[] (immutable) A list of text/plain,
   text/html and image/* parts to display (sequentially) as the message
   body, with a preference for text/plain when alternative versions are
   available.


 * *htmlBody*: EmailBodyPart[] (immutable) A list of text/plain,
   text/html and image/* parts to display (sequentially) as the message
   body, with a preference for text/html when alternative versions are
   available.


 * *attachedEmails*: EmailBodyPart[] (immutable) A list of all parts of
   type message/rfc822 or message/global. Note, this *does not* recurse,
   so the parts within these are not included. The attached message may
   be fetched using the Email/parse method and the blobId.


 * *attachedFiles*: EmailBodyPart[] (immutable) A list of all parts in
   *bodyStructure*, traversing depth-first, not of type multipart/*, and
   not included in any of the *textBody*, *htmlBody* or *attachedEmails*
   properties. Note, an HTML body part may reference image parts in
   attachedFiles using cid: links to reference the *Content-Id* or by
   referencing the *Content-Location*.


 * *hasAttachment*: Boolean (immutable; server-set) This is true if
   there are one or more parts in the message that a client UI should
   offer as downloadable. A server SHOULD set hasAttachment if either:


   * The *attachedEmails* list contains at least one item.
   * The *attachedFiles* list contains at least one item that does not
     have Content-Disposition: inline. The server MAY ignore parts in
     this list that are processed automatically in some way, or are
     referenced as embedded images in one of the text/html parts of the
     message. The server MAY set hasAttachment based on implementation-
     defined or site configurable heuristics.


 * *preview*: String (immutable; server-set) Up to 256 characters of
   plain text, summarising the message body. This is intended to be
   shown as a preview line on a mailbox listing, and may be
   truncated when shown. The server may choose which part of the
   message to include in the preview, for example skipping quoted
   sections and salutations and collapsing white-space can result in
   a more useful preview.MIME structures are arbitrary nested trees of docu=
ments, but the
majority of email clients present a model of an email body (normally
plain text or HTML), with a set of attachments. Interpreting the MIME
structure to form this flat model represents considerable difficulty and
causes inconsistency between clients. Therefore in addition to the
*bodyStructure* property, which gives the full tree, the Email object
contains 4 alternate properties with flat lists of body parts:


 * *textBody*/*htmlBody*: These provide a list of parts that should be
   rendered as the "body" of the message. This is a list rather than a
   single part as messages may have headers and/or footers
   appended/prepended as separate parts as they are transmitted, and
   some clients send text and images intended to be displayed inline in
   the body as multiple parts rather than a single HTML part with
   referenced images.


Because MIME allows for multiple representations of the same data (using
multipart/alternative), there is a textBody property (which prefers a
plain text representation) and an htmlBody property (which prefers an
HTML representation) to accommodate the two most common client
requirements. The same part may appear in both lists where there is no
alternative between the two.


 * *attachedEmails*/*attachedFiles*: These provide a list of parts that
   should be presented as "attachments" to the message. Emails are
   presented in a separate list so their contents may be easily fetched
   via a back-reference with the Email/parse method in the same request,
   if the client wishes to. Some images in attachedFiles may be solely
   there for embedding within an HTML body part; clients may wish to not
   present these as attachments in the user interface if they are
   displaying the HTML with the embedded images directly.The *bodyValues* p=
roperty allows for clients to fetch the value of text
parts directly without having to do a second request for the blob, and
have the server handle decoding the charset into unicode. This data is
in a separate property rather than on the EmailBodyPart object to avoid
duplication of large amounts of data, as the same part may be included
twice if the client fetches more than one of bodyStructure, textBody
and htmlBody.The exact algorithm for decomposing bodyStructure into textBod=
y,
htmlBody, attachedEmails and attachedFiles part lists is not mandated,
as this is a quality-of-service implementation issue and likely to
require workarounds for malformed content discovered over time.However, we =
will define a suggested algorithm for the RFC to help
implementors. TODO.Email/get


Standard */get* method, with the following additional arguments:


 * *bodyProperties*: String[] (optional) A list of properties to fetch
   for each EmailBodyPart returned. If omitted, this defaults to:


[ "partId", "blobId", "size", "name", "type", "charset", "disposition",
cid", "language", "location", "width", "height" ]


 * *fetchTextBodyValues*: Boolean (default: false) If true, the
   *bodyValues* property includes any text/* part in the textBody
   property.


 * *fetchHTMLBodyValues*: Boolean (default: false) If true, the
   *bodyValues* property includes any text/* part in the htmlBody
   property.


 * *fetchAllBodyValues*: Boolean (default: false) If true, the
   *bodyValues* property includes any text/* part in the
   bodyStructure property.


 * *maxBodyValueBytes*: Number (optional) If supplied by the client, the
   value MUST be a positive integer greater than 0. If a value outside
   of this range is given, the server MUST reject the call with an
   invalidArguments error. When given, the *value* property of any
   EmailBodyValue object returned in *bodyValues* MUST be truncated if
   necessary so it does not exceed this number of octets in size. The
   server MUST ensure the truncation results in valid UTF-8 and does not
   occur mid-codepoint. If the part is of type text/html, the server
   SHOULD NOT truncate inside an HTML tag.If the standard *properties* argu=
ment is omitted or null, the following
default MUST be used instead of "all" properties:


[ "id", "blobId", "threadId", "mailboxIds", "keywords", "size",
"receivedAt", "messageId", "inReplyTo", "references", "sender", "from",
"to", "cc", "bcc", "replyTo", "subject", "sentAt", "hasAttachment",
"preview", "bodyValues", "textBody", "htmlBody", "attachedFiles",
"attachedEmails" ]The following properties are expected to be fast to fetch=
 in a quality
implementation:


 * id
 * blobId
 * threadId
 * mailboxIds
 * keywords
 * size
 * receivedAt
 * messageId
 * inReplyTo
 * sender
 * from
 * to
 * cc
 * bcc
 * replyTo
 * subject
 * sentAt
 * hasAttachment
 * previewClients SHOULD take care when fetching any other properties, as t=
here
may be significantly longer latency in fetching and returning the data.As s=
pecified above, parsed forms of headers may only be used on
appropriate header fields. Attempting to fetch a form that is forbidden
(e.g. header:From:asDate) MUST result in the method call being rejected
with an invalidArguments error.Where a specific header is requested as a pr=
operty, the capitalization
of the property name in the response MUST be identical to that used in
the request.Example


Request:


["Email/get", { "ids": [ "f123u456", "f123u457" ], "properties": [
"threadId", "mailboxIds", "from", "subject", "receivedAt", "header:List-
POST:asURL" "htmlBody", "bodyValues" ], "bodyProperties": [ "partId",
"blobId", "size", "type" ], "fetchHTMLBodyValues": true,
"maxBodyValueBytes": 256 }, "#1"]and response:


["Email/get", { "accountId": "abc", "state": "41234123231", "list":
[ { "id": "f123u457", "threadId": "ef1314a", "mailboxIds": { "f123":
true }, "from": [{name: "Joe Bloggs", email: "joe@bloggs.com"}],
"subject": "Dinner on Thursday?", "receivedAt": "2013-10-
13T14:12:00Z", "header:List-POST:asURL":
"mailto:partytime@lists.example.com", "htmlBody": [{ "partId": "1",
"blobId": "841623871", "size": 283331, "type": "text/html" }, {
"partId": "2", "blobId": "319437193", "size": 10343, "type":
"text/plain" }], "bodyValues": { "1": { "isEncodingProblem": false,
"isTruncated": true, "value": "<html><body><p>Hello ..." }, "2": {
"isEncodingProblem": false, "isTruncated": false, "value": "--
\nSent by your friendly mailing list ..." } } } ], notFound: [
"f123u456" ] }, "#1"]

Links:

  1. https://github.com/jmapio/jmap/commits/emailformat
  2. https://www.iana.org/assignments/imap-keywords/imap-keywords.xhtml

--_----------=_151842040710121310
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="utf-8"

<!DOCTYPE html>
<html>
<head>
<title></title>
<style type=3D"text/css">p.MsoNormal,p.MsoNoSpacing{margin:0}</style>
</head>
<body><div>Revised text below for further review/comment. (You can also loo=
k at the <a href=3D"https://github.com/jmapio/jmap/commits/emailformat">ema=
ilformat branch commits on GitHub</a> for diffs).<br></div>
<div><br></div>
<div>Cheers,<br></div>
<div>Neil.</div>
<div><br></div>
<div>-------<br></div>
<p>The <b>Email</b> object is a representation of an [@!RFC5322] message, w=
hich allows clients to avoid the complexities of MIME parsing, transport en=
coding and character encoding.<br></p><h2 id=3D"propertiesoftheemailobject"=
>Properties of the Email object<br></h2><p>Broadly, a message consists of t=
wo parts: a list of header fields, then a body. The body is normally a MIME=
-encoded set of documents in a tree structure. The JMAP Email object provid=
es a way to access the full structure, or to use simplified properties and =
avoid some complexity if this is sufficient for the client application.<br>=
</p><p>Due to the number of properties involved, the set of <i>Email</i> pr=
operties is specified over the following three sub-sections.<br></p><h3 id=
=3D"metadata">Metadata<br></h3><p>These properties represent metadata about=
 the [@!RFC5322] message, and are not derived from parsing the message itse=
lf.<br></p><ul><li><p><b>id</b>: <code>String</code> (immutable; server-set)
The id of the Email object. Note, this is the JMAP object id, NOT the [@!RF=
C5322] Message-ID header field value.<br></p></li><li><p><b>blobId</b>: <co=
de>String</code> (immutable; server-set)
The id representing the raw octets of the [@!RFC5322] message. This may be =
used to download the raw original message, or to attach it directly to anot=
her Email etc.<br></p></li><li><p><b>threadId</b>: <code>String</code> (imm=
utable; server-set)
The id of the Thread to which this Email belongs.<br></p></li><li><p><b>mai=
lboxIds</b>: <code>String[Boolean]</code> The set of mailbox ids this email=
 belongs to. An email MUST belong to one or more mailboxes at all times (un=
til it is deleted). The set is represented as an object, with each key bein=
g a <i>Mailbox id</i>. The value for each key in the object MUST be <code>t=
rue</code>.<br></p></li><li><p><b>keywords</b>: <code>String[Boolean]</code=
> (default: <code>{}</code>)
A set of keywords that apply to the email. The set is represented as an obj=
ect, with the keys being the <i>keywords</i>. The value for each key in the=
 object MUST be <code>true</code>.<br></p><p>Keywords are shared with IMAP.=
 The six system keywords from IMAP are treated specially. The following fou=
r keywords have their first character changed from <code>\</code> in IMAP t=
o <code>$</code> in JMAP and have particular semantic meaning:<br></p><ul><=
li><code>$draft</code>: The email is a draft the user is composing.<br></li=
><li><code>$seen</code>: The email has been read.<br></li><li><code>$flagge=
d</code>: The email has been flagged for urgent/special attention.<br></li>=
<li><code>$answered</code>: The email has been replied to.<br></li></ul><p>=
The IMAP <code>\Recent</code> keyword is not exposed via JMAP. The IMAP <co=
de>\Deleted</code> keyword is also not present: IMAP uses a delete+expunge =
model, which JMAP does not. Any message with the <code>\Deleted</code> keyw=
ord MUST NOT be visible via JMAP.<br></p><p>Users may add arbitrary keyword=
s to an email. For compatibility with IMAP, a keyword is a case-insensitive=
 string of 1=E2=80=93255 characters in the ASCII subset %x21=E2=80=93%x7e (=
excludes control chars and space), and MUST NOT include any of these charac=
ters: <code>( ) { ] % * " \</code><br></p><p>Because JSON is case-sensitive=
, servers MUST return keywords in lower-case.<br></p><p>The <a href=3D"http=
s://www.iana.org/assignments/imap-keywords/imap-keywords.xhtml">IANA Keywor=
d Registry</a> as established in [@!RFC5788] assigns semantic meaning to so=
me other keywords in common use. New keywords may be established here in th=
e future. In particular, note:<br></p><ul><li><code>$forwarded</code>: The =
email has been forwarded.<br></li><li><code>$phishing</code>: The email is =
highly likely to be phishing. Clients SHOULD warn users to take care when v=
iewing this email and disable links and attachments.<br></li><li><code>$jun=
k</code>: The email is definitely spam. Clients SHOULD set this flag when u=
sers report spam to help train automated spam-detection systems.<br></li><l=
i><code>$notjunk</code>: The email is definitely not spam. Clients SHOULD s=
et this flag when users indicate an email is legitimate, to help train auto=
mated spam-detection systems.<br></li></ul></li><li><p><b>size</b>: <code>N=
umber</code> (immutable; server-set)
The size, in octets, of the raw data for the RFC5322 message (as referenced=
 by the <i>blobId</i>, i.e. the number of octets in the file the user would=
 download).<br></p></li><li><p><b>receivedAt</b>: <code>UTCDate</code> (imm=
utable; default: time of creation on server)
The date the email was received by the message store. This is the <i>intern=
al date</i> in IMAP.<br></p></li></ul><h3 id=3D"headerfields">Header fields=
<br></h3><p>These properties are derived from the [@!RFC5322] and [@!RFC653=
2] message header fields. All header fields may be fetched in a raw form. S=
ome headers may also be fetched in a parsed form. The structured form that =
may be fetched depends on the header. The following forms are defined:<br><=
/p><ul><li><p><b>Raw</b> The raw octets of the header field value from the =
first octet following the header field name terminating colon, up to but ex=
cluding the header field terminating CRLF. Any standards-compliant message =
MUST be either ASCII (RFC5322) or UTF-8 (RFC6532), however other encodings =
exist in the wild. A server MAY use heuristics to determine a charset and d=
ecode the octets, or MAY replace any octet or octet run with the high bit s=
et that violates UTF-8 syntax with the unicode replacement character (U+FFF=
D). Any NUL octet MUST be dropped.<br></p></li><li><p><b>Text</b> The heade=
r field value with:<br></p><ol><li>White space unfolded (as defined in [@!R=
FC5322] section 2.2.3)<br></li><li>The terminating CRLF at the end of the v=
alue removed<br></li><li>Any SP characters at the beginning of the value re=
moved<br></li><li>Any syntactically correct [@!RFC2047] encoded sections wi=
th a known
character set are decoded. Any [@!RFC2047] encoded NUL octets or control ch=
aracters are dropped from the decoded value. Any text that looks like [@!RF=
C2047] syntax but violates [@!RFC2047] placement or whitespace rules MUST N=
OT be decoded.<br></li><li>Any [@!RFC6532] UTF-8 values decoded.<br></li><l=
i>The resulting unicode is converted to NFC form.<br></li></ol><p>If any de=
codings fail, the parser SHOULD insert a unicode replacement
character (U+FFFD) and attempt to continue as much as possible.<br></p><p>T=
o prevent obviously nonsense behaviour, which can lead to interoperability =
issues, this form may only be fetched or set for the following header field=
s:<br></p><ul><li>Subject<br></li><li>Comment<br></li><li>Any header not de=
fined in [@!RFC5322] or [@!RFC2369]<br></li></ul></li><li><p><b>Addresses</=
b> The header is parsed as an <code>address-list</code> value, as specified=
 in [@!RFC5322] section 3.4, into the <code>EmailAddress[]</code> type. The=
 <b>EmailAddress</b> object has the following properties:<br></p><ul><li><b=
>name</b>: <code>String|null</code> The <i>display name</i> of the [@!RFC53=
22] <i>mailbox</i> or <i>group</i>, or <code>null</code> if none.<br></li><=
li><b>email</b>: <code>String|null</code> The <i>addr-spec</i> of the [@!RF=
C5322] <i>mailbox</i>, or <code>null</code> if a <i>group</i>.<br></li></ul=
><p>Any syntactically correct [@!RFC2047] encoded sections with a known enc=
oding MUST be decoded, following the same rules as for the <i>Text</i> form=
. Any [@!RFC6532] UTF-8 values MUST be decoded.<br></p><p>Parsing SHOULD be=
 best-effort in the face of invalid structure to accommodate
invalid messages and semi-complete drafts. EmailAddress objects MAY have an=
 <i>email</i> property that does not conform to the <i>addr-spec</i> form (=
for example, may not contain an @ symbol).<br></p><p>To prevent obviously n=
onsense behaviour, which can lead to interoperability issues, this form may=
 only be fetched or set for the following header fields:<br></p><ul><li>Fro=
m<br></li><li>Sender<br></li><li>Reply-To<br></li><li>To<br></li><li>Cc<br>=
</li><li>Bcc<br></li><li>Resent-From<br></li><li>Resent-Sender<br></li><li>=
Resent-Reply-To<br></li><li>Resent-To<br></li><li>Resent-Cc<br></li><li>Res=
ent-Bcc<br></li><li>Any header not defined in [@!RFC5322] or [@!RFC2369]<br=
></li></ul></li><li><p><b>MessageIds</b> The header is parsed as a list of =
<code>msg-id</code> values, as specified in [@!RFC5322] section 3.6.5, into=
 the <code>String[]</code> type.<br></p><p>To prevent obviously nonsense be=
haviour, which can lead to interoperability issues, this form may only be f=
etched or set for the following header fields:<br></p><ul><li>Message-ID<br=
></li><li>In-Reply-To<br></li><li>References<br></li><li>Resent-Message-ID<=
br></li><li>Any header not defined in [@!RFC5322] or [@!RFC2369]<br></li></=
ul></li><li><p><b>Date</b> The header is parsed as a <code>date-time</code>=
 value, as specified in [@!RFC5322] section 3.3, into the <code>Date</code>=
 type.<br></p><p>To prevent obviously nonsense behaviour, which can lead to=
 interoperability issues, this form may only be fetched or set for the foll=
owing header fields:<br></p><ul><li>Date<br></li><li>Resent-Date<br></li><l=
i>Any header not defined in [@!RFC5322] or [@!RFC2369]<br></li></ul></li><l=
i><p><b>URL</b> The header is parsed as a URL, as described in [@!RFC2369].=
 This does not include the surrounding angle brackets or any comments in th=
e header with the URL.<br></p><p>To prevent obviously nonsense behaviour, w=
hich can lead to interoperability issues, this form may only be fetched or =
set for the following header fields:<br></p><ul><li>List-Help<br></li><li>L=
ist-Unsubscribe<br></li><li>List-Subscribe<br></li><li>List-Post<br></li><l=
i>List-Owner<br></li><li>List-Archive<br></li><li>Any header not defined in=
 [@!RFC5322] or [@!RFC2369]<br></li></ul></li></ul><p>The following low-lev=
el <b>Email</b> properties are specified for complete access to the header =
data of the message. Where <code>{header-field-name}</code> is specified wi=
thin a property name, this means any series of one or more printable ASCII =
characters (i.e. characters that have values between 33 and 126, inclusive)=
, except colon. Where <code>{header-form}</code> is specified within a prop=
erty name, this means one of the parsed-form name specified above.<br></p><=
ul><li><p><b>headers</b>: <code>EmailHeader[]</code> (immutable)
This is a list of all [@!RFC5322] header fields, in the same order they app=
ear in the message. An <b>EmailHeader</b> object has the following properti=
es:<br></p><ul><li><b>name</b>: <code>String</code> The header <i>field nam=
e</i> as defined in RFC5322, with the same capitalization that it has in th=
e message.<br></li><li><b>value</b>: <code>String</code> The header <i>fiel=
d value</i> as defined in RFC5322, in <i>Raw</i> form.<br></li></ul></li><l=
i><p><b>header:{header-field-name}</b>: <code>String|null</code> (immutable)
The value of the <i>last</i> header field in the message with the given hea=
der field name (matched case-insensitively), or <code>null</code> if none. =
The value is in <i>Raw</i> form.<br></p></li><li><p><b>header:{header-field=
-name}:as{header-form}</b>: <code>String|null</code> (immutable)
The value of the <i>last</i> header field in the message with the given hea=
der field name (matched case-insensitively), or <code>null</code> if none, =
decoded according to the parsing algorithm given.<br></p></li></ul><p>The f=
ollowing convenience properties are also specified for the <b>Email</b> obj=
ect:<br></p><ul><li><b>messageId</b>: <code>MsgIds[]</code> (immutable)
The value is identical to the value of <i>header:Message-ID:asMessageIds</i=
>.<br></li><li><b>inReplyTo</b>: <code>MsgIds[]</code> (immutable)
The value is identical to the value of <i>header:In-Reply-To:asMessageIds</=
i>.<br></li><li><b>references</b>: <code>MsgIds[]</code> (immutable)
The value is identical to the value of <i>header:References:asMessageIds</i=
>.<br></li><li><b>sender</b>: <code>EmailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:Sender:asAddresses</i>.<br=
></li><li><b>from</b>: <code>EmailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:From:asAddresses</i>.<br><=
/li><li><b>to</b>: <code>EmailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:To:asAddresses</i>.<br></l=
i><li><b>cc</b>: <code>EmailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:Cc:asAddresses</i>.<br></l=
i><li><b>bcc</b>: <code>EmailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:Bcc:asAddresses</i>.<br></=
li><li><b>replyTo</b>: <code>EmailAddress[]|null</code> (immutable)
The value is identical to the value of <i>header:Reply-To:asAddresses</i>.<=
br></li><li><b>subject</b>: <code>String|null</code> (immutable)
The value is identical to the value of <i>header:Subject:asText</i>.<br></l=
i><li><b>sentAt</b>: <code>Date</code> (immutable; default on creation: cur=
rent time on server)
The value is identical to the value of <i>header:Date:asDate</i>.<br></li><=
/ul><h3 id=3D"bodyparts">Body parts<br></h3><p>These properties are derived=
 from the [@!RFC5322] message body and its [@RFC2045] MIME entities.<br></p=
><p>A <b>EmailBodyPart</b> object has the following properties:<br></p><ul>=
<li><b>partId</b>: <code>String</code> Identifies this part uniquely within=
 the Email. This is scoped to the <i>emailId</i> and has no meaning outside=
 of the JMAP Email object representation.<br></li><li><b>blobId</b>: <code>=
String</code> The id references the raw octets of the contents of the part =
after decoding any <i>Content-Transfer</i> encoding (as defined in [@!RFC20=
45]). Note, two parts may be transfer-encoded differently but have same the=
 same blob id if their decoded octets are identical and the server is using=
 a secure hash of the data for the blob id.<br></li><li><b>size</b>: <code>=
Number</code> The size, in octets, of the raw data after content-transfer d=
ecoding (as referenced by the <i>blobId</i>, i.e. the number of octets in t=
he file the user would download).<br></li><li><b>headers</b>: <code>EmailHe=
ader[]</code> (immutable)
This is a list of all header fields in the part, in the order they appear. =
The values are in <i>Raw</i> form.<br></li><li><b>name</b>: <code>String|nu=
ll</code> This is the [@!RFC2231] decoded <i>filename</i> parameter of the =
<i>Content-Disposition</i> header field, or (for compatibility with existin=
g systems) if not present then the [@!RFC2047] decoded <i>name</i> paramete=
r of the <i>Content-Type</i> header field.<br></li><li><b>type</b>: <code>S=
tring</code> The value of the <i>Content-Type</i> header field of the part,=
 if present, otherwise <code>null</code>. CFWS is removed and any parameter=
s are stripped.<br></li><li><b>charset</b>: <code>String|null</code> The va=
lue of the charset parameter of the <i>Content-Type</i> header field, if pr=
esent.<br></li><li><b>disposition</b>: <code>String|null</code> The value o=
f the <i>Content-Disposition</i> header field of the part, if present, othe=
rwise <code>null</code>. CFWS is removed and any parameters are stripped.<b=
r></li><li><b>cid</b>: <code>String|null</code> The value of the <i>Content=
-Id</i> header field of the part, if present, otherwise <code>null</code>. =
CFWS is removed. This may be used to reference the content from within an h=
tml body part using the <code>cid:</code> protocol.<br></li><li><b>language=
</b>: <code>String[]|null</code> The list of language tags, as defined in [=
@!RFC3282], in the <i>Content-Language</i> header field of the part, if pre=
sent.<br></li><li><b>location</b>: <code>String|null</code> The URI, as def=
ined in [@!RFC2557], in the <i>Content-Location</i> header field of the par=
t, if present.<br></li><li><b>width</b>: <code>Number|null</code> The width=
 (in px) of the image, if the type is an image and the server is able to de=
termine this information for the image. This MAY not be supported for all o=
r any image types on some servers.<br></li><li><b>height</b>: <code>Number|=
null</code> The height (in px) of the image, if the type is an image and th=
e server is able to determine this information for the image. This MAY not =
be supported for all or any image types on some servers.<br></li><li><b>sub=
Parts</b>: <code>EmailBodyPart[]</code> (optional)
If type is <code>multipart/*</code>, this contains the body parts of each c=
hild.<br></li></ul><p>The following <b>Email</b> properties are specified f=
or access to the body data of the message:<br></p><ul><li><p><b>bodyStructu=
re</b>: <code>EmailBodyPart[]</code> (immutable)
This is the full MIME structure of the message body, including sub parts bu=
t not recursing into <code>message/rfc822</code> or <code>message/global</c=
ode> parts.<br></p></li><li><p><b>bodyValues</b>: <code>String[BodyValue]</=
code> (immutable)
This is a map of <i>partId</i> to an <b>EmailBodyValue</b> object for none,=
 some or all <code>text/*</code> parts. Which parts are included and whethe=
r the value is truncated is determined by various arguments to <i>Email/get=
</i> and <i>Email/parse</i>.<br></p><p>An <b>EmailBodyValue</b> object has =
the following properties:<br></p><ul><li><b>value</b>: <code>String</code> =
The value of the body part after decoding <i>Content-Transport-Encoding</i>=
 and
decoding the <i>Content-Type</i> charset, if known to the server. The serve=
r MAY use heuristics to determine the charset to use for decoding if the ch=
arset is unknown, or if no charset is given, or if it believes the charset =
given is incorrect. Decoding is best-effort and SHOULD insert the unicode r=
eplacement character (U+FFFD) and continue when a malformed section is enco=
untered.<br></li><li><b>isEncodingProblem</b>: <code>Boolean</code> This is=
 <code>true</code> if malformed sections were found while decoding the char=
set, or the charset was unknown.<br></li><li><b>isTruncated</b>: <code>Bool=
ean</code> This is <code>true</code> if the <i>value</i> has been truncated=
.<br></li></ul></li><li><p><b>textBody</b>: <code>EmailBodyPart[]</code> (i=
mmutable)
A list of <code>text/plain</code>, <code>text/html</code> and <code>image/*=
</code> parts to display (sequentially) as the message body, with a prefere=
nce for <code>text/plain</code> when alternative versions are available.<br=
></p></li><li><p><b>htmlBody</b>: <code>EmailBodyPart[]</code> (immutable)
A list of <code>text/plain</code>, <code>text/html</code> and <code>image/*=
</code> parts to display (sequentially) as the message body, with a prefere=
nce for <code>text/html</code> when alternative versions are available.<br>=
</p></li><li><p><b>attachedEmails</b>: <code>EmailBodyPart[]</code> (immuta=
ble)
A list of all parts of type <code>message/rfc822</code> or <code>message/gl=
obal</code>. Note, this <b>does not</b> recurse, so the parts within these =
are not included. The attached message may be fetched using the Email/parse=
 method and the blobId.<br></p></li><li><p><b>attachedFiles</b>: <code>Emai=
lBodyPart[]</code> (immutable)
A list of all parts in <i>bodyStructure</i>, traversing depth-first, not of=
 type <code>multipart/*</code>, and not included in any of the <i>textBody<=
/i>, <i>htmlBody</i> or <i>attachedEmails</i> properties. Note, an HTML bod=
y part may reference image parts in attachedFiles using <code>cid:</code> l=
inks to reference the <i>Content-Id</i> or by referencing the <i>Content-Lo=
cation</i>.<br></p></li><li><p><b>hasAttachment</b>: <code>Boolean</code> (=
immutable; server-set)
This is <code>true</code> if there are one or more parts in the message tha=
t a client UI should offer as downloadable. A server SHOULD set hasAttachme=
nt if either:<br></p><ul><li>The <i>attachedEmails</i> list contains at lea=
st one item.<br></li><li>The <i>attachedFiles</i> list contains at least on=
e item that does not have <code>Content-Disposition: inline</code>. The ser=
ver MAY ignore parts in this list that are processed automatically in some =
way, or are referenced as embedded images in one of the <code>text/html</co=
de> parts of the message.<br></li></ul><p>The server MAY set hasAttachment =
based on implementation-defined or site configurable heuristics.<br></p></l=
i><li><p><b>preview</b>: <code>String</code> (immutable; server-set)
Up to 256 characters of plain text, summarising the message body. This is i=
ntended to be shown as a preview line on a mailbox listing, and may be trun=
cated when shown. The server may choose which part of the message to includ=
e in the preview, for example skipping quoted sections and salutations and =
collapsing white-space can result in a more useful preview.<br></p></li></u=
l><p>MIME structures are arbitrary nested trees of documents, but the major=
ity of email clients present a model of an email body (normally plain text =
or HTML), with a set of attachments. Interpreting the MIME structure to for=
m this flat model represents considerable difficulty and causes inconsisten=
cy between clients. Therefore in addition to the <i>bodyStructure</i> prope=
rty, which gives the full tree, the Email object contains 4 alternate prope=
rties with flat lists of body parts:<br></p><ul><li><p><i>textBody</i>/<i>h=
tmlBody</i>: These provide a list of parts that should be
rendered as the "body" of the message. This is a list rather than a single =
part as messages may have headers and/or footers appended/prepended as sepa=
rate parts as they are transmitted, and some clients send text and images i=
ntended to be displayed inline in the body as multiple parts rather than a =
single HTML part with referenced images.<br></p><p>Because MIME allows for =
multiple representations of the same data (using <code>multipart/alternativ=
e</code>), there is a textBody property (which prefers a plain text represe=
ntation) and an htmlBody property (which prefers an HTML representation) to=
 accommodate the two most common client requirements. The same part may app=
ear in both lists where there is no alternative between the two.<br></p></l=
i><li><p><i>attachedEmails</i>/<i>attachedFiles</i>: These provide a list o=
f parts that should
be presented as "attachments" to the message. Emails are presented in a sep=
arate list so their contents may be easily fetched via a back-reference wit=
h the <code>Email/parse</code> method in the same request, if the client wi=
shes to. Some images in attachedFiles may be solely there for embedding wit=
hin an HTML body part; clients may wish to not present these as attachments=
 in the user interface if they are displaying the HTML with the embedded im=
ages directly.<br></p></li></ul><p>The <i>bodyValues</i> property allows fo=
r clients to fetch the value of text parts directly without having to do a =
second request for the blob, and have the server handle decoding the charse=
t into unicode. This data is in a separate property rather than on the Emai=
lBodyPart object to avoid duplication of large amounts of data, as the same=
 part may be included twice if the client fetches more than one of bodyStru=
cture, textBody and htmlBody.<br></p><p>The exact algorithm for decomposing=
 bodyStructure into textBody, htmlBody, attachedEmails and attachedFiles pa=
rt lists is not mandated, as this is a quality-of-service implementation is=
sue and likely to require workarounds for malformed content discovered over=
 time.<br></p><p>However, we will define a suggested algorithm for the RFC =
to help implementors. TODO.<br></p><h2 id=3D"emailget">Email/get<br></h2><p=
>Standard <i>/get</i> method, with the following additional arguments:<br><=
/p><ul><li><p><b>bodyProperties</b>: <code>String[]</code> (optional)
A list of properties to fetch for each EmailBodyPart returned. If omitted, =
this defaults to:<br></p><p>[ "partId", "blobId", "size", "name", "type", "=
charset", "disposition", cid", "language", "location", "width", "height" ]<=
br></p></li><li><p><b>fetchTextBodyValues</b>: <code>Boolean</code> (defaul=
t: <code>false</code>)
If <code>true</code>, the <i>bodyValues</i> property includes any <code>tex=
t/*</code> part in the <code>textBody</code> property.<br></p></li><li><p><=
b>fetchHTMLBodyValues</b>: <code>Boolean</code> (default: <code>false</code=
>)
If <code>true</code>, the <i>bodyValues</i> property includes any <code>tex=
t/*</code> part in the <code>htmlBody</code> property.<br></p></li><li><p><=
b>fetchAllBodyValues</b>: <code>Boolean</code> (default: <code>false</code>)
If <code>true</code>, the <i>bodyValues</i> property includes any <code>tex=
t/*</code> part in the <code>bodyStructure</code> property.<br></p></li><li=
><p><b>maxBodyValueBytes</b>: <code>Number</code> (optional)
If supplied by the client, the value MUST be a positive integer greater tha=
n 0. If a value outside of this range is given, the server MUST reject the =
call with an <code>invalidArguments</code> error. When given, the <i>value<=
/i> property of any EmailBodyValue object returned in <i>bodyValues</i> MUS=
T be truncated if necessary so it does not exceed this number of octets in =
size. The server MUST ensure the truncation results in valid UTF-8 and does=
 not occur mid-codepoint. If the part is of type <code>text/html</code>, th=
e server SHOULD NOT truncate inside an HTML tag.<br></p></li></ul><p>If the=
 standard <i>properties</i> argument is omitted or <code>null</code>, the f=
ollowing default MUST be used instead of "all" properties:<br></p><pre><cod=
e>[ "id", "blobId", "threadId", "mailboxIds", "keywords", "size", "received=
At", "messageId", "inReplyTo", "references", "sender", "from", "to", "cc", =
"bcc", "replyTo", "subject", "sentAt", "hasAttachment", "preview", "bodyVal=
ues", "textBody", "htmlBody", "attachedFiles", "attachedEmails" ]
</code><br></pre><p>The following properties are expected to be fast to fet=
ch in a quality implementation:<br></p><ul><li>id<br></li><li>blobId<br></l=
i><li>threadId<br></li><li>mailboxIds<br></li><li>keywords<br></li><li>size=
<br></li><li>receivedAt<br></li><li>messageId<br></li><li>inReplyTo<br></li=
><li>sender<br></li><li>from<br></li><li>to<br></li><li>cc<br></li><li>bcc<=
br></li><li>replyTo<br></li><li>subject<br></li><li>sentAt<br></li><li>hasA=
ttachment<br></li><li>preview<br></li></ul><p>Clients SHOULD take care when=
 fetching any other properties, as there may be significantly longer latenc=
y in fetching and returning the data.<br></p><p>As specified above, parsed =
forms of headers may only be used on appropriate header fields. Attempting =
to fetch a form that is forbidden (e.g. <code>header:From:asDate</code>) MU=
ST result in the method call being rejected with an <code>invalidArguments<=
/code> error.<br></p><p>Where a specific header is requested as a property,=
 the capitalization of the property name in the response MUST be identical =
to that used in the request.<br></p><h3 id=3D"example">Example<br></h3><p>R=
equest:<br></p><pre><code>["Email/get", {
  "ids": [ "f123u456", "f123u457" ],
  "properties": [ "threadId", "mailboxIds", "from", "subject", "receivedAt"=
, "header:List-POST:asURL" "htmlBody", "bodyValues" ],
  "bodyProperties": [ "partId", "blobId", "size", "type" ],
  "fetchHTMLBodyValues": true,
  "maxBodyValueBytes": 256
}, "#1"]
</code><br></pre><p>and response:<br></p><pre><code>["Email/get", {
  "accountId": "abc",
  "state": "41234123231",
  "list": [
    {
      "id": "f123u457",
      "threadId": "ef1314a",
      "mailboxIds": { "f123": true },
      "from": [{name: "Joe Bloggs", email: "joe@bloggs.com"}],
      "subject": "Dinner on Thursday?",
      "receivedAt": "2013-10-13T14:12:00Z",
      "header:List-POST:asURL": "mailto:partytime@lists.example.com",
      "htmlBody": [{
        "partId": "1",
        "blobId": "841623871",
        "size": 283331,
        "type": "text/html"
      }, {
        "partId": "2",
        "blobId": "319437193",
        "size": 10343,
        "type": "text/plain"
      }],
      "bodyValues": {
        "1": {
          "isEncodingProblem": false,
          "isTruncated": true,
          "value": "&lt;html&gt;&lt;body&gt;&lt;p&gt;Hello ..."
        },
        "2": {
          "isEncodingProblem": false,
          "isTruncated": false,
          "value": "-- \nSent by your friendly mailing list ..."
        }
      }
    }
  ],
  notFound: [ "f123u456" ]
}, "#1"]
</code><br></pre><div><br></div>
</body>
</html>

--_----------=_151842040710121310--


From nobody Mon Feb 12 11:58:03 2018
Return-Path: <chris.newman@oracle.com>
X-Original-To: jmap@ietfa.amsl.com
Delivered-To: jmap@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 21F9912D94D for <jmap@ietfa.amsl.com>; Mon, 12 Feb 2018 11:57:58 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.031
X-Spam-Level: 
X-Spam-Status: No, score=-2.031 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_PASS=-0.001, T_RP_MATCHES_RCVD=-0.01] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=oracle.com
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Em6u8LbiXqE3 for <jmap@ietfa.amsl.com>; Mon, 12 Feb 2018 11:57:54 -0800 (PST)
Received: from aserp2130.oracle.com (aserp2130.oracle.com [141.146.126.79]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 9F5C412D94C for <jmap@ietf.org>; Mon, 12 Feb 2018 11:57:49 -0800 (PST)
Received: from pps.filterd (aserp2130.oracle.com [127.0.0.1]) by aserp2130.oracle.com (8.16.0.22/8.16.0.22) with SMTP id w1CJvig4060386; Mon, 12 Feb 2018 19:57:44 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=corp-2017-10-26; bh=XmQLkcWhYc7z+xbfoxh5I6+d/nGcfmbEupNi9EvJ2GQ=; b=Z9BpoDaPnM2OejrxPtZBmMQ44upKTvYbNZR8v04ZIjyt7P9qfmBP15GNTEceeBKCRFVs aNrhFih6+5kcB7vEurYQz97Rjuslgb8oO9xNSY8w5W2hUL4TQpTMRDAKawSaUZku/t5t Ej5HxGhqERMhvYOXY0Qfmcx1ajxEHn0ZMY32/Wgm2peDCQCY6GYCm7XGJRpvDtioDETj CMyUYqH8zyzu0RVD6wHkedUrwJdLUEX5FHKTlJCWyDHw+EjqeMOTnCThXM1pZzX+QhgB ASRq9qV8jIy5E8nHUAyqfP0s9ybP8Z4h3zWmaXzTrQk4zWM7+3zQ5D7S3ainT9RTezzf 0g== 
Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp2130.oracle.com with ESMTP id 2g3h7f03sv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 12 Feb 2018 19:57:44 +0000
Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0022.oracle.com (8.14.4/8.14.4) with ESMTP id w1CJvUxC019225 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 12 Feb 2018 19:57:30 GMT
Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id w1CJvTja006672; Mon, 12 Feb 2018 19:57:30 GMT
Received: from [10.145.239.150] (/10.145.239.150) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 12 Feb 2018 11:57:29 -0800
From: "Chris Newman" <chris.newman@oracle.com>
To: "Neil Jenkins" <neilj@fastmailteam.com>
Cc: "IETF JMAP Mailing List" <jmap@ietf.org>
Date: Mon, 12 Feb 2018 11:57:25 -0800
X-Mailer: MailMate (1.10r5443)
Message-ID: <60D63DE9-FC7F-430B-9C0E-42639F83C0F8@oracle.com>
In-Reply-To: <1518420407.1012131.1267607120.3E7422B3@webmail.messagingengine.com>
References: <1518070284.168650.1263633200.05C7397A@webmail.messagingengine.com> <1518408506.1699741.1267466096.17DCF605@webmail.messagingengine.com> <1518419708.1006757.1267595536.799BEEC0@webmail.messagingengine.com> <1518420407.1012131.1267607120.3E7422B3@webmail.messagingengine.com>
MIME-Version: 1.0
Content-Type: text/plain; format=flowed
X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8803 signatures=668668
X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1711220000 definitions=main-1802120254
Archived-At: <https://mailarchive.ietf.org/arch/msg/jmap/KQYUwxxSNEWwykhfctwg8U4mVjI>
Subject: Re: [Jmap] New JSON message representation
X-BeenThere: jmap@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: JSON Message Access Protocol <jmap.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/jmap>, <mailto:jmap-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/jmap/>
List-Post: <mailto:jmap@ietf.org>
List-Help: <mailto:jmap-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/jmap>, <mailto:jmap-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 12 Feb 2018 19:57:58 -0000

On 11 Feb 2018, at 23:26, Neil Jenkins wrote:
> An *EmailBodyValue* object has the following properties:
>
>
>    * *value*: String The value of the body part after decoding 
> *Content-Transport-
>      Encoding* and decoding the *Content-Type* charset, if known to 
> the
>      server. The server MAY use heuristics to determine the charset to
>      use for decoding if the charset is unknown, or if no charset is
>      given, or if it believes the charset given is incorrect. Decoding
>      is best-effort and SHOULD insert the unicode replacement 
> character
>      (U+FFFD) and continue when a malformed section is encountered.

I'm fine with this approach, but this does have security considerations. 
I suggest adding to this section:
"See the security considerations section for issues related to heuristic 
determination of content-type and charset."

and here's suggested text for the security considerations:
---
Service providers typically perform security filtering on incoming email 
and it's important the detection of content-type and charset for the 
security filter aligns with the heuristics performed by JMAP servers. 
Servers that apply heuristics to determine the content-type or charset 
for *EmailBodyValue* SHOULD document the heuristics and provide a 
mechanism to turn them off in the event they are misaligned with the 
security filter used at a particular site. Automatic conversion of 
charsets that allow hidden channels for ASCII text, such as UTF-7, have 
been problematic for security filters in the past so server 
implementations can mitigate this risk by having such conversions 
off-by-default and/or separately configurable.
---

		- Chris


From nobody Mon Feb 12 15:19:32 2018
Return-Path: <neilj@fastmailteam.com>
X-Original-To: jmap@ietfa.amsl.com
Delivered-To: jmap@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 0EC0D126C25 for <jmap@ietfa.amsl.com>; Mon, 12 Feb 2018 15:19:31 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.72
X-Spam-Level: 
X-Spam-Status: No, score=-2.72 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=fastmailteam.com header.b=ZBQn+tNJ; dkim=pass (2048-bit key) header.d=messagingengine.com header.b=k650VNdY
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6B4EBoil5g8L for <jmap@ietfa.amsl.com>; Mon, 12 Feb 2018 15:19:29 -0800 (PST)
Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 3C232120726 for <jmap@ietf.org>; Mon, 12 Feb 2018 15:19:29 -0800 (PST)
Received: from betaweb1.internal (betaweb1.nyi.internal [10.202.2.10]) by mailout.nyi.internal (Postfix) with ESMTP id 21D4720CD2; Mon, 12 Feb 2018 18:19:28 -0500 (EST)
Received: from betaweb1 ([::ffff:10.202.2.10]) by betaweb1.internal (MEProxy); Mon, 12 Feb 2018 18:19:28 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= fastmailteam.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=vqxhmC +rNAqdeak37XK5AcTtDBuNNFubikp0BG4uVs0=; b=ZBQn+tNJy8PSlY+HJwihK9 y4fyIufgmkfWiL3NNmjo8xLNHCIIyg4cXkUR3X16Dqor0NqoPCe+I4lEXvFeu54z 8Iu8xouw7GGB+pMeCPmNjuvGDWKmTKCBPefhek8wEIme+AmRmV0F5RO2HWE/L8Dh S8g1VDjQcFumPA0oKKvXAz6uvxAu3GEyErr9H7cU6xLt3toMI1emRyCsFTKbnUgD keHHiF6+Uh163hKuGyx//Jz3VDf25Y4pa40o7P26TPjY/h6qh/cW860HxMD1IQHN FupoehtYz/e4+Dc5gLJsDLU1pITWq+F4oEOw6P8nrV017LVBs6A8qfA8bOq0bUAA ==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; bh=vqxhmC +rNAqdeak37XK5AcTtDBuNNFubikp0BG4uVs0=; b=k650VNdY9iII+1WpCp+YEW +wbBB974jlLLRjhjxyibFPLIGKh5UFLpeapa6ssM3BKIjUhdVkKPega6u0J0n8NR PUwIl5EimHVG0INRv5ubWUaALXLrCuUyDLwRAqfTm0PZA1RB/RWF6FsL77zVwxzf O7xfsqT1X3wQ8uhX2zS2o32e2PkA/3ggXx2vcx1rJHigOjL/oTDjei/I0Y22KnmN zlGHibUUQOzbkeHnwxRT5q1v/Q4XNVprXtng7YGTKnw2mRisJ54ieKb0CvHC8OO7 bYVCmJjUY7aDChks0imCkv5P9xVIopXrzCK/oF/ODxEJV25L3DvUttshRUuDMXMw ==
X-ME-Sender: <xms:ACGCWo9iGffobowYivx9nDQN6G7cxvccmyffJnnh9D_oRSANVggFjQ>
Received: by mailuser.nyi.internal (Postfix, from userid 99) id CF4F4E2479; Mon, 12 Feb 2018 18:19:27 -0500 (EST)
Message-Id: <1518477567.1847888.1268631136.2D834D85@webmail.messagingengine.com>
From: Neil Jenkins <neilj@fastmailteam.com>
To: Chris Newman <chris.newman@oracle.com>
Cc: IETF JMAP Mailing List <jmap@ietf.org>
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Type: multipart/alternative; boundary="_----------=_151847756718478880"
X-Mailer: MessagingEngine.com Webmail Interface - ajax-2ce04827
In-Reply-To: <60D63DE9-FC7F-430B-9C0E-42639F83C0F8@oracle.com>
References: <1518070284.168650.1263633200.05C7397A@webmail.messagingengine.com> <1518408506.1699741.1267466096.17DCF605@webmail.messagingengine.com> <1518419708.1006757.1267595536.799BEEC0@webmail.messagingengine.com> <1518420407.1012131.1267607120.3E7422B3@webmail.messagingengine.com> <60D63DE9-FC7F-430B-9C0E-42639F83C0F8@oracle.com>
Date: Tue, 13 Feb 2018 10:19:27 +1100
Archived-At: <https://mailarchive.ietf.org/arch/msg/jmap/En0dGnzE3PY_ZmlcvIeP8QMs8-I>
Subject: Re: [Jmap] New JSON message representation
X-BeenThere: jmap@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: JSON Message Access Protocol <jmap.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/jmap>, <mailto:jmap-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/jmap/>
List-Post: <mailto:jmap@ietf.org>
List-Help: <mailto:jmap-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/jmap>, <mailto:jmap-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 12 Feb 2018 23:19:31 -0000

This is a multi-part message in MIME format.

--_----------=_151847756718478880
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset="utf-8"

On Tue, 13 Feb 2018, at 6:57 AM, Chris Newman wrote:
> I'm fine with this approach, but this does have security
> considerations.
Agreed. I've already added a security consideration in relation to the
truncation of the value, I'll add in your text regarding heuristic
determination of content-type and charset.
I've created a pull request[1] with the changes. Further comments
welcome either there or on the list. I'd like to merge this in the next
week or two.
Neil.

Links:

  1. https://github.com/jmapio/jmap/pull/175

--_----------=_151847756718478880
Content-Transfer-Encoding: 7bit
Content-Type: text/html; charset="utf-8"

<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">p.MsoNormal,p.MsoNoSpacing{margin:0}</style>
</head>
<body><div>On Tue, 13 Feb 2018, at 6:57 AM, Chris Newman wrote:<br></div>
<blockquote type="cite"><div>I'm fine with this approach, but this does have security considerations.<br></div>
</blockquote><div><br></div>
<div>Agreed. I've already added a security consideration in relation to the truncation of the value, I'll add in your text regarding heuristic determination of content-type and charset.<br></div>
<div><br></div>
<div>I've created <a href="https://github.com/jmapio/jmap/pull/175">a pull request</a> with the changes. Further comments welcome either there or on the list. I'd like to merge this in the next week or two.<br></div>
<div><br></div>
<div>Neil.<br></div>
</body>
</html>

--_----------=_151847756718478880--


From nobody Mon Feb 19 03:15:16 2018
Return-Path: <jfcm@rdlab.org>
X-Original-To: jmap@ietfa.amsl.com
Delivered-To: jmap@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id CBEA21272E1 for <jmap@ietfa.amsl.com>; Mon, 19 Feb 2018 03:15:14 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: 4.316
X-Spam-Level: ****
X-Spam-Status: No, score=4.316 tagged_above=-999 required=5 tests=[BAYES_50=0.8, DATE_IN_PAST_96_XX=3.405, DKIM_SIGNED=0.1, FORGED_MUA_EUDORA=0.001, RCVD_IN_DNSWL_NONE=-0.0001, T_DKIM_INVALID=0.01] autolearn=no autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=fail (2048-bit key) reason="fail (message has been altered)" header.d=rdlab.org
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id yZNYWI2K0rDT for <jmap@ietfa.amsl.com>; Mon, 19 Feb 2018 03:15:14 -0800 (PST)
Received: from host.presenceweb.org (host.presenceweb.org [67.222.106.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 1FC24127286 for <jmap@ietf.org>; Mon, 19 Feb 2018 03:15:14 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=rdlab.org;  s=default; h=Content-Type:Mime-Version:References:In-Reply-To:Subject:From: To:Date:Sender:Reply-To:Message-ID:Cc:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=zQf8zlpY1myh0dlKLUi9m8SHvjgG5TxSPURoNNGZTlY=; b=nX9UMtNu2gsWo5Uh2Ay55IX923 MXcTsT8RgZ3pcJ2Jlzr+PkFN5UHiar+ZTYgx+NLAJXP/qjfbk5XCQNYSW9nHm+W27cHcAmhjuRDm2 hPslLZDcQIkyxjVl+I24FhNyQ2Qwo6bGYh85lhTH9l0VDNnBbW6Jlwtnx2q5IPqAE9zfgCVWnKyBr rbrn17ibQH8QD3ZNdzuzaQVN0LOlnP/E9Jf8fljbB8i/TgSA0+X1+SzBoRwo/OADe/008gyMe77PV CWFPd6C6DwlV0KzIJTdQSYTJ5AzWWe/UtmVmgsfCHNk8mn2WzcPoXaFkpbTCwYMzAxUCdprKiBqtH u6TkUEdQ==;
Received: from gra86-h02-176-142-255-40.dsl.sta.abo.bbox.fr ([176.142.255.40]:62335 helo=Morfin-Morfin.rdlab.org) by host.presenceweb.org with esmtpa (Exim 4.89_1) (envelope-from <jfcm@rdlab.org>) id 1enjPc-0008MR-9T for jmap@ietf.org; Mon, 19 Feb 2018 12:15:12 +0100
X-Mailer: QUALCOMM Windows Eudora Version 7.1.0.9
Date: Tue, 13 Feb 2018 09:18:00 +0100
To: IETF JMAP Mailing List <jmap@ietf.org>
From: JFCM <jfcm@rdlab.org>
In-Reply-To: <500E0B79-200E-4DFA-939A-C3419559743E@oracle.com>
References: <1518070284.168650.1263633200.05C7397A@webmail.messagingengine.com> <500E0B79-200E-4DFA-939A-C3419559743E@oracle.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"; format=flowed
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - host.presenceweb.org
X-AntiAbuse: Original Domain - ietf.org
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - rdlab.org
X-Get-Message-Sender-Via: host.presenceweb.org: authenticated_id: info+rdlab.org/only user confirmed/virtual account not confirmed
X-Authenticated-Sender: host.presenceweb.org: info@rdlab.org
X-Source: 
X-Source-Args: 
X-Source-Dir: 
Message-Id: <20180219111514.1FC24127286@ietfa.amsl.com>
Archived-At: <https://mailarchive.ietf.org/arch/msg/jmap/83Xru_QsF3XGkncl1RH6Sxm-ybE>
Subject: Re: [Jmap] New JSON message representation
X-BeenThere: jmap@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: JSON Message Access Protocol <jmap.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/jmap>, <mailto:jmap-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/jmap/>
List-Post: <mailto:jmap@ietf.org>
List-Help: <mailto:jmap-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/jmap>, <mailto:jmap-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 19 Feb 2018 11:15:15 -0000

On 20:08 09/02/2018, Chris Newman said:
>>  * *receivedAt*: UTCDate (immutable; default: time of creation on
>>    server) The date the email was received by the message store. This is
>>    the *internal date* in IMAP.Header fields
>
>I note the IMAP APPEND command allows this to be client-specified. 
>This is very useful in practice when migrating mail between mail 
>stores. The date the user really wants is when the mail first 
>entered a mailstore owned by the user (or operated on behalf of the 
>user). The date when the mail first entered this particular 
>mailstore is less useful to the end user.

I also have difficulty in corellating this with RFC 2244 modtime 
requirements. I call "neb" the "nebularity" of a user autoritative 
digital resources. The "rgnr" is the immutable "nebReceivedAt" (down 
to the receiving machine cpu cycle). It turns to be terse enough when 
expressed in alphadigital. This was first introduced to time sort 
domain name registration requests (after synchronization in case of 
parallel or back-up registry servers).
jfcm


From nobody Mon Feb 19 03:15:20 2018
Return-Path: <jfcm@rdlab.org>
X-Original-To: jmap@ietfa.amsl.com
Delivered-To: jmap@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id D57F3127286 for <jmap@ietfa.amsl.com>; Mon, 19 Feb 2018 03:15:14 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: 3.516
X-Spam-Level: ***
X-Spam-Status: No, score=3.516 tagged_above=-999 required=5 tests=[BAYES_40=-0.001, DATE_IN_PAST_96_XX=3.405, DKIM_SIGNED=0.1, FORGED_MUA_EUDORA=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, T_DKIM_INVALID=0.01] autolearn=no autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=fail (2048-bit key) reason="fail (message has been altered)" header.d=rdlab.org
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 0Zolq5UTwR4L for <jmap@ietfa.amsl.com>; Mon, 19 Feb 2018 03:15:13 -0800 (PST)
Received: from host.presenceweb.org (host.presenceweb.org [67.222.106.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id E3559124D6C for <jmap@ietf.org>; Mon, 19 Feb 2018 03:15:13 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=rdlab.org;  s=default; h=Content-Type:Mime-Version:References:In-Reply-To:Subject:From: To:Date:Sender:Reply-To:Message-ID:Cc:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=pzfXTJg1iCutuZ00GMs+Y5aE03d29ze9aawOvQxbtfw=; b=p50B/xVaA6Lo92SBVrvldYUpkf 66f0ST+MOAvlamURXkSJa8mt1ox6IVG6sb5z3UjsVmUtAgSwtINyRZv21R63eCXpCND6BCi2cUPwY 3UiS6UdMbi2jFeltzbFLJP+jmqqCLI6rxJPNEB2myYLgoqfC6teqMwgPNiPtT0q0lroVm6F/uebxz eD9r88PaBayWRqOHpWZZYb132U4q9uKFpJfPZEeXjhl8/Br3XnIZaZq5a6MrowzXr1Fl9oRSvgsxs xqOVRWwaOhKixQnAzoLz0IFegzpNLRsv9QaZqED9Uq0+RfllQsLFLpNDwVCCrXa5zYsDW/985u0iO KmwKKJMQ==;
Received: from gra86-h02-176-142-255-40.dsl.sta.abo.bbox.fr ([176.142.255.40]:62335 helo=Morfin-Morfin.rdlab.org) by host.presenceweb.org with esmtpa (Exim 4.89_1) (envelope-from <jfcm@rdlab.org>) id 1enjPb-0008MR-2R; Mon, 19 Feb 2018 12:15:11 +0100
X-Mailer: QUALCOMM Windows Eudora Version 7.1.0.9
Date: Tue, 13 Feb 2018 08:34:04 +0100
To: Alexey Melnikov <alexey.melnikov@isode.com>, Neil Jenkins <neilj@fastmailteam.com>, IETF JMAP Mailing List <jmap@ietf.org>
From: JFCM <jfcm@rdlab.org>
In-Reply-To: <0bb7d2f4-bcba-86ea-12f7-43a59a2f951e@isode.com>
References: <1518070284.168650.1263633200.05C7397A@webmail.messagingengine.com> <0bb7d2f4-bcba-86ea-12f7-43a59a2f951e@isode.com>
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary="=====================_360981181==.ALT"
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - host.presenceweb.org
X-AntiAbuse: Original Domain - ietf.org
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - rdlab.org
X-Get-Message-Sender-Via: host.presenceweb.org: authenticated_id: info+rdlab.org/only user confirmed/virtual account not confirmed
X-Authenticated-Sender: host.presenceweb.org: info@rdlab.org
X-Source: 
X-Source-Args: 
X-Source-Dir: 
Message-Id: <20180219111513.E3559124D6C@ietfa.amsl.com>
Archived-At: <https://mailarchive.ietf.org/arch/msg/jmap/ipv9E9xqWeA6Z8wQwpFJLBws5Ug>
Subject: Re: [Jmap] New JSON message representation
X-BeenThere: jmap@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: JSON Message Access Protocol <jmap.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/jmap>, <mailto:jmap-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/jmap/>
List-Post: <mailto:jmap@ietf.org>
List-Help: <mailto:jmap-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/jmap>, <mailto:jmap-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 19 Feb 2018 11:15:15 -0000

--=====================_360981181==.ALT
Content-Type: text/plain; charset="iso-8859-1"; format=flowed
Content-Transfer-Encoding: 8bit

At 12:41 09/02/2018, Alexey Melnikov wrote:
>I haven't digested your whole email yet, but a very quick comment 
>about keywords:
>
>On 08/02/2018 06:11, Neil Jenkins wrote:
>>Users may add arbitrary keywords to an email. For compatibility 
>>with IMAP, a keyword is a (case-sensitive)
>IMAP keywords are case insensitive. So $MDNSent and $mdnsent are the same.
>>    * string of 1–255 characters in the ASCII subset %x21ââ€"%x7e 
>> (excludes control chars and space), and MUST NOT include any of 
>> these characters: ( ) { ] % * " \
>Probably not including } and [ as well. But I need to double check.

I concur for another reason: internationalization. If we name 
"polynyms" strict computed semantic synonym strings in different 
character sets that support langague diversity. ASCII lowercases turn 
out being a common subset for universal reference (hence English 
being used by the IETF, cf. RFC 3935), through internationalization 
standardization. The main barrier to polynymy is upper cases that 
many languages/charsets do not have. I also note that most of the 
world's users are accustomed to Windows paltforms which are case insensitive.
jfcm  
--=====================_360981181==.ALT
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: 8bit

<html>
<body>
At 12:41 09/02/2018, Alexey Melnikov wrote:<br>
<blockquote type=cite class=cite cite="">I haven't digested your whole
email yet, but a very quick comment about keywords:<br><br>
On 08/02/2018 06:11, Neil Jenkins
wrote:<blockquote type=cite class=cite cite="">
<ul>
Users may add arbitrary keywords to an email. For compatibility with
IMAP, a keyword is a (case-sensitive) </blockquote>
</ul>IMAP keywords are case insensitive. So $MDNSent and $mdnsent are the
same.<blockquote type=cite class=cite cite="">
<ul>
<li>string of 1–255 characters in the ASCII subset %x21ââ€“%x7e (excludes
control chars and space), and MUST NOT include any of these characters: (
) { ] % * &quot; \</blockquote>
</ul>Probably not including } and [ as well. But I need to double
check.</blockquote><br>
I concur for another reason: internationalization. If we name
&quot;polynyms&quot; strict computed semantic synonym strings in
different character sets that support langague diversity. ASCII
lowercases turn out being a common subset for universal reference (hence
English being used by the IETF, cf. RFC 3935), through
internationalization standardization. The main barrier to polynymy is
upper cases that many languages/charsets do not have. I also note that
most of the world's users are accustomed to Windows paltforms which are
case insensitive.<br>
jfcm </body>
</html>

--=====================_360981181==.ALT--


From nobody Tue Feb 27 15:13:53 2018
Return-Path: <agenda@ietf.org>
X-Original-To: jmap@ietf.org
Delivered-To: jmap@ietfa.amsl.com
Received: from ietfa.amsl.com (localhost [IPv6:::1]) by ietfa.amsl.com (Postfix) with ESMTP id 95FE012EAAB; Tue, 27 Feb 2018 15:11:11 -0800 (PST)
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
From: "\"IETF Secretariat\"" <agenda@ietf.org>
To: <brong@fastmailteam.com>, <jmap-chairs@ietf.org>
Cc: jmap@ietf.org, aamelnikov@fastmail.fm
X-Test-IDTracker: no
X-IETF-IDTracker: 6.73.0
Auto-Submitted: auto-generated
Precedence: bulk
Message-ID: <151977307160.5200.17504278755307034977.idtracker@ietfa.amsl.com>
Date: Tue, 27 Feb 2018 15:11:11 -0800
Archived-At: <https://mailarchive.ietf.org/arch/msg/jmap/se8m0WiKLzPdghSGHx9F8KQiIwg>
Subject: [Jmap] jmap - Requested session has been scheduled for IETF 101
X-BeenThere: jmap@ietf.org
X-Mailman-Version: 2.1.22
List-Id: JSON Message Access Protocol <jmap.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/jmap>, <mailto:jmap-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/jmap/>
List-Post: <mailto:jmap@ietf.org>
List-Help: <mailto:jmap-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/jmap>, <mailto:jmap-request@ietf.org?subject=subscribe>
X-List-Received-Date: Tue, 27 Feb 2018 23:11:12 -0000

Dear Bron Gondwana,

The session(s) that you have requested have been scheduled.
Below is the scheduled session information followed by
the original request. 

jmap Session 1 (2:00:00)
    Thursday, Afternoon Session II 1550-1750
    Room Name: Richmond/Chelsea/Tower size: 75
    ---------------------------------------------
    


Request Information:


---------------------------------------------------------
Working Group Name: JSON Mail Access Protocol
Area Name: Applications and Real-Time Area
Session Requester: Bron Gondwana

Number of Sessions: 1
Length of Session(s):  2 Hours
Number of Attendees: 40
Conflicts to Avoid: 
 First Priority: extra dispatch uta artarea dmarc iasa20 mtgvenue saag oauth dcrup doh
 Second Priority: tls httpbis ace lamps core
 Third Priority: quic


People who must be present:
  Neil Jenkins
  Alexey Melnikov
  Barry Leiba
  Bron Gondwana

Resources Requested:
  Experimental Room Setup (U-Shape and classroom, subject to availability)
  Flipcharts: please specify number in Special Requests field

Special Requests:
  One flipchart please

Please avoid Friday as Barry won&#39;t be available.
---------------------------------------------------------

