Subject: Re: [Jmap] Review of draft-ietf-jmap-mail-06

From: Stephan Bosch <[email-masked]>
Date: Sun, 5 Aug 2018 09:30:07 +0200

Hi,

Got some more small editorial stuff:

Op 30/07/2018 om 17:53 schreef Stephan Bosch:
> Hi,
>
> Here are some of the comments and suggestions I collected while 
> reading draft-ietf-jmap-mail-06. As stated in my previous review, I 
> haven't followed the discussions and developments much lately, so 
> there could be some stuff there (design choices) that is obvious to 
> everyone else, but not to me. Some comments may therefore be redundant.
>
> Text from the document itself is pasted here as-is. My comments are 
> prefixed with "-> ".
>

## Section 4.2.1

-> The example is missing a comma after "header:List-POST:asURLs". I 
recommend feeding all examples to (at least) a JSON validator.

## Section 4.7

-> Missing colon after *mailboxIds*.

## Section 8

-> Missing colon after *isEnabled*

Regards,

Stephan.

---

From: Neil Jenkins <[email-masked]>
Date: Tue, 07 Aug 2018 02:29:50 -0400

Hi Stephen,

Thanks again for the review. Again, I've made changes to account for your comments and suggestions, which I will publish as a new draft shortly. In answer to your questions:

On Tue, 31 Jul 2018, at 1:53 AM, Stephan Bosch wrote:
> This may be any Net-Unicode string ([RFC5198]) of at least 1
> character in length and maximum 255 octets in size.
> -> 255 octets could be very limited for languages involving multi-byte
> characters. Could this perhaps be a server capability property? Where 
> does this limit come from anyway? IMAP?

255 octets was just chosen as a reasonable limit for the length of a mailbox name (note, this is not an IMAP-like path—the length of any parent's name is not important). It's 255 to allow it to fit null terminated in 256 bytes.

We could make this a capability, but it just didn't seem important enough.

> -> Also, stating the limit in octets rather than UTF-8 characters (or 
> maybe just codepoints) makes this inconsistent between languages (for 
> display).

The limit is in octets as it's a limit on how much space the server can be required to use.

> -> Is there a maximum mailbox hierarchy depth? How would the client know 
> about it? What minimum depth must be supported by any server?

At the moment there is no limit on this (other than the limit the server can set on the overall total number of mailboxes in the account); I don't believe there's one in IMAP either. We can certainly add this though if you think it's important?

> -> How are IMAP namespaces mapped to JMAP? More specifically: how are 
> personal and shared mailboxes identified in JMAP?

They would be presented as different JMAP accounts <https://jmap.io/spec-core.html#terminology> the user has access to. The primary account would (normally) be the one belonging to the user.

> ## Section 2.3:
> -> How to find a mailbox by name without downloading the full list?

Hmm, there wasn't actually a way to search by name. I've added this to the Mailbox/query filter options, so you could do this:

[[ "Mailbox/query", {
  "filter": { "name": "Interesting Stuff" },
  "position": 0,
  "limit": 1,
}, "t0" ],
[ "Mailbox/get", {
  "#ids": {
    "resultOf": "t0",
    "name": "Mailbox/query",
    "path": "/ids"
  }
}, "t1" ]]

> -> Should wildcard name queries be possible?

Can you explain what your use-case is here?

> -> Why only *hasRole* and not allow query for a specific *role* and a 
> value of "*" meaning any? I think this could be particularly useful for 
> backreferences to operate on a specific mailbox by role rather than id 
> or name.

I've added the ability to query for a specific role.

> -> Comparing to IMAP LIST-EXTENDED: Would filters for *hasChildren* be useful?

Maybe? What's the use-case again?

> ## Section 4.1.1:
> 
>        *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".
> -> Why is this an object?

Firstly because the order is unimportant, and arrays are ordered (JSON doesn't have a "set" type). But more importantly this allows you to use patch syntax to update it (e.g. see the examples section <https://jmap.io/spec-core.html#examples> in the core API for examples of how patching works).

> -> Could we define savedAt already (IMAP SAVEDATE)?

I think this would probably be better off as an extension, with its own capability string.

Neil.

---

From: Bron Gondwana <[email-masked]>
Date: Tue, 07 Aug 2018 22:58:56 +1000

On Tue, Aug 7, 2018, at 16:29, Neil Jenkins wrote:
> Hi Stephen,
> 
> Thanks again for the review. Again, I've made changes to account for
> your comments and suggestions, which I will publish as a new draft
> shortly. In answer to your questions:> 
>> -> 255 octets could be very limited for languages involving
>> multi-byte>> characters. Could this perhaps be a server capability property? Where>> does this limit come from anyway? IMAP?
> 
> 255 octets was just chosen as a reasonable limit for the length of a
> mailbox name (note, this is not an IMAP-like path—the length of any
> parent's name is not important). It's 255 to allow it to fit null
> terminated in 256 bytes.> 
Another potentially sane option is 1024 bytes.  Even 255 bytes is still
a LONG name even in multibyte characters, but I'd be happy to consider
1024 for display names and keep IDs at 255.  Otherwise I have to go back
and suggest OBJECTID gets edited over in EXTRA land.
> 
>> -> Also, stating the limit in octets rather than UTF-8 characters (or>> maybe just codepoints) makes this inconsistent between languages (for>> display).
> 
This I fully support. Octets are a sane thing for limits, especially if
they're high enough that people won't usually hit them.  Certainly
Cyrus' mailbox length limits are the 7-bit encoded version, because
that's what gets stored via IMAP.
>> -> Is there a maximum mailbox hierarchy depth? How would the
>> client know>> about it? What minimum depth must be supported by any server?
> 
> At the moment there is no limit on this (other than the limit the
> server can set on the overall total number of mailboxes in the
> account); I don't believe there's one in IMAP either. We can certainly
> add this though if you think it's important?
I'm happy with that.  Cyrus' current limitation is purely the length of
the internal version of the mailbox name, but you could create A.A.A.A
out to MAX_MAILBOX_NAME.  Annoyingly, some buggy clients did that with
INBOX.INBOX.INBOX... such that we special-case reject that now.
>> -> How are IMAP namespaces mapped to JMAP? More specifically: how are>> personal and shared mailboxes identified in JMAP?
> 
> They would be presented as different JMAP accounts[1] the user has
> access to. The primary account would (normally) be the one belonging
> to the user.> 
>> ## Section 2.3:
> Hmm, there wasn't actually a way to search by name. I've added this to
> the Mailbox/query filter options, so you could do this:>
> [[ "Mailbox/query", { "filter": { "name": "Interesting Stuff" },
> "position": 0, "limit": 1, }, "t0" ], [ "Mailbox/get", { "#ids": {
> "resultOf": "t0", "name": "Mailbox/query", "path": "/ids" } }, "t1" ]]
This does raise the question of some kind of recursively applied query
(includeParents) for tree-as-nodes types.  I'd say that's a thing to
address in an extension though, if at all.
> Can you explain what your use-case is here?

I assume this is search where you enter a couple of characters and want
mailboxes which match those characters anywhere in the name, or just at
the start...
>> -> Why only *hasRole* and not allow query for a specific *role* and a>> value of "*" meaning any? I think this could be particularly
>> useful for>> backreferences to operate on a specific mailbox by role rather
>> than id>> or name.
> 

I swear I wrote this during IETF102 :p

But yeah, good point - I'd use this in test cases :)

> 
>> -> Comparing to IMAP LIST-EXTENDED: Would filters for *hasChildren*
>> be useful?> 

The shitty thing with hasChildren is dealing with changes.  Do you touch
the parent when adding/removing a child such that it appears in the
/changes response?
>> ## Section 4.1.1:
>> 
>>        *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".
> Firstly because the order is unimportant, and arrays are ordered (JSON
> doesn't have a "set" type). But more importantly this allows you to
> use patch syntax to update it (e.g. see the examples section[2] in the
> core API for examples of how patching works).> 
See also my proposed (and very much shot down) IMAPDATA extension!  One
issue with SAVEDATE is that it's per mailbox, and hence it wouldn't be a
single value - it would be a map from mailboxId to the value for that
mailbox, assuming a server which supports multiple mailboxes.
Bron.

--
  Bron Gondwana, CEO, FastMail Pty Ltd
  [email-masked]

Links:

  1. https://jmap.io/spec-core.html#terminology
  2. https://jmap.io/spec-core.html#examples

---

From: Stephan Bosch <[email-masked]>
Date: Sun, 19 Aug 2018 01:38:20 +0200

Hi,

Op 07/08/2018 om 14:58 schreef Bron Gondwana:
>> shortly. In answer to your questions:
>>
>> terminated in 256 bytes.
> Another potentially sane option is 1024 bytes.  Even 255 bytes is 
> still a LONG name even in multibyte characters, but I'd be happy to 
> consider 1024 for display names and keep IDs at 255.  Otherwise I have 
> to go back and suggest OBJECTID gets edited over in EXTRA land.

I am mainly concerned about strings that the user will get to see: the 
IDs are not in that realm. I am just saying that a 
specification-enforced limit will hit the multi-byte character languages 
(think e.g. Japanese) more than english. So, while 255 octets ought to 
be enough for everyone, it might not be. I agree 1024 is less likely to 
be too limited, but still: is a capability property really such a burden?

> This I fully support. Octets are a sane thing for limits, especially 
> if they're high enough that people won't usually hit them.  Certainly 

Same point about a specification-enforced limit hitting the multi-byte 
character languages more than english.

>> account); I don't believe there's one in IMAP either. We can 
>> certainly add this though if you think it's important?
>
> I'm happy with that.  Cyrus' current limitation is purely the length 
> of the internal version of the mailbox name, but you could create 
> A.A.A.A out to MAX_MAILBOX_NAME.  Annoyingly, some buggy clients did 
> that with INBOX.INBOX.INBOX... such that we special-case reject that now.

I am just mentioning this to make sure it is considered. I am a bit too 
lazy to look, but do we have a sensible error code for this (e.g. when 
filesystem storage hits PATH_MAX)?

>> They would be presented as different JMAP accounts 
>> <https://jmap.io/spec-core.html#terminology> the user has access to. 
>> The primary account would (normally) be the one belonging to the user.

Ok. Then do we need to add a flag that signifies an account as being 
shared/public, so that the client can present mailboxes and other 
objects therein as such? There could e.g. also be an Archive account 
that is still personal, but not primary.

>> Hmm, there wasn't actually a way to search by name. I've added this 
>> to the Mailbox/query filter options, so you could do this:
>>
>> [[ "Mailbox/query", {
> I assume this is search where you enter a couple of characters and 
> want mailboxes which match those characters anywhere in the name, or 
> just at the start...

Yeah, I am just comparing some IMAP features here. Why does IMAP support 
wildcards in LIST? Answers should be similar.

> But yeah, good point - I'd use this in test cases :)

Ok.

>>> be useful?
> The shitty thing with hasChildren is dealing with changes.  Do you 
> touch the parent when adding/removing a child such that it appears in 
> the /changes response?

Again: just comparing some IMAP features here.

>> Firstly because the order is unimportant, and arrays are ordered 
>> (JSON doesn't have a "set" type). But more importantly this allows 
>> you to use patch syntax to update it (e.g. see the examples section 
>> <https://jmap.io/spec-core.html#examples> in the core API for 
>> examples of how patching works).

Ah, right. Maybe mention that and refer to the section in which the 
patching is explained.

> See also my proposed (and very much shot down) IMAPDATA extension!  
> One issue with SAVEDATE is that it's per mailbox, and hence it 
> wouldn't be a single value - it would be a map from mailboxId to the 
> value for that mailbox, assuming a server which supports multiple 
> mailboxes.
>
Yeah Ok.

Regards,

Stephan.

---

From: Neil Jenkins <[email-masked]>
Date: Wed, 29 Aug 2018 02:02:00 -0400

Hi

> I am mainly concerned about strings that the user will get to see:
    the IDs are not in that realm. I am just saying that a
    specification-enforced limit will hit the multi-byte character
    languages (think e.g. Japanese) more than english. So, while 255
    octets ought to be enough for everyone, it might not be. I agree
    1024 is less likely to be too limited, but still: is a capability
    property really such a burden?

For the reasons explained before I think the limit should be specified in octets (if clients want to give the user a guaranteed UTF-8 character limit they can always just divide this by 4…). However, I guess we can make the actual value of the limit a capability. We probably want to add:
 * *maxMailboxDepth*: PositiveInt|null
The maximum depth of the mailbox hierarchy (i.e. one less than the maximum number of ancestors a mailbox may have), or null for no limit.
 * *maxSizeMailboxName*: PositiveInt
The maximum length, in (UTF-8) octets, allowed for the name of a mailbox. This MUST be >= 255.

>> I'm happy with that.  Cyrus'
        current limitation is purely the length of the internal version
        of the mailbox name, but you could create A.A.A.A out to
        MAX_MAILBOX_NAME.  Annoyingly, some buggy clients did that with
        INBOX.INBOX.INBOX... such that we special-case reject that now.

Explaining that kind of limit to users is … hard. Renaming folder X may fail even though the new name is a reasonable length, because the combined length with some of its descendants could now be too long — ouch. The server is free to reject the change with an invalidProperties error response though of course, which is fine. I don't think this should be a capability though.
 
>>> They would be presented as different JMAP accounts <https://jmap.io/spec-core.html#terminology> the user has access to.
          The primary account would (normally) be the one belonging to
          the user.

Hmm, yes that's probably reasonable. I think a simple boolean on each account object would suffice; something like "isYours": true|false (or isUser or isPersonal… naming things is hard). Thoughts on the name?

>>> Firstly because the order is unimportant, and arrays are
          ordered (JSON doesn't have a "set" type). But more importantly
          this allows you to use patch syntax to update it (e.g. see the examples section <https://jmap.io/spec-core.html#examples> in the core API
          for examples of how patching works).
    patching is explained.

OK, will do.

Neil.