BugMeNot

It integrates BugMeNot into any login form (it retrieves all matching logins from bugmenot.com and autofills the login form)

2016-09-16 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name        BugMeNot
// @namespace   darkred
// @authors     hosts, Matt McCarthy, darkred
// @description It integrates BugMeNot into any login form  (it retrieves all matching logins from bugmenot.com and autofills the login form)
// @include     http://*
// @include     https://*
// @exclude     *bugmenot*
// @version     2016.09.16
// @grant       GM_xmlhttpRequest
// @grant       GM_setValue
// @grant       GM_getValue
// @grant       GM_log
// @grant       GM_openInTab
// @noframes
// @run-at      document-idle
// ==/UserScript==

// latest version by hosts: 01.03.09
// based on code found at http://www.oreillynet.com/pub/h/4171
// ----------------------------
// based on code by Matt McCarthy
// and included here with his gracious permission




// new logins gotten from the current page (reset on every page load)
var retrievals = 0;
// millisecond delay between a field losing focus and checking to see
// if any other of our fields has focus. If this is too low, the menu
// won't work because it will get "display: none" and its onclick
// won't fire.
var BLUR_TIMEOUT = 150;

//http://www.bugmenot.com/view/orasisx.net
//phoneRegex = /(?:http://)(.*)/.*?/;
//doma= location.href.match( phoneRegex );

// myString = location.href;
// domainnameRE = new RegExp('(?:https?://)(.*?)/.*?', 'i');
// domainname = myString.match(domainnameRE)
// domainname = domainname[1];
//alert (domainname);
var myString = location.href;
var domainnameRE = new RegExp('(?:https?://)(www\.)?(.*?)/.*?', 'i');
var domainname = myString.match(domainnameRE);
domainname = domainname[2];

// If the current domain name doesn't match the stored lastURL, then reset the counter
if (GM_getValue('lastURL').indexOf(domainname) == -1){
	var counter = 0;
	GM_setValue('counter', 0);
} else {
	counter = parseInt(GM_getValue('counter'));		// else retrieve stored counter value
}


// var allInputs = null;
var bmnView = 'http://bugmenot.com/view';
var bmnUri = bmnView + '/' + domainname;
var bmnHomeUri = 'http://bugmenot.com/';
var DEBUG = false;
// var bmnWrappers = new Object();

var Style = {
	menuLink: {
		border: 'none',
		backgroundColor: '#fff',
		color: '#000',
		display: 'block',
		padding: '2px',
		margin: '0',
		// width: '12em',
		width: '17em',
		fontSize: '8pt',
		fontWeight: 'normal',
		textDecoration: 'none'
	},
	menuLinkHover: {
		backgroundColor: '#316AC5',
		color: '#fff'
	},
	menuLinkWrapper: {
		textAlign: 'left',
		padding: '1px',
		margin: 0
	},
	bmnWrapper: {
		display: 'none',
		fontFamily: 'tahoma, verdana, arial, sans-serif',
		whiteSpace: 'nowrap',
		position: 'absolute',
		zIndex: 1000,
		padding: '2px',
		border: '1px solid #ACA899',
		backgroundColor: '#fff',
		opacity: '0.9',
		filter: 'alpha(opacity=90)'
	}
};
function copyProperties(to, from) {
	for (var i in from) {
		to[i] = from[i];
	}
}

function main() {
	processPasswordFields();
}

function getBmnWrapper(pwFieldIndex) {
	return document.getElementById('reify-bugmenot-bmnWrapper' +
	pwFieldIndex);
}


function processPasswordFields() {
	var allInputs = document.getElementsByTagName('input');
	//allInputslength = allInputs.length;
	var bmnContainer = document.createElement('div');
	bmnContainer.id = 'reify-bugmenot-container';
	var bodyEl = document.getElementsByTagName('body')[0];
	if (!bodyEl) return;
	for (var i = 0; i < allInputs.length; i++) {
		var pwField = allInputs[i];
		//GM_log (allInputs[i].type.toLowerCase());
		if (!(pwField.type && pwField.type.toLowerCase() == 'password')) {
			continue;
		}
		var previousTextFieldInd = getPreviousTextField(i, allInputs);
		if (previousTextFieldInd == - 1) {
			if (DEBUG) {
				GM_log('Couldn\'t find text field before password input ' +
				i + '.');
				continue;
			}
		}
		var usernameField = allInputs[previousTextFieldInd];
		usernameField.blur();		// Workaround for when the Username textbox has focus by default on page load
		usernameField.setAttribute('usernameInputIndex', previousTextFieldInd);
		usernameField.setAttribute('passwordInputIndex', i);
		Utility.addEventHandler(usernameField, 'focus', usernameField_onfocus);
		Utility.addEventHandler(usernameField, 'blur', usernameField_onblur);
		Utility.addEventHandler(pwField, 'focus', pwField_onfocus);
		Utility.addEventHandler(pwField, 'blur', pwField_onblur);
		pwField.setAttribute('usernameInputIndex', previousTextFieldInd);
		pwField.setAttribute('passwordInputIndex', i);

		// var getLoginLink = menuLink(bmnUri, 'Get login from BugMeNot', 'Get a login from BugMeNot', getLoginLink_onclick, Style.menuLink, previousTextFieldInd, i, menuLink_onmouseover, menuLink_onmouseout);
		if (counter == 0) {
			var myprompt = 'Get login from BugMeNot' + ' (' + (counter + 1) + '/-)';
			var myprompt2 = 'Get a login from BugMeNot';
		} else {
			var total = JSON.parse(GM_getValue('allUsernames')).length;
			myprompt = 'Try next login from BugMeNot' + ' (' + (counter + 1) + '/' + total + ')';
			myprompt2 = 'Try next login';
		}

		var getLoginLink = menuLink(bmnUri, myprompt, myprompt2, getLoginLink_onclick, Style.menuLink, previousTextFieldInd, i, menuLink_onmouseover, menuLink_onmouseout);
		var getLoginLinkWrapper = menuEntry(getLoginLink, Style.menuLinkWrapper);
		if (counter > 0) {
			var resetCounterLink = menuLink('', 'Reset login attempt counter', 'Resets the login attempt counter (reloads the page)', resetCounterLink_onclick, Style.menuLink, previousTextFieldInd, i, menuLink_onmouseover, menuLink_onmouseout);
			var resetCounterLinkWrapper = menuEntry(resetCounterLink, Style.menuLinkWrapper);
		}

		var fullFormLink = menuLink(bmnUri, 'More options', 'See more options for getting logins from BugMeNot.com ' + '(opens a new window)', openMenuLink_onclick, Style.menuLink, previousTextFieldInd, i, menuLink_onmouseover, menuLink_onmouseout);
		var fullFormLinkWrapper = menuEntry(fullFormLink, Style.menuLinkWrapper);

		var visitBmnLink = menuLink(bmnHomeUri, 'Visit BugMeNot', 'Go to the BugMeNot home page (opens a new window)', openMenuLink_onclick, Style.menuLink, previousTextFieldInd, i, menuLink_onmouseover, menuLink_onmouseout);
		var visitBmnLinkWrapper = menuEntry(visitBmnLink, Style.menuLinkWrapper);


		var bmnWrapper = document.createElement('div');
		bmnWrapper.id = 'reify-bugmenot-bmnWrapper' + i;
		bmnWrapper.className = 'reify-bugmenot-bmnWrapper';

		bmnWrapper.appendChild(getLoginLinkWrapper);
		if (counter > 0) {
			bmnWrapper.appendChild(resetCounterLinkWrapper);
		}
		bmnWrapper.appendChild(fullFormLinkWrapper);
		bmnWrapper.appendChild(visitBmnLinkWrapper);

		copyProperties(bmnWrapper.style, Style.bmnWrapper);
		bmnContainer.appendChild(bmnWrapper);
	}
	if (bmnContainer.hasChildNodes()) {
		bodyEl.appendChild(bmnContainer);
	}
}

function menuEntry(linkEl, styleObj) {
	var p = document.createElement('p');
	copyProperties(p.style, styleObj);
	p.appendChild(linkEl);
	return p;
}

function menuLink(href, text, title, onclick, styleObj, usernameInputIndex, passwordInputIndex, onmouseover, onmouseout) {
	var newMenuLink = document.createElement('a');
	newMenuLink.href = href;
	newMenuLink.appendChild(document.createTextNode(text));
	newMenuLink.title = title;
	newMenuLink.setAttribute('usernameInputIndex', usernameInputIndex);
	newMenuLink.setAttribute('passwordInputIndex', passwordInputIndex);
	Utility.addEventHandler(newMenuLink, 'click', onclick);
	Utility.addEventHandler(newMenuLink, 'mouseover', onmouseover);
	Utility.addEventHandler(newMenuLink, 'mouseout', onmouseout);
	copyProperties(newMenuLink.style, styleObj);
	return newMenuLink;
}

function menuLink_onmouseover(event) {
	event = event || window.event;
	var target = event.currentTarget || event.srcElement;
	copyProperties(target.style, Style.menuLinkHover);
}

function menuLink_onmouseout(event) {
	event = event || window.event;
	var target = event.currentTarget || event.srcElement;
	copyProperties(target.style, Style.menuLink);
}

function getLoginLink_onclick(event) {
	var allInputs = document.getElementsByTagName('input');
	if ((!allInputs[this.getAttribute('passwordInputIndex')].value.length && !allInputs[this.getAttribute('usernameInputIndex')].value.length) || confirm('Overwrite the current login entry?')) {
		getLogin(bmnUri, this.getAttribute('usernameInputIndex'), this.getAttribute('passwordInputIndex'));
	}
	menuLink_onmouseout({
		currentTarget: this
	});
	event.preventDefault && event.preventDefault();
	return false;
}

function openMenuLink_onclick(event) {
	if (typeof GM_openInTab != 'undefined') {
		GM_openInTab(this.href);
	} else {
		window.open(this.href);
	}
	menuLink_onmouseout({
		currentTarget: this
	});
	event.preventDefault && event.preventDefault();
	return false;
}

function resetCounterLink_onclick(){
	GM_setValue('counter', 0);
	window.location.reload();
}


function usernameField_onfocus(event) {
	var allInputs = document.getElementsByTagName('input');
	event = event || window.event;
	var target = event.currentTarget || event.srcElement;
	target.setAttribute('hasFocus', true);
	showHideBmnWrapper(target, allInputs[target.getAttribute('passwordInputIndex')], true);
}

function usernameField_onblur(event) {
	var allInputs = document.getElementsByTagName('input');
	event = event || window.event || this;
	var target = event.currentTarget || event.srcElement;
	target.setAttribute('hasFocus', false);
	var fRef = hideIfNoFocus(allInputs[target.getAttribute('usernameInputIndex')], allInputs[target.getAttribute('passwordInputIndex')]);
	// race condition: wait for other element's onfocus
	setTimeout(fRef, BLUR_TIMEOUT);
}

function pwField_onfocus(event) {
	var allInputs = document.getElementsByTagName('input');
	event = event || window.event;
	var target = event.currentTarget || event.srcElement;
	target.setAttribute('hasFocus', true);
	showHideBmnWrapper(allInputs[target.getAttribute('usernameInputIndex')], target, true);
}

function pwField_onblur(event) {
	var allInputs = document.getElementsByTagName('input');
	event = event || window.event;
	var target = event.currentTarget || event.srcElement;
	target.setAttribute('hasFocus', false);
	var fRef = hideIfNoFocus(allInputs[target.getAttribute('usernameInputIndex')], allInputs[target.getAttribute('passwordInputIndex')]);
	// race condition: wait for other element's onfocus
	setTimeout(fRef, BLUR_TIMEOUT);
}

function hideIfNoFocus(usernameField, pwField) {
	return (function () {
		var bUsernameFocus = usernameField.getAttribute('hasFocus');
		if (typeof bUsernameFocus == 'string') {
			bUsernameFocus = (bUsernameFocus && bUsernameFocus !== false);
		}
		var bPasswordFocus = pwField.getAttribute('hasFocus');
		if (typeof bPasswordFocus == 'string') {
			bPasswordFocus = (bPasswordFocus && bPasswordFocus !== false);
		}
		if ((!bUsernameFocus) && (!bPasswordFocus)) {
			showHideBmnWrapper(usernameField, pwField, false);
		}
	});
}

function showHideBmnWrapper(usernameField, pwField, show) {
	var bmnWrapper = getBmnWrapper(pwField.getAttribute('passwordInputIndex'));
	if (show) {
		bmnWrapper.style.display = 'block';
		positionBmnWrapper(bmnWrapper, usernameField, pwField);
	} else {
		//GM_log('hiding bugmenot wrapper');
		bmnWrapper.style.display = 'none';
		// Menu links may not get onmouseout event, so they get
		// stuck with the hover style unless we do this.
		var menuLinks = bmnWrapper.getElementsByTagName('div');
		for (var i = 0; i < menuLinks.length; i++) {
			copyProperties(menuLinks[i].style, Style.menuLink);
		}
	}
}

function positionBmnWrapper(bmnWrapper, usernameField, pwField) {
	var pwLeft = Utility.elementLeft(pwField);
	if (pwLeft + pwField.offsetWidth + bmnWrapper.offsetWidth +
	Utility.scrollLeft() + 10 < Utility.viewportWidth()) {
		bmnWrapper.style.left = (pwLeft + pwField.offsetWidth + 2) + 'px';
		bmnWrapper.style.top = Utility.elementTop(pwField) + 'px';
	} else {
		bmnWrapper.style.left = (Utility.elementLeft(usernameField) -
		bmnWrapper.offsetWidth - 2) + 'px';
		bmnWrapper.style.top = Utility.elementTop(usernameField) + 'px';
	}
}


// We have a uri param rather than assuming it's for the current
// page so this function can be modular and potentially used
// for pages other than the current one.
function getLogin(uri, usernameInputIndex, passwordInputIndex) {

	var allInputs = document.getElementsByTagName('input');
	var usernameField = allInputs[usernameInputIndex];
	var pwField = allInputs[passwordInputIndex];
	waitOrRestoreFields(usernameField, pwField, false);
	// var hostUri = location.hostname;
	var firstAttempt = retrievals == 0;
	var submitData = 'submit=This+login+didn%27t+work&num=' + retrievals +
	'&site=' + encodeURI(location.hostname);

	if (counter == 0){
		GM_xmlhttpRequest({
			method: firstAttempt ? 'get' : 'post',
			headers: firstAttempt ? null :
				{
					'Content-type': 'application/x-www-form-urlencoded'
				},
			data: firstAttempt ? null : submitData,
			url: firstAttempt ? uri : bmnView,
			onload: function (responseDetails) {
				if (responseDetails.status == 200) {
					waitOrRestoreFields(usernameField, pwField, true);
					// decoded = decodeit(responseDetails.responseText);
					var decoded = responseDetails.responseText;
					var doc = textToXml(decoded);
					if (!(doc && doc.documentElement)) {
						return Errors.say(Errors.malformedResponse);
					}



					var allUsernames = doc.documentElement.querySelectorAll('dd:nth-child(2) > kbd');
					var allPasswords = doc.documentElement.querySelectorAll('dd:nth-child(4) > kbd');
					var allUsernamesArray = [];
					var allPasswordsArray = [];
					for (var i = 0; i < allUsernames.length; i++) {
						allUsernamesArray.push(allUsernames[i].innerHTML);
						allPasswordsArray.push(allPasswords[i].innerHTML);
					}

					for (var j = 0; j < allUsernamesArray.length; j++){
						console.log(allUsernamesArray[j] + ', ' + allPasswordsArray[j]);
					}


					GM_setValue('allUsernames', JSON.stringify(allUsernamesArray));
					GM_setValue('allPasswords', JSON.stringify(allPasswordsArray));


					// var accountInfo = doc.documentElement.getElementsByTagName('td') [0];
					var accountInfo = doc.documentElement.getElementsByTagName('kbd') [0];
					if (!(accountInfo)) {
						return Errors.say(Errors.noLoginAvailable);
					}
					usernameField.value = accountInfo.childNodes[0].nodeValue;
					// var pwsField = doc.documentElement.getElementsByTagName('td') [1];
					var pwsField = doc.documentElement.getElementsByTagName('kbd') [1];
					pwField.value = pwsField.childNodes[0].nodeValue;
					retrievals++;
				} else {
					return Errors.say(Errors.xmlHttpFailure);
				}
			},
			onerror: function (responseDetails) {
				waitOrRestoreFields(usernameField, pwField, true);
				Errors.say(Errors.xmlHttpFailure);
			}
		});
	} else {
		var retrievedUsernames = [];
		var retrievedPasswords = [];
		retrievedUsernames = JSON.parse(GM_getValue('allUsernames'));
		retrievedPasswords = JSON.parse(GM_getValue('allPasswords'));

		for (var j = 0; j < retrievedUsernames.length; j++){
			console.log(retrievedUsernames[j] + ', ' + retrievedPasswords[j]);
		}

		usernameField.value = retrievedUsernames[counter];
		pwField.value = retrievedPasswords[counter];
	}

	counter = parseInt(counter);
	counter++;											// (after all is done..)
	GM_setValue('counter', counter);					// .. store just increased counter and..
	GM_setValue('lastURL', String(window.location)); 	// .. store current location as lastURL
}

function waitOrRestoreFields(usernameField, pwField, restore) {
	document.documentElement.style.cursor = restore ? 'default' : 'progress';
	usernameField.value = restore ? '' : 'Loading...';
	//usernameField.disabled = !restore;
	//pwField.disabled = !restore;
}

function getPreviousTextField(pwFieldIndex, allInputs) {
	//var allInputs = document.getElementsByTagName("input");
	for (var i = pwFieldIndex; i >= 0 && i < allInputs.length; i--)
		if (allInputs[i].type && (allInputs[i].type.toLowerCase() == 'text' || allInputs[i].type.toLowerCase() == 'email'))
			return i;
	return - 1;
}

/*
function decodeit(codedtext) {
	var regexkey = /var key = (.*?)\;/;
	var match = regexkey.exec(codedtext);
	if (match != null) {
		var key = parseInt(match[1]);
	} else {
		alert('decoded key cannot be found\nbugmenot site has changed');
	}
	var codedtext = codedtext.replace(/<script>d\('(.*?)'\)\;<\/script>/gi, aaa);
	//alert (codedtext);
	return codedtext;
	function aaa(str, strInput, offset, s) {
		return d(strInput);
	}
	function decoder(data) {
		var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
		var o1,
			o2,
			o3,
			h1,
			h2,
			h3,
			h4,
			bits,
			i = 0,
			enc = '';
		do {
			h1 = b64.indexOf(data.charAt(i++));
			h2 = b64.indexOf(data.charAt(i++));
			h3 = b64.indexOf(data.charAt(i++));
			h4 = b64.indexOf(data.charAt(i++));
			bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
			o1 = bits >> 16 & 255;
			o2 = bits >> 8 & 255;
			o3 = bits & 255;
			if (h3 == 64) enc += String.fromCharCode(o1);
			else if (h4 == 64) enc += String.fromCharCode(o1, o2);
			else enc += String.fromCharCode(o1, o2, o3);
		} while (i < data.length);
		return enc;
	}
	function d(strInput) {
		strInput = decoder(strInput);
		var strOutput = '';
		var intOffset = (key + 112) / 12;
		for (i = 4; i < strInput.length; i++) {
			thisLetter = strInput.charAt(i);
			thisCharCode = strInput.charCodeAt(i);
			newCharCode = thisCharCode - intOffset;
			strOutput += String.fromCharCode(newCharCode);
		}
		return strOutput;
	}
}
*/

function textToXml(t) {
	try {
		if (typeof DOMParser != undefined) {
			//t = toString(t);
			//			var dp = new DOMParser( );
			//			return dp.parseFromString(t, "text/xml");
			var parser = new DOMParser();
			//var t = t.replace(/<\?xml.*?\?>/g, ""); // strip <?xml ?> tag
			//t = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<rando>" + t + "</rando>";
			//t = t.replace(/&(?!\w*;)/g, "&");
			//alert(t);
			//alert(parser.parseFromString(t, "application/xml"));
			// return parser.parseFromString(t, 'application/xml');   // <--- the previous value
			return parser.parseFromString(t, 'text/html');
		}
		else {
			return null;
		}
	}
	catch (e) {
		return null;
	}
}

var Errors = {
	noLoginAvailable: 'Sorry, but BugMeNot.com had no login available ' +
	'for this site.\nIf you\'re feeling helpful, you can click "More ' +
	'options" to provide a login for future visitors.',
	malformedResponse: 'Sorry, but I couldn\'t understand the response ' +
	'from BugMeNot.com.\nThe service might be unavailable.',
	siteBlocked: 'Sorry, but I couldn\'t understand the response ' +
	'from BugMeNot.com.\nThe service might be unavailable.',
	xmlHttpFailure: 'There was an error in contacting BugMeNot.com.\n' +
	'The server may be unavailable or having internal errors.',
	say: function (msg) {
		alert(msg);
		return false;
	}
};

var Utility = {
	elementTop: function (el) {
		return Utility.recursiveOffset(el, 'offsetTop');
	},
	elementLeft: function (el) {
		return Utility.recursiveOffset(el, 'offsetLeft');
	},
	recursiveOffset: function (el, prop) {
		var dist = 0;
		while (el.offsetParent)
		{
			dist += el[prop];
			el = el.offsetParent;
		}
		return dist;
	},
	viewportWidth: function () {
		return Utility.detectAndUseAppropriateObj('clientWidth');
	},
	viewportHeight: function () {
		return Utility.detectAndUseAppropriateObj('clientHeight');
	},
	scrollLeft: function () {
		return Utility.detectAndUseAppropriateObj('scrollLeft');
	},
	scrollTop: function () {
		return Utility.detectAndUseAppropriateObj('scrollTop');
	},
	detectAndUseAppropriateObj: function (prop) {
		if (document.documentElement && document.documentElement[prop]) {
			return document.documentElement[prop];
		}
		else if (document.body && document.body[prop]) {
			return document.body[prop];
		} else {
			return - 1;
		}
	},
	addEventHandler: function (target, eventName, eventHandler) {
		if (target.addEventListener) {
			target.addEventListener(eventName, eventHandler, false);
		} else if (target.attachEvent) {
			target.attachEvent('on' + eventName, eventHandler);
		}
	}
};

main();
// to do
// http://www.bugmenot.com/view/thecavernforum.com  Site Blocked