diff --git a/lib/imap.js b/lib/imap.js index e5e2987..cbc6549 100644 --- a/lib/imap.js +++ b/lib/imap.js @@ -24,6 +24,8 @@ var CRLF = '\r\n', }, RE_LITHEADER = /(?:((?:BODY\[.*\](?:<\d+>)?)?|[^ ]+) )?\{(\d+)\}$/i, RE_UNRESP = /^\* (OK|PREAUTH|NO|BAD)(?:\r\n| (?:\[(.+)\] )?(.+))$/i, + RE_TAGGED_RESP = /^A\d+ (OK|NO|BAD) (?:\[(.+?)\] )?(.+)$/i, + RE_TEXT_CODE = /([^ ]+)(?: (.*))?$/, //RE_ISPARTIAL = /<(\d+)>$/, RE_DBLQ = /"/g, RE_CMD = /^([^ ]+)(?: |$)/, @@ -539,23 +541,29 @@ ImapConnection.prototype.connect = function(loginCb) { case 'OK': if (m[2] === undefined && m[3] === undefined) break; - var code = m[2]; + var code, codeval; + if (m[2]) { + code = RE_TEXT_CODE.exec(m[2]); + codeval = code[2]; + code = code[1].toUpperCase(); + } if (state.status === STATES.NOAUTH) { if (!state.isReady) { clearTimeout(state.tmrConn); state.isReady = true; state.conn.emit('ready'); } - } else if (/^ALERT$/i.test(code)) + } else if (code === 'ALERT') self.emit('alert', m[3]); else if (state.status === STATES.BOXSELECTING) { - if (m = /^UIDVALIDITY (\d+)/i.exec(code)) - state.box.uidvalidity = parseInt(m[1], 10); - else if (m = /^UIDNEXT (\d+)/i.exec(code)) - state.box.uidnext = parseInt(m[1], 10); - else if (m = /^PERMANENTFLAGS \((.*)\)/i.exec(code)) { + if (code === 'UIDVALIDITY') + state.box.uidvalidity = parseInt(codeval, 10); + else if (code === 'UIDNEXT') + state.box.uidnext = parseInt(codeval, 10); + else if (code === 'PERMANENTFLAGS') { var idx, permFlags, keywords; - state.box.permFlags = permFlags = m[1].split(' '); + codeval = codeval.substr(1, codeval.length - 2); + state.box.permFlags = permFlags = codeval.split(' '); if ((idx = state.box.permFlags.indexOf('\\*')) > -1) { state.box.newKeywords = true; permFlags.splice(idx, 1); @@ -570,8 +578,8 @@ ImapConnection.prototype.connect = function(loginCb) { }); } } else if (state.status === STATES.BOXSELECTED) { - if (m = /^UIDVALIDITY (\d+)/i.exec(code)) { - state.box.uidvalidity = parseInt(m[1], 10); + if (code === 'UIDVALIDITY') { + state.box.uidvalidity = parseInt(codeval, 10); self.emit('uidvalidity', state.box.uidvalidity); } } @@ -648,10 +656,11 @@ ImapConnection.prototype.connect = function(loginCb) { } if (typeof requests[0].callback === 'function') { + m = RE_TAGGED_RESP.exec(line); var err = null; var args = requests[0].cbargs, cmdstr = requests[0].cmdstr; - if (line[0] === '+') { + if (!m) { if (requests[0].cmd !== 'APPEND') { err = new Error('Unexpected continuation'); err.level = 'protocol'; @@ -659,7 +668,7 @@ ImapConnection.prototype.connect = function(loginCb) { err.request = cmdstr; } else return requests[0].callback(); - } else if (m = /^A\d+ (NO|BAD) (?:\[(.+?)\] )?(.+)$/i.exec(line)) { + } else if (m[1] !== 'OK') { // m[1]: error type // m[2]: resp-text-code // m[3]: message @@ -680,6 +689,19 @@ ImapConnection.prototype.connect = function(loginCb) { ) && args.length === 0) args.unshift([]); } + if (m) { + var msg = m[3], info; + if (m[2]) { + m = RE_TEXT_CODE.exec(m[2]); + info = { + code: m[1].toUpperCase(), + codeval: m[2], + message: msg + }; + } else + info = { message: msg }; + args.push(info); + } args.unshift(err); requests[0].callback.apply(self, args); }