/* * @author: Andrew Van Tassel * @email: andrew@andrewvantassel.com * @website: http://mailhops.com */ var mailHops = { msgURI: null, resultTextDataPane: null, resultTextDataPane2: null, resultTextDataPane3: null, resultContainerDataPane: null, resultDetailsLink: null, resultContainerDetails: null, resultDetails: null, resultMapLink: null, mailhopsDataPaneSPF: null, mailhopsDataPaneDKIM: null, mailhopsDataPaneMailer: null, mailhopsDataPaneDNSBL: null, mailhopsListContainer: null, mailhopsAuthContainer: null, resultListDataPane: null, resultMeta: null, isLoaded: false, options: {'lan':'en','unit':'mi','api_url':'http://api.mailhops.com','debug':false}, appVersion: 'MailHops Postbox 0.9.0', message: {secure:[]}, client_location: null } function LOG(msg) { var consoleService = Components.classes["@mozilla.org/consoleservice;1"] .getService(Components.interfaces.nsIConsoleService); consoleService.logStringMessage('MailHops: '+msg); } mailHops.init = function() { //load preferences mailHops.loadPref(); mailHops.isLoaded = true; mailHops.resultContainerDataPane = document.getElementById ( "mailhopsDataPane"); mailHops.resultTextDataPane = document.getElementById ( "mailhopsDataPaneText"); mailHops.resultTextDataPane2 = document.getElementById ( "mailhopsDataPaneText2"); mailHops.resultTextDataPane3 = document.getElementById ( "mailhopsDataPaneText3"); mailHops.resultDetailsLink = document.getElementById ( "mailhopsDataPaneDetailsLink"); mailHops.resultContainerDetails = document.getElementById ( "mailhopsDetailsContainer"); mailHops.resultDetails = document.getElementById ( "mailhopsDataPaneDetails"); mailHops.resultMeta = document.getElementById ( "mailhopsDataPaneMeta"); mailHops.resultMapLink = document.getElementById ( "mailhopsDataPaneMapLink"); //auth mailHops.mailhopsAuthContainer = document.getElementById ( "dataPaneMailHopsAuthContainer"); mailHops.mailhopsDataPaneSPF = document.getElementById ( "mailhopsDataPaneSPF"); mailHops.mailhopsDataPaneDKIM = document.getElementById ( "mailhopsDataPaneDKIM"); mailHops.mailhopsDataPaneMailer = document.getElementById ( "mailhopsDataPaneMailer"); mailHops.mailhopsDataPaneDNSBL = document.getElementById ( "mailhopsDataPaneDNSBL"); //list mailHops.mailhopsListContainer = document.getElementById ( "dataPaneMailHopsListContainer"); mailHops.resultListDataPane = document.getElementById ( "mailhopsListDataPane"); //event listner for route click to launch map mailHops.resultMapLink.addEventListener("click", function () { if(this.hasAttribute("data-route")) mailHops.launchMap(String(this.getAttribute("data-route"))); } , false); mailHops.resultDetailsLink.addEventListener("click", function () { if(mailHops.resultContainerDetails.style.display=='none'){ mailHops.resultContainerDetails.style.display = 'block'; mailHops.resultDetailsLink.setAttribute('class','text-link dataPaneMoreLink active'); } else{ mailHops.resultContainerDetails.style.display = 'none'; mailHops.resultDetailsLink.setAttribute('class','text-link dataPaneMoreLink'); } } , false); mailHops.mailhopsDataPaneDNSBL.addEventListener("click", function () { if(this.hasAttribute('data-ip')) mailHops.launchSpamHausURL(this.getAttribute('data-ip')); } , false); document.getElementById("mailhopsDataPanePrefsLink").addEventListener("click", function () { window.openDialog("chrome://mailhops/content/preferences.xul","mailHopsPreferences",null,null); } , false); document.getElementById("mailhopsDataPaneRefreshLink").addEventListener("click", function () { mailHops.refreshCache(); } , false); }; mailHops.loadPref = function() { //get preferences mailHops.options.lan = mailHops.getCharPref('mail.mailHops.lang','en'); mailHops.options.unit = mailHops.getCharPref('mail.mailHops.unit','mi'); mailHops.options.fkey = mailHops.getCharPref('mail.mailHops.fkey','');//forecast.io api_key //Display Boxes mailHops.options.show_details = mailHops.getCharPref('mail.mailHops.show_details','true')=='true'?true:false; mailHops.options.show_meta = mailHops.getCharPref('mail.mailHops.show_meta','true')=='true'?true:false; mailHops.options.show_auth = mailHops.getCharPref('mail.mailHops.show_auth','true')=='true'?true:false; mailHops.options.show_lists = mailHops.getCharPref('mail.mailHops.show_lists','true')=='true'?true:false; //Details options mailHops.options.show_host = mailHops.getCharPref('mail.mailHops.show_host','true')=='true'?true:false; mailHops.options.show_secure = mailHops.getCharPref('mail.mailHops.show_secure','true')=='true'?true:false; //Auth options mailHops.options.show_dkim = mailHops.getCharPref('mail.mailHops.show_dkim','true')=='true'?true:false; mailHops.options.show_spf = mailHops.getCharPref('mail.mailHops.show_spf','true')=='true'?true:false; mailHops.options.show_mailer = mailHops.getCharPref('mail.mailHops.show_mailer','true')=='true'?true:false; mailHops.options.show_dnsbl = mailHops.getCharPref('mail.mailHops.show_dnsbl','true')=='true'?true:false; mailHops.options.debug = mailHops.getCharPref('mail.mailHops.debug','false')=='true'?true:false; mailHops.options.client_location = mailHops.getCharPref('mail.mailHops.client_location',''); mailHops.options.api_url = mailHops.getCharPref('mail.mailHops.api_url','http://api.mailhops.com'); if(mailHops.options.client_location == ''){ mailHops.setClientLocation(); } }; mailHops.StreamListener = { content: "" , found: false , onDataAvailable: function ( request , context , inputStream , offset , count ) { try { var sis = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance ( Components.interfaces.nsIScriptableInputStream ) ; sis.init ( inputStream ) ; if ( ! this.found ) { this.content += sis.read ( count ) ; this.content = this.content.replace ( /\r/g , "" ) ; var pos = this.content.indexOf ( "\n\n" ) ; if ( pos > -1 ) { // last header line must end with LF -> pos+1 !!! this.content = this.content.substr ( 0 , pos + 1 ) ; this.found = true ; } } } catch ( ex ) { } } , onStartRequest: function ( request , context ) { this.content = "" ; this.found = false ; } , onStopRequest: function ( aRequest , aContext , aStatusCode ) { mailHops.headers = Components.classes["@mozilla.org/messenger/mimeheaders;1"].createInstance ( Components.interfaces.nsIMimeHeaders ) ; mailHops.headers.initialize ( this.content , this.content.length ) ; mailHops.getRoute() ; } }; /** * loop through the header, find out if we have received-from headers */ mailHops.loadHeaderData = function() { var msgURI = null ; if ( gDBView ) { msgURI = gDBView.URIForFirstSelectedMessage ; } if ( msgURI == null ) { return ; } mailHops.msgURI = msgURI; var messenger = Components.classes["@mozilla.org/messenger;1"].createInstance ( Components.interfaces.nsIMessenger ) ; var msgService = messenger.messageServiceFromURI ( msgURI ) ; msgService.CopyMessage ( msgURI , mailHops.StreamListener , false , null , msgWindow , {} ) ; }; mailHops.getRoute = function(){ //IP regex var 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}$/; var 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; // TODO test IPV6 regex for Received headers, currently only used for X-Originating-IP // IPv6 addresses including compressed and IPv4-embedded variants (RFC 2373) // http://regexlib.com/REDetails.aspx?regexp_id=2919 var 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}))/; var headReceived = mailHops.headers.extractHeader ( "Received" , true ) ; var headXOrigIP = mailHops.headers.extractHeader ( "X-Originating-IP" , false ) ; //auth box var headXMailer = (mailHops.options.show_auth && mailHops.options.show_mailer) ? mailHops.headers.extractHeader ( "X-Mailer" , false ) : null; var headUserAgent = (mailHops.options.show_auth && mailHops.options.show_mailer) ? mailHops.headers.extractHeader ( "User-Agent" , false ) : null; var headXMimeOLE = (mailHops.options.show_auth && mailHops.options.show_mailer) ? mailHops.headers.extractHeader ( "X-MimeOLE" , false ) : null; var headReceivedSPF = (mailHops.options.show_auth && mailHops.options.show_spf) ? mailHops.headers.extractHeader ( "Received-SPF" , false ) : null; var headAuth = mailHops.options.show_auth ? mailHops.headers.extractHeader ( "Authentication-Results" , false ) : null; //lists box var headListUnsubscribe = mailHops.options.show_lists ? mailHops.headers.extractHeader ( "List-Unsubscribe" , false ) : null; //display auth if(mailHops.options.show_auth) mailHops.displayResultAuth(headXMailer,headUserAgent,headXMimeOLE,headAuth,headReceivedSPF); else mailHops.mailhopsAuthContainer.style.display='none'; //display unsubscribe link if(mailHops.options.show_lists) mailHops.displayResultLists(headListUnsubscribe); else mailHops.mailhopsListContainer.style.display='none'; var received_ips; var all_ips = new Array(); var rline=''; //empty secure mailHops.message.secure = []; //loop through the received headers and parse for IP addresses if ( headReceived ){ var headReceivedArr = headReceived.split('\n'); if(headReceivedArr.length != 0){ for ( var h=0; h',''); var label = document.createElement('label'); label.setAttribute('class','text-link dataPaneURLitem'); if(href.indexOf('mailto:')!=-1){ label.setAttribute('value','Unsubscribe via Email'); if(href.toLowerCase().indexOf('subject=')==-1){ if(href.indexOf('?')==-1) href+='?subject=Unsubscribe'; else href+='&subject=Unsubscribe'; } } else{ label.setAttribute('value','Unsubscribe via Web'); } label.setAttribute('tooltiptext',href); label.setAttribute('href',href); mailHops.resultListDataPane.appendChild(label); } } } }; mailHops.displayResultAuth = function( header_xmailer, header_useragent, header_xmimeole, header_auth, header_spf ){ mailHops.mailhopsAuthContainer.style.display=''; //SPF if(header_spf){ header_spf=header_spf.replace(/^\s+/,""); var headerSPFArr=header_spf.split(' '); mailHops.mailhopsDataPaneSPF.setAttribute('value','SPF: '+headerSPFArr[0]); mailHops.mailhopsDataPaneSPF.style.backgroundImage = 'url(chrome://mailhops/content/images/auth/'+headerSPFArr[0]+'.png)'; mailHops.mailhopsDataPaneSPF.setAttribute('tooltiptext',header_spf+'\n'+mailHops.authExplainSPF(headerSPFArr[0])); mailHops.mailhopsDataPaneSPF.style.display='block'; } else{ mailHops.mailhopsDataPaneSPF.style.display='none'; } //Authentication-Results //http://tools.ietf.org/html/rfc5451 if(header_auth){ var headerAuthArr=header_auth.split(';'); var dkim_result; var spf_result; for(var h=0;h 0){ if(mailHops.options.client_location){ var client_location = JSON.parse(mailHops.options.client_location); response.route.push(client_location.route[0]); } for(var i=0; i 0){ if(mailHops.options.unit=='mi') distanceText =' ( '+mailHops.addCommas(Math.round(response.distance.miles))+' mi traveled )'; else distanceText =' ( '+mailHops.addCommas(Math.round(response.distance.kilometers))+' km traveled )'; } else if(displayText=='') displayText = ' Local message.'; } if(header_route) mailHops.resultMapLink.setAttribute("data-route", header_route); else mailHops.resultMapLink.removeAttribute("data-route"); mailHops.resultTextDataPane.style.backgroundImage = 'url('+image+')'; mailHops.resultTextDataPane.value = displayText; mailHops.resultTextDataPane.setAttribute('tooltiptext',displayText+' '+distanceText); if(distanceText){ mailHops.resultTextDataPane2.style.display = 'block'; mailHops.resultTextDataPane2.value = distanceText; mailHops.resultTextDataPane2.setAttribute('tooltiptext',displayText+' '+distanceText); } else { mailHops.resultTextDataPane2.style.display = 'none'; } //set weather of sender if(weather){ mailHops.resultTextDataPane3.style.display = 'block'; mailHops.resultTextDataPane3.setAttribute('tooltiptext',new Date(weather.time*1000)); mailHops.resultTextDataPane3.value = weather.summary+' '+Math.round(weather.temp)+'\u00B0'; mailHops.resultTextDataPane3.style.backgroundImage = 'url('+mailHops.getWeatherIcon(weather.icon)+')'; } //show the detail link mailHops.resultDetailsLink.style.display = 'block'; mailHops.resultMapLink.style.display = 'block'; //show details by default if(mailHops.options.show_details){ mailHops.resultContainerDetails.style.display = 'block'; mailHops.resultDetailsLink.setAttribute('class','text-link dataPaneMoreLink active'); } else{ mailHops.resultContainerDetails.style.display = 'none'; mailHops.resultDetailsLink.setAttribute('class','text-link dataPaneMoreLink'); } }; mailHops.getSecureTrans = function(ip){ for(var i=0; i 1 ? '.' + x[1] : ''; var rgx = /(\d+)(\d{3})/; while (rgx.test(x1)) { x1 = x1.replace(rgx, '$1' + ',' + '$2'); } return x1 + x2; }; mailHops.launchExternalURL = function(url){ var messenger = Components.classes["@mozilla.org/messenger;1"].createInstance().QueryInterface(Components.interfaces.nsIMessenger); messenger.launchExternalURL(url); }; mailHops.launchWhoIs = function(ip){ mailHops.launchExternalURL('http://www.mailhops.com/whois/'+ip); }; mailHops.launchSpamHausURL = function(ip){ mailHops.launchExternalURL('http://www.spamhaus.org/query/bl?ip='+ip); }; mailHops.launchMap = function(route){ if(route != '') { var lookupURL=mailHops.options.api_url+'/v1/map/?pb&app='+mailHops.appVersion+'&l='+mailHops.options.lan+'&u='+mailHops.options.unit+'&r='+String(route); if(mailHops.options.fkey != '') lookupURL += '&fkey='+mailHops.options.fkey; window.openDialog("chrome://mailhops/content/mailhopsMap.xul","MailHops",'toolbar=no,location=no,directories=no,menubar=yes,scrollbars=yes,close=yes,width=1024,height=768,resizable=yes', {src: lookupURL}); } }; // weather.style.backgroundImage = 'url(chrome://mailhops/content/images/weather mailHops.getWeatherIcon = function(icon){ var forecast_icons = {'clear-day': {'day':'sun', 'night':'sun'} , 'clear-night': {'day':'clear_night', 'night':'clear_night'} , 'rain': {'day':'rain','night':'rain'} , 'snow': {'day':'snow','night':'snow'} , 'sleet': {'day':'rain','night':'rain'} , 'wind': {'day':'clouds','night':'clouds'} , 'fog': {'day':'clouds','night':'clouds'} , 'cloudy': {'day':'clouds','night':'cloudy_night'} , 'partly-cloudy-day': {'day':'cloudy','night':'cloudy'} , 'partly-cloudy-night': {'day':'cloudy_night','night':'cloudy_night'} , 'hail': {'day':'rain','night':'rain'} , 'thunderstorm': {'day':'thunderstorm','night':'thunderstorm'} , 'tornado': {'day':'thunderstorm','night':'thunderstorm'} }; var hr = (new Date).getHours(); var time = (hr >= 4 && hr <= 18)?'day':'night'; return 'chrome://mailhops/content/images/weather/'+forecast_icons[icon][time]+'.png'; }; mailHops.saveResults = function(results){ if(!mailHops.msgURI) return false; var messenger = Components.classes["@mozilla.org/messenger;1"].createInstance().QueryInterface(Components.interfaces.nsIMessenger); var msgHdr = messenger.messageServiceFromURI(mailHops.msgURI).messageURIToMsgHdr(mailHops.msgURI); if(!msgHdr) return false; msgHdr.setStringProperty( "MH-Route", results ); }; mailHops.getResults = function(){ if(!mailHops.msgURI) return false; var messenger = Components.classes["@mozilla.org/messenger;1"].createInstance().QueryInterface(Components.interfaces.nsIMessenger); var msgHdr = messenger.messageServiceFromURI(mailHops.msgURI).messageURIToMsgHdr(mailHops.msgURI); if(!msgHdr) return false; return msgHdr.getStringProperty( "MH-Route" ); }; mailHops.refreshCache = function(){ mailHops.saveResults(''); mailHops.getRoute(); }; addEventListener ( "messagepane-loaded" , mailHops.setupEventListener , true ) ;