diff --git a/package.json b/package.json index 02b4b0b84..3e2ffd2c9 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "body-parser": "1.18.3", "busboy": "0.2.14", "chance": "1.0.16", + "cheerio": "1.0.0-rc.2", "clone": "2.1.2", "connect-flash": "0.1.1", "connect-mongo": "2.0.1", diff --git a/src/mailer/mailCheck.js b/src/mailer/mailCheck.js index 006e20bee..8ab7f34de 100644 --- a/src/mailer/mailCheck.js +++ b/src/mailer/mailCheck.js @@ -18,6 +18,7 @@ var Imap = require('imap'); var winston = require('winston'); // var marked = require('marked'); var simpleParser = require('mailparser').simpleParser; +var cheerio = require('cheerio'); var emitter = require('../emitter'); var userSchema = require('../models/user'); @@ -77,119 +78,132 @@ mailCheck.init = function(settings) { deleteMessage: s.mailerCheckDeleteMessage.value }; - mailCheck.fetchMail(mailCheck.fetchMailOptions); + mailCheck.messages = []; + + bindImapError(); + bindImapReady(mailCheck.fetchMailOptions); + + mailCheck.fetchMail(); mailCheck.checkTimer = setInterval(function() { - mailCheck.fetchMail(mailCheck.fetchMailOptions); + mailCheck.fetchMail(); }, POLLING_INTERVAL); }; mailCheck.refetch = function() { - mailCheck.fetchMail(mailCheck.fetchMailOptions); -}; + if (_.isUndefined(mailCheck.fetchMailOptions)) { + winston.warn('Mailcheck.refetch() running before Mailcheck.init(); please run Mailcheck.init() prior'); + return; + } -mailCheck.fetchMail = function() { - try { - if (_.isUndefined(mailCheck.fetchMailOptions)) { - winston.warn('Mailcheck.fetchMail() running before Mailcheck.init(); please run Mailcheck.init() prior'); - return; - } + mailCheck.fetchMail(); +}; - var messages = []; +function bindImapError() { + mailCheck.Imap.on('error', function(err) { + winston.debug(err); + }); +} - mailCheck.Imap.once('error', function(err) { - winston.debug(err); +function bindImapReady() { + try { + mailCheck.Imap.on('end', function() { + handleMessages(mailCheck.messages); + mailCheck.Imap.destroy(); }); - mailCheck.Imap.once('ready', function() { - openInbox(function (err) { - if (err) { - mailCheck.Imap.end(); - winston.debug(err); - } else { - async.waterfall([ - function (next) { - mailCheck.Imap.search(['UNSEEN'], next); - }, - function (results, next) { - if (_.size(results) < 1) { - winston.debug('MailCheck: Nothing to Fetch.'); - return next(); - } + mailCheck.Imap.on('ready', function() { + openInbox(function (err) { + if (err) { + mailCheck.Imap.end(); + winston.debug(err); + } else { + async.waterfall([ + function (next) { + mailCheck.Imap.search(['UNSEEN'], next); + }, + function (results, next) { + if (_.size(results) < 1) { + winston.debug('MailCheck: Nothing to Fetch.'); + return next(); + } - winston.debug('Processed %s Mail > Ticket', _.size(results)); + winston.debug('Processed %s Mail > Ticket', _.size(results)); - var flag = '\\Seen'; - if (mailCheck.fetchMailOptions.deleteMessage) - flag = '\\Deleted'; + var flag = '\\Seen'; + if (mailCheck.fetchMailOptions.deleteMessage) + flag = '\\Deleted'; - mailCheck.Imap.addFlags(results, flag, function (err) { - if (err) winston.warn(err); - }); + mailCheck.Imap.addFlags(results, flag, function (err) { + if (err) winston.warn(err); + }); - var message = {}; + var message = {}; - var f = mailCheck.Imap.fetch(results, { - bodies: '' - }); + var f = mailCheck.Imap.fetch(results, { + bodies: '' + }); - f.on('message', function (msg) { - msg.on('body', function (stream) { - var buffer = ''; - stream.on('data', function (chunk) { - buffer += chunk.toString('utf8'); - }); + f.on('message', function (msg) { + msg.on('body', function (stream) { + var buffer = ''; + stream.on('data', function (chunk) { + buffer += chunk.toString('utf8'); + }); + + stream.once('end', function () { + simpleParser(buffer, function (err, mail) { + if (err) winston.warn(err); - stream.once('end', function () { - simpleParser(buffer, function (err, mail) { - if (err) winston.warn(err); + if (mail.headers.has('from')) + message.from = mail.headers.get('from').value[0].address; - if (mail.headers.has('from')) - message.from = mail.headers.get('from').value[0].address; - - if (mail.subject) - message.subject = mail.subject; - else - message.subject = message.from; - + if (mail.subject) + message.subject = mail.subject; + else + message.subject = message.from; + if (_.isUndefined(mail.textAsHtml)) { + var $ = cheerio.load(mail.html); + var $body = $('body'); + message.body = ($body.length > 0) ? $body.html() : mail.html; + } else message.body = mail.textAsHtml; - messages.push(message); - }); + mailCheck.messages.push(message); }); }); }); + }); - f.once('end', function () { - mailCheck.Imap.closeBox(true, function (err) { - if (err) winston.warn(err); - + f.on('end', function () { + mailCheck.Imap.closeBox(true, function (err) { + if (err) winston.warn(err); - return next(); - }); + return next(); }); - } - ], function (err) { - if (err) winston.warn(err); - - mailCheck.Imap.end(); - }); - } - }); - - }); - - mailCheck.Imap.once('end', function() { - handleMessages(messages); + }); + } + ], function (err) { + if (err) winston.warn(err); + mailCheck.Imap.end(); + }); + } + }); }); + } catch (error) { + winston.warn(error); + mailCheck.Imap.end(); + } +} - // Call Connect Last +mailCheck.fetchMail = function() { + try { + mailCheck.messages = []; mailCheck.Imap.connect(); - } catch (err) { - winston.warn(err); mailCheck.Imap.end(); + winston.warn(err); } }; diff --git a/yarn.lock b/yarn.lock index ecc87c842..14127eb54 100644 --- a/yarn.lock +++ b/yarn.lock @@ -316,6 +316,10 @@ dependencies: "@types/babel-types" "*" +"@types/node@*": + version "10.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" + "@yarnpkg/lockfile@^1.0.2": version "1.1.0" resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" @@ -1311,6 +1315,17 @@ check-error@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" +cheerio@1.0.0-rc.2: + version "1.0.0-rc.2" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db" + dependencies: + css-select "~1.2.0" + dom-serializer "~0.1.0" + entities "~1.1.1" + htmlparser2 "^3.9.1" + lodash "^4.15.0" + parse5 "^3.0.1" + cheerio@^0.22.0: version "0.22.0" resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" @@ -5503,7 +5518,7 @@ lodash@4.17.10: version "4.17.10" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" -lodash@4.x, lodash@^4.0.0, lodash@^4.11.1, lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1, lodash@^4.3.0, lodash@~4.17.10, lodash@~4.17.5: +lodash@4.x, lodash@^4.0.0, lodash@^4.11.1, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1, lodash@^4.3.0, lodash@~4.17.10, lodash@~4.17.5: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" @@ -5690,6 +5705,10 @@ math-interval-parser@^1.1.0: dependencies: xregexp "^2.0.0" +max-listeners-exceeded-warning@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/max-listeners-exceeded-warning/-/max-listeners-exceeded-warning-0.0.1.tgz#3115afeb2204f0843f612dccd64834428561efbd" + maxmin@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/maxmin/-/maxmin-2.1.0.tgz#4d3b220903d95eee7eb7ac7fa864e72dc09a3166" @@ -6971,6 +6990,12 @@ parse-url@^1.3.0: is-ssh "^1.3.0" protocols "^1.4.0" +parse5@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" + dependencies: + "@types/node" "*" + parseqs@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d"