From 0afe9195d499808eec19cb7fef3400558929055c Mon Sep 17 00:00:00 2001 From: Andrew Sutherland Date: Tue, 11 Nov 2014 12:05:53 -0500 Subject: [PATCH] handle NIL namespace delimiters, update docs We experience the following NAMESPACE command/response on a yahoo.co.jp test account: ``` W6 NAMESPACE * NAMESPACE (("" NIL)) NIL NIL W6 OK NAMESPACE completed ``` The server greeting is: ``` * OK [CAPABILITY IMAP4rev1 ID NAMESPACE UIDPLUS LITERAL+ CHILDREN XAPPLEPUSHSERVICE AUTH=PLAIN AUTH=LOGIN] IMAP4rev1 imapgate-0.7.68_11_1.61475 imap515.mail.kks.yahoo.co.jp ``` The grammar in https://tools.ietf.org/html/rfc2342 says this is legal, although I'm not seeing any examples or semantics: Namespace = nil / "(" 1*( "(" string SP (<"> QUOTED_CHAR <"> / nil) *(Namespace_Response_Extension) ")" ) ")" I've opted to have the value pass through as null rather than normalizing it. This is inconsistent with browserbox's current behaviour for LIST/LSUB in this case (which I submitted the patches for). In those cases we normalize to '/', which I didn't have a great reason for, but I also didn't know what else to do. It may make sense to revisit that decision in the future. I've updated the docs to reflect the current behaviour and that it may change. In this case it seems like if we're reporting the namespace at all we might as well report a falsey value so any consuming logic can know that the value is not to be trusted and should use the delimiter reported by LIST/LSUB. I do think we want to report the namespace since the root of "" is useful. For reference, this is what LIST/LSUB looks like for the (freshly created) account: ``` W4 LIST * LIST (\\NoInferiors \\HasNoChildren) "/" "Bulk Mail" * LIST (\\NoInferiors \\HasNoChildren) "/" "Draft" * LIST (\\NoInferiors \\HasNoChildren) "/" "Inbox" * LIST (\\NoInferiors \\HasNoChildren) "/" "Sent" * LIST (\\NoInferiors \\HasNoChildren) "/" "Trash" W4 OK LIST completed W5 LSUB * LSUB (\\NoInferiors \\HasNoChildren) "/" "Bulk Mail" * LSUB (\\NoInferiors \\HasNoChildren) "/" "Draft" * LSUB (\\NoInferiors \\HasNoChildren) "/" "Inbox" * LSUB (\\NoInferiors \\HasNoChildren) "/" "Sent" * LSUB (\\NoInferiors \\HasNoChildren) "/" "Trash" W5 OK LSUB completed ``` --- README.md | 4 ++-- src/browserbox.js | 3 ++- test/unit/browserbox-test.js | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 52e74f77..7856a345 100644 --- a/README.md +++ b/README.md @@ -139,7 +139,7 @@ Mailbox object is with the following structure * **root** (boolean) `true` if the node is root * **name** (string) unicode decoded name of the mailbox * **path** (string) full path to the mailbox - * **delimiter** (string) path delimiting symbol + * **delimiter** (string) path delimiting symbol. In the event the server returns NIL for this (some servers do this for the INBOX), it will be coerced to a '/' at this time, but the behavior may be changed in the future depending on how the folder creation API is implemented. * **listed** (boolean) mailbox was found in the LIST response * **subscribed** (boolean) mailbox was found in the LSUB response * **specialUse** (string) mailbox was identified as a special use mailbox ('\Trash', '\Sent', '\Junk' etc. see [RFC6154](http://tools.ietf.org/html/rfc6154#section-2)) @@ -247,7 +247,7 @@ Namespace object is with the following structure Namespace element object has the following structure * **prefix** is the prefix string - * **delimiter** is the hierarchy delimiter + * **delimiter** is the hierarchy delimiter. This can be null for some servers but will usually be a string. **NB!** Namespace_Response_Extensions are not supported (extension data is silently skipped) diff --git a/src/browserbox.js b/src/browserbox.js index e90a7237..38ea1f6a 100644 --- a/src/browserbox.js +++ b/src/browserbox.js @@ -1196,7 +1196,8 @@ return !arr ? false : [].concat(arr || []).map(function(ns) { return !ns || !ns.length ? false : { prefix: ns[0].value, - delimiter: ns[1].value + // The delimiter can legally be NIL which maps to null + delimiter: ns[1] && ns[1].value }; }); }; diff --git a/test/unit/browserbox-test.js b/test/unit/browserbox-test.js index 3c1b7c1c..14664cdb 100644 --- a/test/unit/browserbox-test.js +++ b/test/unit/browserbox-test.js @@ -1194,7 +1194,25 @@ delimiter: '/' }] }); + }); + it('should handle NIL namespace hierarchy delim', function() { + expect(br._parseNAMESPACE({ + payload: { + NAMESPACE: [ + // This specific value is returned by yahoo.co.jp's + // imapgate version 0.7.68_11_1.61475 IMAP server + imapHandler.parser('* NAMESPACE (("" NIL)) NIL NIL') + ] + } + })).to.deep.equal({ + personal: [{ + prefix: '', + delimiter: null + }], + users: false, + shared: false + }); }); });