Sneakemail

By Russ Black Last update Jun 25, 2008 — Installed 1,916 times.
// --------------------------------------------------------------------
// 
// Sneakemail Script
// 
// Written by Russ Black
//
// Last updated June 25, 2008
// 
// To use this script you need to have a sneakemail.com account.
// You can get one for free at http://sneakemail.com/info.pl?sel=quick
// 
// --------------------------------------------------------------------
// 
// This is a Greasemonkey user script.  To install it, you need
// Greasemonkey 0.6.5 or later: http://greasemonkey.mozdev.org/
// Then restart Firefox and revisit this script.
// Under Tools, there will be a new menu item to "Install User Script".
// Accept the default configuration and install.
//
// To uninstall, go to Tools -> Greasemonkey -> Manage User Scripts,
// select "Sneakemail", and click Uninstall.
//
// --------------------------------------------------------------------
// 
// ==UserScript==
// @name           Sneakemail
// @namespace      http://russblack.com/userscripts/
// @description    Quickly create disposable email addresses
// @include        *
// ==/UserScript==

(function() {

  function xpath(expr, doc) {
    if (!doc) {
      doc = document;
    }
    var iter = document.evaluate(expr, doc, null, XPathResult.ANY_TYPE, null);
    var ret = [];
    var n;
    while (n = iter.iterateNext()) {
      ret.push(n);
    }
    return ret;
  }
  
 
var rulidReg = /value=\s*"(\d+)"\s*>\s*Example Allow\s*<\/option>/i
var addrIdReg = /name\s*=\s*"addrid"\s+value\s*=\s*"(\d+)"/i
var accountidReg = /name\s*=\s*"account_id"\s+value\s*=\s*"(\d+)"/i
var sidReg = /name\s*=\s*"sid"\s+value\s*=\s*"([^"]+)"/i
var addressReg = /\w+@sneakemail.com/i
var alreadyExistsReg = /already exists/i
var loginIncorrectReg = /\bincorrect\b/
var stillEvaluatingReg = /<a href="(\/.*?)">[^<]*still evaluating Sneakemail[^<]*<\/a>/i

var skipPastInsignificantText = " (string-length(normalize-space(translate(.,'"+unescape("%A0")+"+^*:',''))) > 1 and not(ancestor::script) ) "

var containsEmail = " (\
contains(.,'email')\
or contains(.,'e-mail')\
or contains(.,'e mail')\
or contains(.,'E Mail')\
or contains(.,'EMail')\
or contains(.,'EMAIL')\
or contains(.,'E MAIL')\
or contains(.,'E-MAIL')\
or contains(.,'E mail')\
or contains(.,'Email')\
or contains(.,'E-Mail')\
or contains(.,'E-mail')\
) "

var containsConfirm = " (\
contains(.,'confirm')\
or contains(.,'Confirm')\
or contains(.,'CONFIRM')\
or contains(.,'Re-enter')\
or contains(.,'Re-Enter')\
or contains(.,'RE-ENTER')\
or contains(.,'REENTER')\
or contains(.,'reenter')\
or contains(.,'Reenter')\
or contains(.,'Re-type')\
or contains(.,'Re-Type')\
or contains(.,'RE-TYPE')\
or contains(.,'RETYPE')\
or contains(.,'retype')\
or contains(.,'Retype')\
or contains(.,'Again')\
or contains(.,'again')\
or contains(.,'AGAIN')\
or contains(.,'Verify')\
or contains(.,'VERIFY')\
or contains(.,'verify')\
) "

var nodes=xpath("\
//input\
[\
	(not(@type) or @type='text') \
	and (not (contains(@value,'@sneakemail.com'))) \
	and \
	(\
		(preceding::text()["+skipPastInsignificantText+"][1] )\
		["
			+containsEmail+
			" and not "+containsConfirm+
			" and not \
			(\
				not(ancestor::form) \
				and count(//input[not(@type) or @type='text']) = 1 \
				and count(//input[@type='password']) = 1 \
				or \
				count(ancestor::form//input[not(@type) or @type='text']) = 1 \
				and count(ancestor::form//input[@type='password']) = 1 \
			)\
		]\
	)\
]\
")

for(var n in nodes) 
{
	var node = nodes[n]

	var btn = document.createElement('input')
	btn.type="button";
	btn.value="Create Sneakemail"
	btn.title="Right-click to change Sneakemail username"
	btn.newSneakEmailFunc=function () {newSneakEmail(btn)}
	btn.addEventListener('click',btn.newSneakEmailFunc,true)
	btn.addEventListener('contextmenu',function (e) { promptForCredentials();e.preventDefault()},true)
	
	var sneakemailDiv = document.createElement('div')
	sneakemailDiv.insertBefore(btn,null)
	node.parentNode.insertBefore(sneakemailDiv, node.nextSibling)
	
}

function Request(btn)
{
	this.btn = btn
	this.input = btn.parentNode.previousSibling
	var confirmNodes = xpath("following::input[2][(not(@type) or @type='text') and ( preceding::text()["+skipPastInsignificantText+"][1]\
	["+containsEmail+" and "+containsConfirm+" ])]",this.input);

	this.confirm=confirmNodes[0]
}

Request.prototype.restoreButton = function() 
{
	this.btn.value = "Create Sneakemail";
	this.btn.disabled = false;
}

Request.prototype.newAddress = function(address, addrId) 
{
	this.input.value=address
	if (this.confirm && !this.confirm.value)
	{
		this.confirm.value=address
	}
	this.addrId = addrId;
	this.btn.value = "Configure this address";
	this.btn.disabled = false;
	var editPropsURL = 'https://sneakemail.com/auth.pl?sel=addr&sid='+this.sid+'&addrid='+addrId+'&curfldrid=0'
	var editFunc=function() 
	{
		var win = window.open(editPropsURL,'Sneakemail','width=510,height=640,resizable=0,scrollbars=yes,menubar=no,status=yes')
		if (win != null)
		{
			win.focus()
		}
	}
	this.btn.removeEventListener('click',this.btn.newSneakEmailFunc,true)
	this.btn.addEventListener('click',editFunc,true)
}

Request.prototype.error = function(errorText)
{
	alert(errorText)
	this.restoreButton()
}

Request.prototype.create = function()
{
	this.btn.disabled = true;
	this.btn.value = "Please Wait...";
	var request = this;

	
	if (GM_getValue('username',"").length == 0)
	{
		if (!confirm("Press OK if you already have a Sneakemail account.\n\nPressing Cancel will let you register for Sneakemail (it's free) in a new window"))
		{
			var win = window.open("http://sneakemail.com/info.pl?sel=quick",'Sneakemail','width=510,height=640,resizable=0,scrollbars=yes,menubar=no,status=yes')
			if (win != null)
			{
				win.focus()
			}
			request.restoreButton();
			return;
		}
		var val = prompt('What is your Sneakemail username?')
		if (val == undefined) {request.restoreButton();return}
		GM_setValue('username',val)
	}
	if (GM_getValue('password',"").length == 0)
	{
		var val = prompt('What is your Sneakemail password?')
		if (val == undefined) {request.restoreButton();return}
		GM_setValue('password',val)
	}

	if (!this.label) 
	{
		var suggestion = window.location.host;
		suggestion = suggestion.replace(/.*\.(\w+\.\w+)/,'$1')
		
		this.label=prompt("Enter a label for this email",suggestion)
		if (!this.label) 
		{
			request.restoreButton()
			return
		}
	}
	
	var err = "There was an error creating the SneakEmail address";
	
	GM_xmlhttpRequest({method: 'GET',url: 'https://sneakemail.com/?username='+escape(GM_getValue('username',""))+'&password='+escape(GM_getValue('password',""))+'&to_create=Create+Address&save_username=on&save_password=on', onerror: function(){request.error($err)}, onload: function(responseDetails) {
		if (loginIncorrectReg.test(responseDetails.responseText))
		{
			var val = prompt('Sneakemail login information is incorrect.\nWhat is your Sneakemail username?',GM_getValue('username',''))
			if (val == undefined) {request.restoreButton();return}
			GM_setValue('username',val)
			val = prompt('What is your Sneakemail password?', GM_getValue('password',''))
			if (val == undefined) {request.restoreButton();return}
			GM_setValue('password',val)
			request.create()
			return;
		}
	
		// first find the session Id
		var sidExec = sidReg.exec(responseDetails.responseText)
		if (!sidExec)
		{
			request.error("Can't find sneakemail session id")
			return
		}
		request.sid=sidExec[1]

		var handleNewAddrPage = function(responseDetails) {
			var rulid=rulidReg.exec(responseDetails.responseText)
			if (!rulid) {request.error("can't find rul_id");return}
			var accountid=accountidReg.exec(responseDetails.responseText)
			if (!accountid) {request.error("can't find account_id");return}
			var createAddressURL='https://sneakemail.com/auth.pl?label='+request.label+'&phrase_slot=1&rulid='+rulid[1]+'&fldrid=0&notes=&submit=Create+Address&sid='+request.sid+'&behavior=new_addr&account_id='+accountid[1]+'&curfldrid=0'

			GM_xmlhttpRequest({method: 'GET',url: createAddressURL, onerror: function(){request.error($err)}, onload: function(responseDetails) {
				if (alreadyExistsReg.test(responseDetails.responseText)) {
					request.label = null;
					alert('The label already exists in your sneakemail account.  Please choose a different label')
					request.create()
					return;
				}
				var newAddress = addressReg.exec(responseDetails.responseText)
				if (!newAddress) {
					request.error("Can't locate new address");
					return;
				}
				var addrId = addrIdReg.exec(responseDetails.responseText)
				if (!addrId) 
				{
					request.error("Can't locate address id of new address");
					return;
				}
				request.newAddress(newAddress, addrId[1])
			}})
		}

		if (stillEvaluatingReg.test(responseDetails.responseText))
		{
			GM_xmlhttpRequest({method: 'GET',url: "https://sneakemail.com/auth.pl?sel=new_addr&sid="+request.sid, onerror: function(){request.error($err)}, onload: handleNewAddrPage})
		}
		else 
		{
			// we're at the new address page now, handle it.
			handleNewAddrPage(responseDetails)
		}

	}})
}

function newSneakEmail(btn) {
	new Request(btn).create()
}

var stillEvaluatingExec = stillEvaluatingReg.exec(document.documentElement.innerHTML)
if (stillEvaluatingExec != null)
{
	document.location = "https://sneakemail.com"+stillEvaluatingExec[1]
}
else
{
	var notSecureExec = document.location.toString().match("http(://sneakemail.com/.*)")
	if (notSecureExec)
	{
		document.location = "https" + notSecureExec[1];
	}
}

function promptForCredentials()
{
	var val = prompt('What is your Sneakemail username?',GM_getValue('username',''))
	if (val == undefined) return
	GM_setValue('username',val)

	val = prompt('What is your Sneakemail password?', GM_getValue('password',''))
	if (val == undefined) return
	GM_setValue('password',val)
}

function loginToSneakemail()
{
	if (GM_getValue('username',"").length == 0 || GM_getValue('password',"").length == 0 )
	{
		promptForCredentials()
	}
	window.open('https://sneakemail.com/?username='+escape(GM_getValue('username',""))+'&password='+escape(GM_getValue('password',""))+'&to_desktop-find=Login%2FFind&save_username=on&save_password=on',
	  'Sneakemail','width=510,height=640,resizable=0,scrollbars=yes,menubar=no,status=yes')
}

GM_registerMenuCommand("Set Sneakemail Login Info", promptForCredentials)
GM_registerMenuCommand("My Sneakemail Account", loginToSneakemail)

})();