New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

imap

Package Overview
Dependencies
Maintainers
1
Versions
54
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

imap - npm Package Compare versions

Comparing version 0.2.3 to 0.2.4

536

imap.js
var util = require('util'), net = require('net'),
tls = require('tls'), EventEmitter = require('events').EventEmitter;
var emptyFn = function() {}, CRLF = "\r\n", debug=emptyFn,
var emptyFn = function() {}, CRLF = '\r\n', debug=emptyFn,
STATES = {

@@ -10,3 +10,4 @@ NOCONNECT: 0,

BOXSELECTED: 4
}, BOX_ATTRIBS = ['NOINFERIORS', 'NOSELECT', 'MARKED', 'UNMARKED'];
}, BOX_ATTRIBS = ['NOINFERIORS', 'NOSELECT', 'MARKED', 'UNMARKED'],
reFetch = /^\* \d+ FETCH .+? \{(\d+)\}\r\n/;

@@ -38,3 +39,3 @@ function ImapConnection (options) {

tmrConn: null,
curData: '',
curData: null,
curExpected: 0,

@@ -75,3 +76,4 @@ curXferred: 0,

fnInit = function() {
// First get pre-auth capabilities, including server-supported auth mechanisms
// First get pre-auth capabilities, including server-supported auth
// mechanisms
self._send('CAPABILITY', function() {

@@ -87,7 +89,9 @@ // Next, attempt to login

var fnMe = arguments.callee;
// Re-enter this function after we've obtained the available namespaces
// Re-enter this function after we've obtained the available
// namespaces
self._send('NAMESPACE', function(e) { fnMe.call(this, e, true); });
return;
}
// Lastly, get the top-level mailbox hierarchy delimiter used by the server
// Lastly, get the top-level mailbox hierarchy delimiter used by the
// server
self._send('LIST "" ""', loginCb);

@@ -102,3 +106,4 @@ });

this._state.tmrConn = setTimeout(this._fnTmrConn, this._options.connTimeout, loginCb);
this._state.tmrConn = setTimeout(this._fnTmrConn.bind(this),
this._options.connTimeout, loginCb);
this._state.conn.setKeepAlive(true);

@@ -112,5 +117,5 @@

});
this._state.conn.cleartext.setEncoding('utf8');
//this._state.conn.cleartext.setEncoding('utf8');
} else {
this._state.conn.setEncoding('utf8');
//this._state.conn.setEncoding('utf8');
this._state.conn.cleartext = this._state.conn;

@@ -131,12 +136,15 @@ }

var trailingCRLF = false, literalInfo;
debug('\n<<RECEIVED>>: ' + util.inspect(data) + '\n');
debug('\n<<RECEIVED>>: ' + util.inspect(data.toString()) + '\n');
if (self._state.curExpected === 0) {
if (data.indexOf(CRLF) === -1) {
self._state.curData += data;
if (self._state.curData)
self._state.curData = self._state.curData.add(data);
else
self._state.curData = data;
return;
}
if (self._state.curData.length) {
data = self._state.curData + data;
self._state.curData = '';
if (self._state.curData && self._state.curData.length) {
data = self._state.curData.add(data);
self._state.curData = null;
}

@@ -151,8 +159,9 @@ }

var chunk = data;
self._state.curXferred += Buffer.byteLength(data, 'utf8');
self._state.curXferred += data.length;
if (self._state.curXferred > self._state.curExpected) {
var pos = Buffer.byteLength(data, 'utf8')-(self._state.curXferred-self._state.curExpected),
extra = (new Buffer(data)).slice(pos).toString('utf8');
var pos = data.length
- (self._state.curXferred - self._state.curExpected),
extra = data.slice(pos);
if (pos > 0)
chunk = (new Buffer(data)).slice(0, pos).toString('utf8');
chunk = data.slice(0, pos);
else

@@ -164,5 +173,7 @@ chunk = undefined;

if (chunk) {
if (curReq._msgtype === 'headers')
self._state.curData += chunk;
if (chunk && chunk.length) {
if (curReq._msgtype === 'headers') {
self._state.curData.append(chunk, curReq.curPos);
curReq.curPos += chunk.length;
}
else

@@ -176,9 +187,13 @@ curReq._msg.emit('data', chunk);

if (curReq._msgtype === 'headers')
curReq._headers = self._state.curData;
self._state.curData = '';
curReq._headers = self._state.curData.toString();
self._state.curData = null;
curReq._done = true;
}
self._state.curData += data;
if (restDesc = self._state.curData.match(/^(.*?)\)\r\n/)) {
if (self._state.curData)
self._state.curData = self._state.curData.add(data);
else
self._state.curData = data;
if (restDesc = self._state.curData.toString().match(/^(.*?)\)\r\n/)) {
if (restDesc[1]) {

@@ -191,9 +206,10 @@ restDesc[1] = restDesc[1].trim();

parseFetch(curReq._desc + restDesc[1], curReq._headers, curReq._msg);
data = self._state.curData.substring(self._state.curData.indexOf(CRLF) + 2);
data = self._state.curData.slice(self._state.curData.indexOf(CRLF)
+ 2);
curReq._done = false;
self._state.curXferred = 0;
self._state.curExpected = 0;
self._state.curData = '';
self._state.curData = null;
curReq._msg.emit('end');
if (data.length && data[0] === '*') {
if (data.length && data[0] === 42/* '*' */) {
self._state.conn.cleartext.emit('data', data);

@@ -207,9 +223,10 @@ return;

} else if (self._state.curExpected === 0
&& (literalInfo = data.match(/^\* \d+ FETCH .+? \{(\d+)\}\r\n/))) {
&& (literalInfo = data.toString().match(reFetch))) {
self._state.curExpected = parseInt(literalInfo[1], 10);
var idxCRLF = data.indexOf(CRLF),
curReq = self._state.requests[0],
type = /BODY\[(.*)\](?:\<\d+\>)?/.exec(data.substring(0, idxCRLF)),
type = /BODY\[(.*)\](?:\<\d+\>)?/
.exec(data.toString().substring(0, idxCRLF)),
msg = new ImapMessage(),
desc = data.substring(data.indexOf("(")+1, idxCRLF).trim();
desc = data.toString().substring(data.indexOf('(')+1, idxCRLF).trim();
type = type[1];

@@ -220,3 +237,7 @@ curReq._desc = desc;

curReq._msgtype = (type.indexOf('HEADER') === 0 ? 'headers' : 'body');
self._state.conn.cleartext.emit('data', data.substring(idxCRLF + 2));
if (curReq._msgtype === 'headers') {
self._state.curData = new Buffer(self._state.curExpected);
curReq.curPos = 0;
}
self._state.conn.cleartext.emit('data', data.slice(idxCRLF + 2));
return;

@@ -227,18 +248,28 @@ }

return;
data = data.split(CRLF).filter(isNotEmpty);
var endsInCRLF = (data[data.length-2] === 13 && data[data.length-1] === 10);
data = data.split(CRLF);
// Defer any extra server responses found in the incoming data
if (data.length > 1) {
data.slice(1).forEach(function(line) {
process.nextTick(function() {
self._state.conn.cleartext.emit('data', line + CRLF);
});
});
for (var i=1,len=data.length; i<len; ++i) {
(function(line, isLast) {
process.nextTick(function() {
var needsCRLF = !isLast || (isLast && endsInCRLF),
b = new Buffer(needsCRLF ? line.length + 2 : line.length);
line.copy(b, 0, 0);
if (needsCRLF) {
b[b.length-2] = 13;
b[b.length-1] = 10;
}
self._state.conn.cleartext.emit('data', b);
});
})(data[i], i === len-1);
}
}
data = data[0].explode(' ', 3);
data = data[0].toString().explode(' ', 3);
if (data[0] === '*') { // Untagged server response
if (self._state.status === STATES.NOAUTH) {
if (data[1] === 'PREAUTH') { // no need to login, the server pre-authenticated us
if (data[1] === 'PREAUTH') { // the server pre-authenticated us
self._state.status = STATES.AUTH;

@@ -266,15 +297,19 @@ if (self._state.numCapRecvs === 0)

case 'FLAGS':
if (self._state.status === STATES.BOXSELECTING)
self._state.box._flags = data[2].substr(1, data[2].length-2).split(' ').map(function(flag) {return flag.substr(1);});;
if (self._state.status === STATES.BOXSELECTING) {
self._state.box._flags = data[2].substr(1, data[2].length-2)
.split(' ').map(function(flag) {
return flag.substr(1);
});
}
break;
case 'OK':
if ((result = /^\[ALERT\] (.*)$/i.exec(data[2])) !== null)
if (result = /^\[ALERT\] (.*)$/i.exec(data[2]))
self.emit('alert', result[1]);
else if (self._state.status === STATES.BOXSELECTING) {
var result;
if ((result = /^\[UIDVALIDITY (\d+)\]$/i.exec(data[2])) !== null)
if (result = /^\[UIDVALIDITY (\d+)\]/i.exec(data[2]))
self._state.box.validity = result[1];
else if ((result = /^\[UIDNEXT (\d+)\]$/i.exec(data[2])) !== null)
else if (result = /^\[UIDNEXT (\d+)\]/i.exec(data[2]))
self._state.box._uidnext = result[1];
else if ((result = /^\[PERMANENTFLAGS \((.*)\)\]$/i.exec(data[2])) !== null) {
else if (result = /^\[PERMANENTFLAGS \((.*)\)\]/i.exec(data[2])) {
self._state.box.permFlags = result[1].split(' ');

@@ -286,6 +321,12 @@ var idx;

}
self._state.box.keywords = self._state.box.permFlags.filter(function(flag) {return flag[0] !== '\\';});
self._state.box.keywords = self._state.box.permFlags
.filter(function(flag) {
return (flag[0] !== '\\');
});
for (var i=0; i<self._state.box.keywords.length; i++)
self._state.box.permFlags.splice(self._state.box.permFlags.indexOf(self._state.box.keywords[i]), 1);
self._state.box.permFlags = self._state.box.permFlags.map(function(flag) {return flag.substr(1);});
self._state.box.permFlags = self._state.box.permFlags
.map(function(flag) {
return flag.substr(1);
});
}

@@ -298,3 +339,5 @@ }

case 'SEARCH':
self._state.requests[0].args.push((typeof data[2] === 'undefined' || data[2].length === 0 ? [] : data[2].split(' ')));
self._state.requests[0].args.push(typeof data[2] === 'undefined'
|| data[2].length === 0
? [] : data[2].split(' '));
break;

@@ -307,12 +350,18 @@ /*case 'STATUS':

var result;
if (self.delim === null && (result = /^\(\\Noselect\) (.+?) ".*"$/.exec(data[2])) !== null)
self.delim = (result[1] === 'NIL' ? false : result[1].substring(1, result[1].length-1));
if (self.delim === null
&& (result = /^\(\\No[sS]elect\) (.+?) .*$/.exec(data[2])))
self.delim = (result[1] === 'NIL'
? false : result[1].substring(1, result[1].length-1));
else if (self.delim !== null) {
if (self._state.requests[0].args.length === 0)
self._state.requests[0].args.push({});
result = /^\((.*)\) (.+?) "(.+)"$/.exec(data[2]);
result = /^\((.*)\) (.+?) "?(.+)"?$/.exec(data[2]);
var box = {
attribs: result[1].split(' ').map(function(attrib) {return attrib.substr(1).toUpperCase();})
.filter(function(attrib) {return BOX_ATTRIBS.indexOf(attrib) > -1;}),
delim: (result[2] === 'NIL' ? false : result[2].substring(1, result[2].length-1)),
attribs: result[1].split(' ').map(function(attrib) {
return attrib.substr(1).toUpperCase();
}).filter(function(attrib) {
return (BOX_ATTRIBS.indexOf(attrib) > -1);
}),
delim: (result[2] === 'NIL'
? false : result[2].substring(1, result[2].length-1)),
children: null,

@@ -323,3 +372,4 @@ parent: null

if (box.delim) {
var path = name.split(box.delim).filter(isNotEmpty), parent = null;
var path = name.split(box.delim).filter(isNotEmpty),
parent = null;
name = path.pop();

@@ -342,3 +392,4 @@ for (var i=0,len=path.length; i<len; i++) {

switch (data[2]) {
case 'EXISTS': // mailbox total message count
case 'EXISTS':
// mailbox total message count
var prev = self._state.box.messages.total,

@@ -349,9 +400,11 @@ now = parseInt(data[1]);

self._state.box.messages.new = now-prev;
self.emit('mail', self._state.box.messages.new); // new mail notification
self.emit('mail', self._state.box.messages.new); // new mail
}
break;
case 'RECENT': // messages marked with the \Recent flag (i.e. new messages)
case 'RECENT':
// messages marked with the \Recent flag (i.e. new messages)
self._state.box.messages.new = parseInt(data[1]);
break;
case 'EXPUNGE': // confirms permanent deletion of a single message
case 'EXPUNGE':
// confirms permanent deletion of a single message
if (self._state.box.messages.total > 0)

@@ -361,6 +414,9 @@ self._state.box.messages.total--;

default:
if (/^FETCH/.test(data[2])) { // fetches without header or body (part) retrievals
// fetches without header or body (part) retrievals
if (/^FETCH/.test(data[2])) {
var curReq = self._state.requests[0],
msg = new ImapMessage();
parseFetch(data[2].substring(data[2].indexOf("(")+1, data[2].lastIndexOf(")")), "", msg);
parseFetch(data[2].substring(data[2].indexOf("(")+1,
data[2].lastIndexOf(")")),
"", msg);
curReq._fetcher.emit('message', msg);

@@ -394,3 +450,4 @@ msg.emit('end');

var err = null;
var args = self._state.requests[0].args, cmd = self._state.requests[0].command;
var args = self._state.requests[0].args,
cmd = self._state.requests[0].command;
if (data[1] !== 'OK') {

@@ -403,5 +460,8 @@ err = new Error('Error while executing request: ' + data[2]);

args.unshift(self._state.box);
// According to RFC 3501, UID commands do not give errors for non-existant user-supplied UIDs,
// so give the callback empty results if we unexpectedly received no untagged responses.
else if ((cmd.indexOf('UID FETCH') === 0 || cmd.indexOf('UID SEARCH') === 0) && args.length === 0)
// According to RFC 3501, UID commands do not give errors for
// non-existant user-supplied UIDs, so give the callback empty results
// if we unexpectedly received no untagged responses.
else if ((cmd.indexOf('UID FETCH') === 0
|| cmd.indexOf('UID SEARCH') === 0
) && args.length === 0)
args.unshift([]);

@@ -495,3 +555,4 @@ }

ImapConnection.prototype.closeBox = function(cb) { // also deletes any messages in this box marked with \Deleted
// also deletes any messages in this box marked with \Deleted
ImapConnection.prototype.closeBox = function(cb) {
var self = this;

@@ -527,3 +588,4 @@ if (this._state.status !== STATES.BOXSELECTED)

if (typeof name !== 'string' || name.length === 0)
throw new Error('Mailbox name must be a string describing the full path of a new mailbox to be created');
throw new Error('Mailbox name must be a string describing the full path'
+ ' of a new mailbox to be created');
this._send('CREATE "' + escape(name) + '"', cb);

@@ -535,3 +597,4 @@ };

if (typeof name !== 'string' || name.length === 0)
throw new Error('Mailbox name must be a string describing the full path of an existing mailbox to be deleted');
throw new Error('Mailbox name must be a string describing the full path'
+ ' of an existing mailbox to be deleted');
this._send('DELETE "' + escape(name) + '"', cb);

@@ -543,6 +606,9 @@ };

if (typeof oldname !== 'string' || oldname.length === 0)
throw new Error('Old mailbox name must be a string describing the full path of an existing mailbox to be renamed');
throw new Error('Old mailbox name must be a string describing the full path'
+ ' of an existing mailbox to be renamed');
else if (typeof newname !== 'string' || newname.length === 0)
throw new Error('New mailbox name must be a string describing the full path of a new mailbox to be renamed to');
if (this._state.status === STATES.BOXSELECTED && oldname === this._state.box.name && oldname !== 'INBOX')
throw new Error('New mailbox name must be a string describing the full path'
+ ' of a new mailbox to be renamed to');
if (this._state.status === STATES.BOXSELECTED
&& oldname === this._state.box.name && oldname !== 'INBOX')
this._state.box._newName = oldname;

@@ -580,3 +646,4 @@

struct: true,
headers: true, // \_______ at most one of these can be used for any given fetch request
headers: true, // \_______ at most one of these can be used for any given
// _______ fetch request
body: false // /

@@ -593,3 +660,3 @@ }

if (opts.request.body.length !== 2)
throw new Error("Expected Array of length 2 for body property for byte range");
throw new Error("Expected Array of length 2 for body byte range");
else if (typeof opts.request.body[1] !== 'string'

@@ -599,20 +666,35 @@ || !(rangeInfo = /^([\d]+)\-([\d]+)$/.exec(opts.request.body[1]))

throw new Error("Invalid body byte range format");
bodyRange = '<' + parseInt(rangeInfo[1]) + '.' + parseInt(rangeInfo[2]) + '>';
bodyRange = '<' + parseInt(rangeInfo[1]) + '.' + parseInt(rangeInfo[2])
+ '>';
opts.request.body = opts.request.body[0];
}
if (typeof opts.request.headers === 'boolean' && opts.request.headers === true)
toFetch = 'HEADER'; // fetches headers only
else if (typeof opts.request.body === 'boolean' && opts.request.body === true)
toFetch = 'TEXT'; // fetches the whole entire message text (minus the headers), including all message parts
else if (typeof opts.request.body === 'string') {
if (opts.request.body !== '' && !/^([\d]+[\.]{0,1})*[\d]+$/.test(opts.request.body))
if (typeof opts.request.headers === 'boolean'
&& opts.request.headers === true) {
// fetches headers only
toFetch = 'HEADER';
} else if (typeof opts.request.body === 'boolean'
&& opts.request.body === true) {
// fetches the whole entire message text (minus the headers), including
// all message parts
toFetch = 'TEXT';
} else if (typeof opts.request.body === 'string') {
if (opts.request.body.toUpperCase() === 'FULL') {
// fetches the whole entire message (including the headers)
toFetch = '';
} else if (/^([\d]+[\.]{0,1})*[\d]+$/.test(opts.request.body)) {
// specific message part identifier, e.g. '1', '2', '1.1', '1.2', etc
toFetch = opts.request.body;
} else
throw new Error("Invalid body partID format");
toFetch = opts.request.body; // specific message part identifier, e.g. '1', '2', '1.1', '1.2', etc
}
} else
toFetch = 'HEADER.FIELDS (' + opts.request.headers.join(' ').toUpperCase() + ')'; // fetch specific headers only
} else {
// fetch specific headers only
toFetch = 'HEADER.FIELDS (' + opts.request.headers.join(' ').toUpperCase()
+ ')';
}
this._send('UID FETCH ' + uids.join(',') + ' (FLAGS INTERNALDATE'
+ (opts.request.struct ? ' BODYSTRUCTURE' : '')
+ (typeof toFetch === 'string' ? ' BODY' + (!opts.markSeen ? '.PEEK' : '')
+ (typeof toFetch === 'string' ? ' BODY'
+ (!opts.markSeen ? '.PEEK' : '')
+ '[' + toFetch + ']' + bodyRange : '') + ')', function(e) {

@@ -683,5 +765,6 @@ var fetcher = self._state.requests[0]._fetcher;

throw new Error('No mailbox is currently selected');
if (self._state.box.permFlags.indexOf('Deleted') === -1)
throw new Error('Cannot move message: server does not allow deletion of messages');
else {
if (self._state.box.permFlags.indexOf('Deleted') === -1) {
throw new Error('Cannot move message: '
+ 'server does not allow deletion of messages');
} else {
self.copy(uids, boxTo, function(err, reentryCount, deletedUIDs, counter) {

@@ -695,18 +778,33 @@ if (err) {

counter = counter || 0;
// Make sure we don't expunge any messages marked as Deleted except the one we are moving
if (typeof reentryCount === 'undefined')
self.search(['DELETED'], function(e, result) { fnMe.call(this, e, 1, result); });
else if (reentryCount === 1) {
if (counter < deletedUIDs.length)
self.delFlags(deletedUIDs[counter], 'DELETED', function(e) { process.nextTick(function(){fnMe.call(this, e, reentryCount, deletedUIDs, counter+1);}); });
else
// Make sure we don't expunge any messages marked as Deleted except the
// one we are moving
if (typeof reentryCount === 'undefined') {
self.search(['DELETED'], function(e, result) {
fnMe.call(this, e, 1, result);
});
} else if (reentryCount === 1) {
if (counter < deletedUIDs.length) {
self.delFlags(deletedUIDs[counter], 'DELETED', function(e) {
process.nextTick(function() {
fnMe.call(this, e, reentryCount, deletedUIDs, counter+1);
});
});
} else
fnMe.call(this, err, reentryCount+1, deletedUIDs);
} else if (reentryCount === 2)
self.addFlags(uids, 'Deleted', function(e) { fnMe.call(this, e, reentryCount+1, deletedUIDs); });
else if (reentryCount === 3)
self.removeDeleted(function(e) { fnMe.call(this, e, reentryCount+1, deletedUIDs); });
else if (reentryCount === 4) {
if (counter < deletedUIDs.length)
self.addFlags(deletedUIDs[counter], 'DELETED', function(e) { process.nextTick(function(){fnMe.call(this, e, reentryCount, deletedUIDs, counter+1);}); });
else
} else if (reentryCount === 2) {
self.addFlags(uids, 'Deleted', function(e) {
fnMe.call(this, e, reentryCount+1, deletedUIDs);
});
} else if (reentryCount === 3) {
self.removeDeleted(function(e) {
fnMe.call(this, e, reentryCount+1, deletedUIDs);
});
} else if (reentryCount === 4) {
if (counter < deletedUIDs.length) {
self.addFlags(deletedUIDs[counter], 'DELETED', function(e) {
process.nextTick(function() {
fnMe.call(this, e, reentryCount, deletedUIDs, counter+1);
});
});
} else
cb();

@@ -727,3 +825,4 @@ }

ImapConnection.prototype._store = function(uids, flags, isAdding, cb) {
var isKeywords = (arguments.callee.caller === this.addKeywords || arguments.callee.caller === this.delKeywords);
var isKeywords = (arguments.callee.caller === this.addKeywords
|| arguments.callee.caller === this.delKeywords);
if (this._state.status !== STATES.BOXSELECTED)

@@ -740,4 +839,6 @@ throw new Error('No mailbox is currently selected');

}
if ((!Array.isArray(flags) && typeof flags !== 'string') || (Array.isArray(flags) && flags.length === 0))
throw new Error((isKeywords ? 'Keywords' : 'Flags') + ' argument must be a string or a non-empty Array');
if ((!Array.isArray(flags) && typeof flags !== 'string')
|| (Array.isArray(flags) && flags.length === 0))
throw new Error((isKeywords ? 'Keywords' : 'Flags')
+ ' argument must be a string or a non-empty Array');
if (!Array.isArray(flags))

@@ -747,8 +848,13 @@ flags = [flags];

if (!isKeywords) {
if (this._state.box.permFlags.indexOf(flags[i]) === -1 || flags[i] === '\\*' || flags[i] === '*')
throw new Error('The flag "' + flags[i] + '" is not allowed by the server for this mailbox');
if (this._state.box.permFlags.indexOf(flags[i]) === -1
|| flags[i] === '\\*' || flags[i] === '*')
throw new Error('The flag "' + flags[i]
+ '" is not allowed by the server for this mailbox');
} else {
// keyword contains any char except control characters (%x00-1F and %x7F) and: '(', ')', '{', ' ', '%', '*', '\', '"', ']'
if (/[\(\)\{\\\"\]\%\*\x00-\x20\x7F]/.test(flags[i]))
throw new Error('The keyword "' + flags[i] + '" contains invalid characters');
// keyword contains any char except control characters (%x00-1F and %x7F)
// and: '(', ')', '{', ' ', '%', '*', '\', '"', ']'
if (/[\(\)\{\\\"\]\%\*\x00-\x20\x7F]/.test(flags[i])) {
throw new Error('The keyword "' + flags[i]
+ '" contains invalid characters');
}
}

@@ -761,3 +867,4 @@ }

this._send('UID STORE ' + uids.join(',') + ' ' + (isAdding ? '+' : '-') + 'FLAGS.SILENT (' + flags + ')', cb);
this._send('UID STORE ' + uids.join(',') + ' ' + (isAdding ? '+' : '-')
+ 'FLAGS.SILENT (' + flags + ')', cb);
};

@@ -771,3 +878,5 @@

if (self._state.numCapRecvs !== 2) {
self._send('CAPABILITY', cb); // fetch post-auth server capabilities if they were not automatically provided after login
// fetch post-auth server capabilities if they were not
// automatically provided after login
self._send('CAPABILITY', cb);
return;

@@ -784,5 +893,7 @@ }

//if (typeof this._state.capabilities['AUTH=PLAIN'] !== 'undefined') {
this._send('LOGIN "' + escape(this._options.username) + '" "' + escape(this._options.password) + '"', fnReturn);
this._send('LOGIN "' + escape(this._options.username) + '" "'
+ escape(this._options.password) + '"', fnReturn);
/*} else {
cb(new Error('Unsupported authentication mechanism(s) detected. Unable to login.'));
cb(new Error('Unsupported authentication mechanism(s) detected. '
+ 'Unable to login.'));
return;

@@ -853,5 +964,9 @@ }*/

function buildSearchQuery(options, isOrChild) {
var searchargs = '', months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
var searchargs = '',
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
'Oct', 'Nov', 'Dec'];
for (var i=0,len=options.length; i<len; i++) {
var criteria = (isOrChild ? options : options[i]), args = null, modifier = (isOrChild ? '' : ' ');
var criteria = (isOrChild ? options : options[i]),
args = null,
modifier = (isOrChild ? '' : ' ');
if (typeof criteria === 'string')

@@ -865,7 +980,9 @@ criteria = criteria.toUpperCase();

} else
throw new Error('Unexpected search option data type. Expected string or array. Got: ' + typeof criteria);
throw new Error('Unexpected search option data type. '
+ 'Expected string or array. Got: ' + typeof criteria);
if (criteria === 'OR') {
if (args.length !== 2)
throw new Error('OR must have exactly two arguments');
searchargs += ' OR (' + buildSearchQuery(args[0], true) + ') (' + buildSearchQuery(args[1], true) + ')'
searchargs += ' OR (' + buildSearchQuery(args[0], true) + ') ('
+ buildSearchQuery(args[1], true) + ')'
} else {

@@ -900,3 +1017,4 @@ if (criteria[0] === '!') {

if (!args || args.length !== 1)
throw new Error('Incorrect number of arguments for search option: ' + criteria);
throw new Error('Incorrect number of arguments for search option: '
+ criteria);
searchargs += modifier + criteria + ' "' + escape(''+args[0]) + '"';

@@ -911,8 +1029,12 @@ break;

if (!args || args.length !== 1)
throw new Error('Incorrect number of arguments for search option: ' + criteria);
throw new Error('Incorrect number of arguments for search option: '
+ criteria);
else if (!(args[0] instanceof Date)) {
if ((args[0] = new Date(args[0])).toString() === 'Invalid Date')
throw new Error('Search option argument must be a Date object or a parseable date string');
throw new Error('Search option argument must be a Date object'
+ ' or a parseable date string');
}
searchargs += modifier + criteria + ' ' + args[0].getDate() + '-' + months[args[0].getMonth()] + '-' + args[0].getFullYear();
searchargs += modifier + criteria + ' ' + args[0].getDate() + '-'
+ months[args[0].getMonth()] + '-'
+ args[0].getFullYear();
break;

@@ -922,3 +1044,4 @@ case 'KEYWORD':

if (!args || args.length !== 1)
throw new Error('Incorrect number of arguments for search option: ' + criteria);
throw new Error('Incorrect number of arguments for search option: '
+ criteria);
searchargs += modifier + criteria + ' ' + args[0];

@@ -929,3 +1052,4 @@ break;

if (!args || args.length !== 1)
throw new Error('Incorrect number of arguments for search option: ' + criteria);
throw new Error('Incorrect number of arguments for search option: '
+ criteria);
var num = parseInt(args[0]);

@@ -938,9 +1062,11 @@ if (isNaN(num))

if (!args || args.length !== 2)
throw new Error('Incorrect number of arguments for search option: ' + criteria);
searchargs += modifier + criteria + ' "' + escape(''+args[0]) + '" "' + escape(''+args[1]) + '"';
throw new Error('Incorrect number of arguments for search option: '
+ criteria);
searchargs += modifier + criteria + ' "' + escape(''+args[0]) + '" "'
+ escape(''+args[1]) + '"';
break;
case 'UID':
if (!args)
throw new Error('Incorrect number of arguments for search option: ' + criteria);
args = args.slice(1);
throw new Error('Incorrect number of arguments for search option: '
+ criteria);
try {

@@ -974,5 +1100,6 @@ validateUIDList(args);

intval = parseInt(''+uids[i]);
if (isNaN(intval))
throw new Error('Message ID must be an integer, "*", or a range: ' + uids[i]);
else if (typeof uids[i] !== 'number')
if (isNaN(intval)) {
throw new Error('Message ID must be an integer, "*", or a range: '
+ uids[i]);
} else if (typeof uids[i] !== 'number')
uids[i] = intval;

@@ -1030,3 +1157,5 @@ }

fetchData.headers[header] = [];
fetchData.headers[header].push(headers[j].substr(headers[j].indexOf(': ')+2).replace(/\r\n/g, '').trim());
fetchData.headers[header].push(headers[j].substr(headers[j]
.indexOf(': ')+2)
.replace(/\r\n/g, '').trim());
}

@@ -1047,4 +1176,7 @@ }

next = -1;
while (Array.isArray(cur[++next]))
ret.push(parseBodyStructure(cur[next], prefix + (prefix !== '' ? '.' : '') + (partID++).toString(), 1));
while (Array.isArray(cur[++next])) {
ret.push(parseBodyStructure(cur[next], prefix
+ (prefix !== '' ? '.' : '')
+ (partID++).toString(), 1));
}
part = { type: cur[next++].toLowerCase() };

@@ -1062,11 +1194,19 @@ if (partLen > next) {

next = 7;
part = {
// the path identifier for this part, useful for fetching specific
// parts of a message
partID: (prefix !== '' ? prefix : '1'),
if (typeof cur[1] === 'string') {
part = {
// the path identifier for this part, useful for fetching specific
// parts of a message
partID: (prefix !== '' ? prefix : '1'),
// required fields as per RFC 3501 -- null or otherwise
type: cur[0].toLowerCase(), subtype: cur[1].toLowerCase(),
params: null, id: cur[3], description: cur[4], encoding: cur[5],
size: cur[6]
// required fields as per RFC 3501 -- null or otherwise
type: cur[0].toLowerCase(), subtype: cur[1].toLowerCase(),
params: null, id: cur[3], description: cur[4], encoding: cur[5],
size: cur[6]
}
} else {
// type information for malformed multipart body
part = { type: cur[0].toLowerCase(), params: null };
cur.splice(1, 0, null);
++partLen;
next = 2;
}

@@ -1077,2 +1217,4 @@ if (Array.isArray(cur[2])) {

part.params[cur[2][i].toLowerCase()] = cur[2][i+1];
if (cur[1] === null)
++next;
}

@@ -1129,3 +1271,4 @@ if (part.type === 'message' && part.subtype === 'rfc822') {

} else if (i === 8)
part.envelope['in-reply-to'] = cur[next][i]; // message ID being replied to
// message ID being replied to
part.envelope['in-reply-to'] = cur[next][i];
else if (i === 9)

@@ -1142,3 +1285,5 @@ part.envelope['message-id'] = cur[next][i];

if (partLen > next && Array.isArray(cur[next])) {
part.body = parseBodyStructure(cur[next], prefix + (prefix !== '' ? '.' : '') + (partID++).toString(), 1);
part.body = parseBodyStructure(cur[next], prefix
+ (prefix !== '' ? '.' : '')
+ (partID++).toString(), 1);
} else

@@ -1152,3 +1297,3 @@ part.body = null;

part.lines = cur[next++];
if (partLen > next)
if (typeof cur[1] === 'string' && partLen > next)
part.md5 = cur[next++];

@@ -1201,4 +1346,6 @@ }

String.prototype.explode = function(delimiter, limit) {
if (arguments.length < 2 || arguments[0] === undefined || arguments[1] === undefined ||
!delimiter || delimiter === '' || typeof delimiter === 'function' || typeof delimiter === 'object')
if (arguments.length < 2 || arguments[0] === undefined
|| arguments[1] === undefined
|| !delimiter || delimiter === '' || typeof delimiter === 'function'
|| typeof delimiter === 'object')
return false;

@@ -1228,7 +1375,7 @@

function escape(str) {
return str.replace('\\', '\\\\').replace('"', '\"');
return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
}
function unescape(str) {
return str.replace('\"', '"').replace('\\\\', '\\');
return str.replace(/\\"/g, '"').replace(/\\\\/g, '\\');
}

@@ -1293,7 +1440,15 @@

*
* Modified by Brian White to use Array.isArray instead of the custom isArray method
* Modified by Brian White to use Array.isArray instead of the custom isArray
* method
*/
function extend() {
// copy reference to target object
var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
var target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false,
options,
name,
src,
copy;

@@ -1314,11 +1469,14 @@ // Handle a deep copy situation

// Must be an Object.
// Because of IE, we also have to check the presence of the constructor property.
// Because of IE, we also have to check the presence of the constructor
// property.
// Make sure that DOM nodes and window objects don't pass through, as well
if (!obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval)
if (!obj || toString.call(obj) !== "[object Object]" || obj.nodeType
|| obj.setInterval)
return false;
var has_own_constructor = hasOwnProperty.call(obj, "constructor");
var has_is_property_of_method = hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf");
var has_is_prop_of_method = hasOwnProperty.call(obj.constructor.prototype,
"isPrototypeOf");
// Not own constructor property must be Object
if (obj.constructor && !has_own_constructor && !has_is_property_of_method)
if (obj.constructor && !has_own_constructor && !has_is_prop_of_method)
return false;

@@ -1351,3 +1509,4 @@

if (deep && copy && (isPlainObject(copy) || Array.isArray(copy))) {
var clone = src && (isPlainObject(src) || Array.isArray(src)) ? src : Array.isArray(copy) ? [] : {};
var clone = src && (isPlainObject(src) || Array.isArray(src)
? src : (Array.isArray(copy) ? [] : {}));

@@ -1368,2 +1527,63 @@ // Never move original objects, clone them

Buffer.prototype.append = function(buf, start) {
buf.copy(this, start, 0);
};
Buffer.prototype.add = function(buf) {
var newBuf = new Buffer(this.length + buf.length);
this.copy(newBuf, 0, 0);
buf.copy(newBuf, this.length, 0);
return newBuf;
};
Buffer.prototype.split = function(str) {
if ((typeof str !== 'string' && !Array.isArray(str))
|| str.length === 0 || str.length > this.length)
return [this];
var search = !Array.isArray(str)
? str.split('').map(function(el) { return el.charCodeAt(0); })
: str,
searchLen = search.length,
ret = [], pos, start = 0;
while ((pos = this.indexOf(search, start)) > -1) {
ret.push(this.slice(start, pos));
start = pos + searchLen;
}
if (!ret.length)
ret = [this];
else if (start < this.length)
ret.push(this.slice(start));
return ret;
};
Buffer.prototype.indexOf = function(str, start) {
if (str.length > this.length)
return -1;
var search = !Array.isArray(str)
? str.split('').map(function(el) { return el.charCodeAt(0); })
: str,
searchLen = search.length,
ret = -1, i, j, len;
for (i=start||0,len=this.length; i<len; ++i) {
if (this[i] == search[0] && (len-i) >= searchLen) {
if (searchLen > 1) {
for (j=1; j<searchLen; ++j) {
if (this[i+j] != search[j])
break;
else if (j == searchLen-1) {
ret = i;
break;
}
}
} else
ret = i;
if (ret > -1)
break;
}
}
return ret;
};
net.Stream.prototype.setSecure = function() {

@@ -1404,2 +1624,2 @@ var pair = tls.createSecurePair();

return cleartext;
}
}
{ "name": "imap",
"version": "0.2.3",
"version": "0.2.4",
"author": "Brian White <mscdex@mscdex.net>",

@@ -4,0 +4,0 @@ "description": "An IMAP module for node.js that makes communicating with IMAP servers easy",

@@ -352,3 +352,3 @@ Description

* **headers** - A Boolean/Array value. A value of true fetches all message headers. An Array containing specific message headers to retrieve can also be specified. **Default:** true
* **body** - A Boolean/String/Array value. A Boolean value of true fetches the entire raw message body. A String value containing a valid partID (see _FetchResult_'s structure property) fetches the entire body/content of that particular part. An Array value of length 2 can be specified if you wish to request a byte range of the content, where the first item is a Boolean/String as previously described and the second item is a String indicating the byte range, for example, to fetch the first 500 bytes: '0-500'. **Default:** false
* **body** - A Boolean/String/Array value. A Boolean value of true fetches the entire raw message body. A String value containing a valid partID (see _FetchResult_'s structure property) fetches the entire body/content of that particular part, or a String value of 'full' fetches the entire email message, including the headers. An Array value of length 2 can be specified if you wish to request a byte range of the content, where the first item is a Boolean/String as previously described and the second item is a String indicating the byte range, for example, to fetch the first 500 bytes: '0-500'. **Default:** false

@@ -355,0 +355,0 @@ * **copy**(Integer/String/Array, String, Function) - _(void)_ - Copies the message(s) with the message ID(s) identified by the first parameter, in the currently open mailbox, to the mailbox specified by the second parameter. The first parameter can either be an Integer for a single message ID, a String for a message ID range (e.g. '2504:2507' or '*' or '2504:*'), or an Array containing any number of the aforementioned Integers and/or Strings. The Function parameter is the callback with one parameter: the error (null if none).

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc