From 99505c4066e1763cbaddb21bb29767b9bf012475 Mon Sep 17 00:00:00 2001 From: Andrew Van Tassel Date: Fri, 9 Dec 2016 17:37:30 -0700 Subject: [PATCH] Added getIPsFromMailParser --- CHANGELOG.md | 5 +++ README.md | 4 +-- lib/api.js | 76 +++++++++++++++++++++++++++++++++++++++++--- package.json | 2 +- test/mailhops.js | 2 ++ test/mailparser.json | 35 ++++++++++++++++++++ test/main.js | 38 +++++++++++++++++++--- 7 files changed, 150 insertions(+), 12 deletions(-) create mode 100644 test/mailparser.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 44ba359..f3b90b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ # Change Log All notable changes to this project will be documented in this file. +## 2.0.1 - 2016-12-08 + +### Added +- getIPsFromMailParser method for parsed message from [mailparser](https://www.npmjs.com/package/mailparser) + ## 2.0.0 - 2016-09-09 ### Added diff --git a/README.md b/README.md index 8ce211d..9bd0e02 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # MailHops API node -[www.MailHops.com](http://www.mailhops.com) +[www.MailHops.com](https://www.mailhops.com) MailHops logo @@ -27,7 +27,7 @@ var mailhops = new MailHops({ api_key: "aWN8Pb27Xj6GfV8D6ARsjokonYwbWUNbz9rM", api_version: 2, proxy: "http://myproxy:3128", - app_name: "Node App v2.0.0", + app_name: "Node App v2.0.1", forecastio_api_key: "" }); ``` diff --git a/lib/api.js b/lib/api.js index 23c2bb3..8f9b62c 100644 --- a/lib/api.js +++ b/lib/api.js @@ -7,6 +7,12 @@ module.exports = { time_traveled: null, + timeTraveled: function(time){ + if(typeof time != 'undefined') + this.time_traveled = time; + return this.time_traveled; + }, + lookup: function(route, options, fn){ if(_.isFunction(options) && _.isUndefined(fn)){ fn = options; @@ -19,8 +25,8 @@ module.exports = { qs.r = Array.isArray(route) ? route.join(',').replace(" ", "") : route.replace(" ", ""); if(!!this.forecastio_api_key) qs.fkey = this.forecastio_api_key; - if(!!this.time_traveled) - qs.t = this.time_traveled; + if(!!this.timeTraveled()) + qs.t = this.timeTraveled(); var config = { uri: [this.api_version, "lookup"].join("/"), @@ -98,6 +104,66 @@ module.exports = { return ips; }, + getIPsFromMailParser: function(parsedmail){ + var ips = [] + ,regexIp=/(1\d{0,2}|2(?:[0-4]\d{0,1}|[6789]|5[0-5]?)?|[3-9]\d?|0)\.(1\d{0,2}|2(?:[0-4]\d{0,1}|[6789]|5[0-5]?)?|[3-9]\d?|0)\.(1\d{0,2}|2(?:[0-4]\d{0,1}|[6789]|5[0-5]?)?|[3-9]\d?|0)\.(1\d{0,2}|2(?:[0-4]\d{0,1}|[6789]|5[0-5]?)?|[3-9]\d?|0)(\/(?:[012]\d?|3[012]?|[456789])){0,1}$/ + ,regexAllIp = /(1\d{0,2}|2(?:[0-4]\d{0,1}|[6789]|5[0-5]?)?|[3-9]\d?|0)\.(1\d{0,2}|2(?:[0-4]\d{0,1}|[6789]|5[0-5]?)?|[3-9]\d?|0)\.(1\d{0,2}|2(?:[0-4]\d{0,1}|[6789]|5[0-5]?)?|[3-9]\d?|0)\.(1\d{0,2}|2(?:[0-4]\d{0,1}|[6789]|5[0-5]?)?|[3-9]\d?|0)(\/(?:[012]\d?|3[012]?|[456789])){0,1}/g + ,regexIPV6 = /(::|(([a-fA-F0-9]{1,4}):){7}(([a-fA-F0-9]{1,4}))|(:(:([a-fA-F0-9]{1,4})){1,6})|((([a-fA-F0-9]{1,4}):){1,6}:)|((([a-fA-F0-9]{1,4}):)(:([a-fA-F0-9]{1,4})){1,6})|((([a-fA-F0-9]{1,4}):){2}(:([a-fA-F0-9]{1,4})){1,5})|((([a-fA-F0-9]{1,4}):){3}(:([a-fA-F0-9]{1,4})){1,4})|((([a-fA-F0-9]{1,4}):){4}(:([a-fA-F0-9]{1,4})){1,3})|((([a-fA-F0-9]{1,4}):){5}(:([a-fA-F0-9]{1,4})){1,2}))/; + + if(typeof parsedmail.headers.received == 'undefined') + return ips; + + _.each(parsedmail.headers.received,function(line){ + var received_ips = line.match(regexAllIp); + + if(!received_ips) + return; + + //get unique IPs for each Received header + received_ips = received_ips.filter(function(item, pos) { + return received_ips.indexOf(item) == pos; + }); + + //maybe multiple IPs in one Received: line + _.each(received_ips, function(ip){ + + var firstchar = line.substring(line.indexOf(ip)-1).substring(0,1); + var lastchar = line.substring(line.indexOf(ip)+ip.length).substring(0,1); + + //do some checks on the first and last characters surrounding the IP + // Microsoft SMTP Server id 14.3.195.1; something like this should not be included + if(!firstchar.match(/\.|\d|\-/) + && !lastchar.match(/\.|\d|\-/) + && ( firstchar != '?' && lastchar != '?' ) + && lastchar != ';' + && regexIp.test(ip)){ + + ips.unshift( ip ); + + } else if(regexIp.test(ip) + && line.indexOf(ip) !== line.lastIndexOf(ip)){ + //check for duplicate IPs in one line + ips.unshift( ip ); + + } + }); + }); + + if(parsedmail.date && parsedmail.receivedDate){ + try { + var firstDate = new Date(parsedmail.date); + var lastDate = new Date(parsedmail.receivedDate); + this.timeTraveled(lastDate - firstDate); + } catch(e){ + this.timeTraveled(null); + } + } else { + this.timeTraveled(null); + } + + return ips; + }, + getReceivedHeaders: function(header){ var receivedHeaders = []; var rline = '',firstDate,lastDate; @@ -156,12 +222,12 @@ module.exports = { try { firstDate = new Date(firstDate); lastDate = new Date(lastDate); - this.time_traveled = lastDate - firstDate; + this.timeTraveled(lastDate - firstDate); } catch(e){ - this.time_traveled = null; + this.timeTraveled(null); } } else { - this.time_traveled = null; + this.timeTraveled(null); } return receivedHeaders; diff --git a/package.json b/package.json index 933dfab..df28d35 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mailhops", - "version": "2.0.0", + "version": "2.0.1", "description": "A nodejs module for interacting with the MailHops API.", "main": "main.js", "scripts": { diff --git a/test/mailhops.js b/test/mailhops.js index 2c103a5..4f9770c 100644 --- a/test/mailhops.js +++ b/test/mailhops.js @@ -15,9 +15,11 @@ describe("mailhops", function(){ var required_keys = [ "configure", "time_traveled", + "timeTraveled", "lookup", "mapUrl", "getIPsFromHeader", + "getIPsFromMailParser", "getReceivedHeaders" ] diff --git a/test/mailparser.json b/test/mailparser.json new file mode 100644 index 0000000..13fc312 --- /dev/null +++ b/test/mailparser.json @@ -0,0 +1,35 @@ +{ + "text": "Ok test it then\n", + "headers": { + "return-path": "", + "x-original-to": "andrew@mailhops.com", + "delivered-to": "x12669597@homiemail-mx18.g.dreamhost.com", + "received": ["from homiemail-a110.g.dreamhost.com (agjbgdcfdbdd.dreamhost.com [69.163.253.130]) (using TLSv1.1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by homiemail-mx18.g.dreamhost.com (Postfix) with ESMTPS id 5895D9004034 for ; Thu, 8 Dec 2016 16:02:34 -0800 (PST)" + , "from homiemail-a110.g.dreamhost.com (localhost [127.0.0.1]) by homiemail-a110.g.dreamhost.com (Postfix) with ESMTP id 1BA792004763B for ; Thu, 8 Dec 2016 16:02:34 -0800 (PST)" + , "from Andrews-MacBook-Pro-4.local (c-67-177-226-240.hsd1.co.comcast.net [67.177.226.240]) (Authenticated sender: andrew@showhops.com) by homiemail-a110.g.dreamhost.com (Postfix) with ESMTPA id F349520047638 for ; Thu, 8 Dec 2016 16:02:33 -0800 (PST)" + ], + "dkim-signature": "v=1; a=rsa-sha1; c=relaxed; d=showhops.com; h=message-id :date:from:mime-version:to:subject:content-type :content-transfer-encoding; s=showhops.com; bh=gXjUxcC3bG8U+A3N7 7ELq45N68U=; b=U09iG7hIF9CmUxHZSxHJekgSgfApMkJmTTMDeyXsVSJlMQish ElW8P2UfAd1k2+x+PlrV7vDIxr2NSyWI/qDSuYuQt4GStsfJnS2LVEodzPM0Mfsx yAK16/iGNu87UCnYo6v3xvilyW6D0L4P4RM/NB7ib7NinOUIaWJiMJ/hAk=", + "message-id": "<5849F498.3080807@showhops.com>", + "date": "Thu, 08 Dec 2016 17:02:32 -0700", + "from": "Andrew Van Tassel ", + "user-agent": "Postbox 4.0.8 (Macintosh/20151105)", + "mime-version": "1.0", + "to": "Andrew Van Tassel ", + "subject": "tomorrow ok", + "content-type": "text/plain; charset=ISO-8859-1; format=flowed", + "content-transfer-encoding": "7bit" + }, + "subject": "tomorrow ok", + "messageId": "5849F498.3080807@showhops.com", + "priority": "normal", + "from": [{ + "address": "andrew@showhops.com", + "name": "Andrew Van Tassel" + }], + "to": [{ + "address": "andrew@mailhops.com", + "name": "Andrew Van Tassel" + }], + "date": "2016-12-09T00:02:32.000Z", + "receivedDate": "2016-12-09T00:02:34.000Z" +} diff --git a/test/main.js b/test/main.js index 38a62af..9aefac0 100644 --- a/test/main.js +++ b/test/main.js @@ -4,13 +4,13 @@ var request = require("request"); var fs = require('fs'); var configuration = require([__dirname, "..", "config"].join("/")); var MailHops = require([__dirname, "..", "main"].join("/")); -var mailhops = new MailHops(configuration); - -console.log('Using %s', mailhops.base_uri); describe("main", function(){ describe("new MailHops()", function(){ + + var mailhops = new MailHops(configuration); + it("api_version parameter exists", function(){ assert.ok(_.has(mailhops, "api_version")); }); @@ -31,6 +31,8 @@ describe("main", function(){ describe("lookup endpoint", function(){ + var mailhops = new MailHops(configuration); + it('string route should return a 200 response with private ip', function(done){ mailhops.lookup('127.0.0.1', function(err, res, body){ assert.equal(res.statusCode,200); @@ -58,6 +60,8 @@ describe("main", function(){ describe("map endpoint", function(){ + var mailhops = new MailHops(configuration); + it('should return a 200 response', function(done){ request(mailhops.mapUrl('127.0.0.1'), function (err, res, body) { assert.equal(res.statusCode,200); @@ -68,6 +72,9 @@ describe("main", function(){ }); describe("parse header and lookup", function(){ + + var mailhops = new MailHops(configuration); + //read header form file var header = fs.readFileSync(__dirname+'/header-test.eml',{ encoding: 'utf8' }); var ips = mailhops.getIPsFromHeader(header); @@ -106,6 +113,9 @@ describe("main", function(){ }); describe("parse header", function(){ + + var mailhops = new MailHops(configuration); + //read header form file var header = fs.readFileSync(__dirname+'/header-test-no-ips.eml',{ encoding: 'utf8' }); var ips = mailhops.getIPsFromHeader(header); @@ -116,7 +126,27 @@ describe("main", function(){ }); it('should return a time of 0 milliseconds', function(done){ - assert.equal(mailhops.time,null); + assert.equal(mailhops.timeTraveled(),null); + done(); + }); + + }); + + describe("get IPs form mailparser", function(){ + + var mailhops = new MailHops(configuration); + + //read header form file + var message = fs.readFileSync(__dirname+'/mailparser.json',{ encoding: 'utf8' }); + var ips = mailhops.getIPsFromMailParser(JSON.parse(message)); + + it('should return an array of 0 IP addresses', function(done){ + assert.equal(ips.length,3); + done(); + }); + + it('should return a time of 0 milliseconds', function(done){ + assert.equal(mailhops.timeTraveled(),2000); done(); });