Skip to content

Instantly share code, notes, and snippets.

@pfrazee
Created May 22, 2013 18:04
Show Gist options
  • Save pfrazee/5629571 to your computer and use it in GitHub Desktop.
Save pfrazee/5629571 to your computer and use it in GitHub Desktop.
Old IMAP wrapper from grimserver
module.exports = function addRoutes(server, config) {
var path = require('path');
var Imap = require('imap');
var MailParser = require('mailparser');
var Email = require('emailjs');
// (Mail)boxes
// ===========
function end(req, res, next) {
if (req.imap)
req.imap.logout();
res.end();
}
function linkBoxesCollection(req, res, next) {
res.link('item', path.join(req.path, '{title}'));
next();
}
function linkUserBoxItem(req, res, next) {
res.link('collection', path.join(req.path, 'messages'), 'messages');
next();
}
function linkUserBoxMessagesCollection(req, res, next) {
res.link('item', path.join(req.path, '{title}'));
next();
}
function linkUserBoxMessageItem(req, res, next) {
next();
}
function connectImap(req, res, next) {
// :TEMP:
req.imap = new Imap(require('./imap.debug.js'));
req.imap.connect(function(err) {
if (err) return res.send(401, err), end(req, res, next);
next();
});
}
function connectSmtp(req, res, next) {
// :TEMP:
req.smtp = Email.server.connect(require('./smtp.debug.js'));
next();
}
function getUserBoxesCollection(req, res, next) {
req.imap.getBoxes(function(err, boxes) {
if (err) return res.send(500, err), end(req, res, next);
res.format({
'application/json': function() {
res.send(nullCirculars(boxes));
}
});
});
var nullCirculars = function(boxes) {
for (var box in boxes) {
boxes[box].parent = null;
if (boxes[box].children)
nullCirculars(boxes[box].children);
}
return boxes;
};
}
function addtoUserBoxesCollection(req, res, next) {
res.send(501); // :TODO:
next();
}
function openInbox(req, res, next) {
req.imap.openBox(req.param('boxId'), false, function(err, mailbox) {
if (err) return res.send(401, err), end(req, res, next);
req.mailbox = mailbox;
next();
});
}
function closeInbox(req, res, next) {
req.imap.closeBox(function(err) {
if (err) return res.send(500, err), end(req, res, next);
next();
});
}
function getUserBoxItem(req, res, next) {
req.imap.status(req.param('boxId'), function(err, mailbox) {
if (err) return res.send(404, err), end(req, res, next);
res.format({
'application/json': function() {
res.send({
name : mailbox.name,
messages : {
total : mailbox.messages.total,
'new' : mailbox.messages['new'],
unseen : mailbox.messages.unseen
}
});
}
});
next();
});
}
function updateUserBoxItem(req, res, next) {
res.send(501); // :TODO:
next();
}
function deleteUserBoxItem(req, res, next) {
res.send(501); // :TODO:
next();
}
function sendMessage(req, res, next) {
if (!req.body)
return res.send(422), end(req, res, next);
var message = {
text : req.body.text,
from : req.body.from,
to : req.body.to,
cc : req.body.cc,
bcc : req.body.bcc,
subject : req.body.subject
};
req.smtp.send(message, function(err, result) {
if (err) return res.send(422), end(req, res, next);
res.format({
'application/json': function() {
res.send(result);
}
});
next();
});
}
function getUserBoxMessagesCollection(req, res, next) {
var criteria = ['ALL'];
if (req.query.q) {
try { criteria = JSON.parse(req.query.q); }
catch (e) {
res.send(400, 'Invalid `q` param - failed to parse JSON');
return end(req, res, next);
}
}
req.imap.search(criteria, function(err, UIDs) {
if (err) return res.send(422, err), end(req, res, next);
var offset = parseInt(req.query.offset, 10) || 0;
var limit = parseInt(req.query.limit, 10) || 20;
var fetchUIDs = UIDs.slice(-(offset+limit), (-offset || undefined));
var nMessages = fetchUIDs.length;
if (nMessages === 0)
return res.send(204), end(req, res, next);
var nProcessed = 0;
var messageHeaders = [];
var setupFetch = function(fetch) {
fetch.on('message', function(msg) {
var parser = new MailParser.MailParser();
msg.on('headers', function(headers) { parser.write(headers); });
msg.on('end', function() { parser.end(req, res, next); });
parser.on('end', function(msgParsed) {
messageHeaders.push({
seqno : msg.seqno,
uid : msg.uid,
flags : msg.flags,
from : msgParsed.from,
to : msgParsed.to,
replyTo : msgParsed.replyTo,
cc : msgParsed.cc,
bcc : msgParsed.bcc,
subject : msgParsed.subject,
references : msgParsed.references,
inReplyTo : msgParsed.inReplyTo,
priority : msgParsed.priority,
date : msgParsed.headers.date
});
if ((++nProcessed) == nMessages) {
res.format({
'application/json': function() {
res.send(messageHeaders.sort(function(a,b) { return (a.uid < b.uid) ? 1 : -1; }));
}
});
}
});
});
};
var fetchReq = {
headers: { fields:true, parse:false },
body: false,
cb: setupFetch
};
req.imap.fetch(fetchUIDs, fetchReq, function(err) {
if (err) return res.send(502, err), end(req, res, next);
});
});
}
function addtoUserBoxMessagesCollection(req, res, next) {
res.send(501); // :TODO:
next();
}
function getUserBoxMessageItem(req, res, next) {
var UID = parseInt(req.param('messageId'), 10);
if (isNaN(UID) || UID != req.param('messageId')) {
return res.send(404), end(req, res, next);
}
var found = false;
var setupFetch = function(fetch) {
fetch.on('message', function(msg) {
found = true;
var parser = new MailParser.MailParser();
msg.on('data', function(data) { parser.write(data); });
msg.on('end', function() { parser.end(); });
parser.on('end', function(msgParsed) {
res.format({
'application/json': function() {
res.send(msgParsed);
}
});
});
});
};
var fetchReq = {
headers: { parse:false },
body: true,
cb: setupFetch
};
var fetch = req.imap.fetch(UID, fetchReq, function(err) {
if (err) return res.send(502, err), end(req, res, next);
if (!found) return res.send(404, err), end(req, res, next);
});
}
function updateUserBoxMessageItem(req, res, next) {
res.send(501); // :TODO:
next();
}
function deleteUserBoxMessageItem(req, res, next) {
res.send(501); // :TODO:
next();
}
// Routes
// ======
server.head ('/:userId/boxes', linkBoxesCollection, end);
server.get ('/:userId/boxes', linkBoxesCollection, connectImap, getUserBoxesCollection, end);
server.post ('/:userId/boxes', linkBoxesCollection, connectImap, addtoUserBoxesCollection, end);
server.head ('/:userId/boxes/:boxId', linkUserBoxItem, end);
server.get ('/:userId/boxes/:boxId', linkUserBoxItem, connectImap, getUserBoxItem, end);
server.patch('/:userId/boxes/:boxId', linkUserBoxItem, connectImap, updateUserBoxItem, end);
server.del ('/:userId/boxes/:boxId', linkUserBoxItem, connectImap, deleteUserBoxItem, end);
server.head ('/:userId/boxes/:boxId/messages', linkUserBoxMessagesCollection, end);
server.post ('/:userId/boxes/_out/messages', linkUserBoxMessagesCollection, connectSmtp, sendMessage, end);
server.get ('/:userId/boxes/:boxId/messages', linkUserBoxMessagesCollection, connectImap, openInbox, getUserBoxMessagesCollection, closeInbox, end);
server.post ('/:userId/boxes/:boxId/messages', linkUserBoxMessagesCollection, connectImap, openInbox, addtoUserBoxMessagesCollection, closeInbox, end);
server.head ('/:userId/boxes/:boxId/messages/:messageId', linkUserBoxMessageItem, end);
server.get ('/:userId/boxes/:boxId/messages/:messageId', linkUserBoxMessageItem, connectImap, openInbox, getUserBoxMessageItem, closeInbox, end);
server.patch('/:userId/boxes/:boxId/messages/:messageId', linkUserBoxMessageItem, connectImap, openInbox, updateUserBoxMessageItem, closeInbox, end);
server.del ('/:userId/boxes/:boxId/messages/:messageId', linkUserBoxMessageItem, connectImap, openInbox, deleteUserBoxMessageItem, closeInbox, end);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment