Jump to content

User:GeneralNotability/cumarkips.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// <nowiki>
// @ts-check
// Chunks borrowed from [[User:Krinkle/Scripts/CVNSimpleOverlay_wiki.js]],
// [[User:GeneralNotability/ip-ext-info.js]], and [[MediaWiki:Gadget-markblocked.js]]

const cuMarkIPs_SPECIAL_IPs = [
	{ addr: '10.0.0.0', cidr: 8, color: 'red', hint: 'Internal IP' },
	{ addr: '172.16.0.0', cidr: 12, color: 'red', hint: 'Internal IP' },
	{ addr: '192.168.0.0', cidr: 16, color: 'red', hint: 'Internal IP' },
	{ addr: '127.0.0.0', cidr: 8, color: 'red', hint: 'Loopback (WTF?)' },
	{ addr: '185.15.56.0', cidr: 22, color: 'yellow', hint: 'WMF IP' },
	{ addr: '91.198.174.0', cidr: 24, color: 'yellow', hint: 'WMF IP' },
	{ addr: '198.35.26.0', cidr: 23, color: 'yellow', hint: 'WMF IP' },
	{ addr: '208.80.152.0', cidr: 22, color: 'yellow', hint: 'WMF IP' },
	{ addr: '103.102.166.0', cidr: 24, color: 'yellow', hint: 'WMF IP' },
	{ addr: '143.228.0.0', cidr: 16, color: 'orange', hint: 'US Congress' },
	{ addr: '12.185.56.0', cidr: 29, color: 'orange', hint: 'US Congress' },
	{ addr: '12.147.170.144', cidr: 28, color: 'orange', hint: 'US Congress' },
	{ addr: '74.119.128.0', cidr: 22, color: 'orange', hint: 'US Congress' },
	{ addr: '156.33.0.0', cidr: 16, color: 'orange', hint: 'US Congress' },
	{ addr: '165.119.0.0', cidr: 16, color: 'orange', hint: 'Executive Office of the President' },
	{ addr: '198.137.240.0', cidr: 23, color: 'orange', hint: 'Executive Office of the President' },
	{ addr: '204.68.207.0', cidr: 24, color: 'orange', hint: 'Executive Office of the President' },
	{ addr: '149.101.0.0', cidr: 16, color: 'orange', hint: 'US Department of Justice' },
	{ addr: '65.165.132.0', cidr: 24, color: 'orange', hint: 'US Dept of Homeland Security' },
	{ addr: '204.248.24.0', cidr: 24, color: 'orange', hint: 'US Dept of Homeland Security' },
	{ addr: '216.81.80.0', cidr: 20, color: 'orange', hint: 'US Dept of Homeland Security' },
	{ addr: '131.132.0.0', cidr: 14, color: 'orange', hint: 'Canadian Dept of National Defence' },
	{ addr: '131.136.0.0', cidr: 14, color: 'orange', hint: 'Canadian Dept of National Defence' },
	{ addr: '131.140.0.0', cidr: 15, color: 'orange', hint: 'Canadian Dept of National Defence' },
	{ addr: '192.197.82.0', cidr: 24, color: 'orange', hint: 'Canadian House of Commons' },
	{ addr: '194.60.0.0', cidr: 18, color: 'orange', hint: 'UK Parliament' },
	{ addr: '138.162.0.0', cidr: 16, color: 'orange', hint: 'US Department of the Navy' }
];

function cuMarkIPs_isIPInRange(addr, targetRange, targetCidr) {
	// https://stackoverflow.com/questions/503052/javascript-is-ip-in-one-of-these-subnets
	const mask = -1 << (32 - +targetCidr); // eslint-disable-line no-bitwise
	if (mw.util.isIPv4Address(addr, false)) {
		const addrMatch = addr.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
		const addrInt = (+addrMatch[1] << 24) + (+addrMatch[2] << 16) + (+addrMatch[3] << 8) + // eslint-disable-line no-bitwise
			(+addrMatch[4]); // eslint-disable-line no-bitwise
		const targetMatch = targetRange.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
		const targetInt = (+targetMatch[1] << 24) + (+targetMatch[2] << 16) + (+targetMatch[3] << 8) + // eslint-disable-line no-bitwise
			(+targetMatch[4]); // eslint-disable-line no-bitwise
		return (addrInt & mask) === (targetInt & mask); // eslint-disable-line no-bitwise
	}
	// TODO: figure out ipv6
}
/**
 * Get all IP userlinks on the page
 *
 * @param {JQuery} $content page contents
 * @return {Map} list of unique users on the page and their corresponding links
 */
function cuMarkIPs_getUsers($content) {
	const userLinks = new Map();

	const blockLinkRe = '^Special:Block\/(.*)$';
	$('a', $content).each(function () {
		if (!$(this).attr('title')) {
			// Ignore if the <a> doesn't have a title
			return;
		}
		const blockLinkMatch = $(this).attr('title').toString().match(blockLinkRe);
		if (!blockLinkMatch) {
			return;
		}
		const user = decodeURIComponent( blockLinkMatch[1] );
		if (mw.util.isIPAddress(user)) {
			if (!userLinks.get(user)) {
				userLinks.set(user, []);
			}
			userLinks.get(user).push($(this));
		}
	});
	return userLinks;
}

// On window load, get all the users on the page and check if they're in the special ranges
$.when( $.ready, mw.loader.using( 'mediawiki.util' ) ).then( function () {
	mw.hook('wikipage.content').add(function ($content) {
		const usersOnPage = cuMarkIPs_getUsers($content);
		usersOnPage.forEach(async (val, key, _) => {
			let color = '';
			let hint = '';
			for (const range of cuMarkIPs_SPECIAL_IPs) {
				if (cuMarkIPs_isIPInRange(key, range.addr, range.cidr)) {
					color = range.color;
					hint = range.hint;
					break;
				}
			}
			if (!color) {
				return;
			}
			val.forEach(($link) => {
				$link.css({ backgroundColor: color });
				$link.attr('title', hint);
			});
		});
	});
});
// </nowiki>