User:GeneralNotability/spurlookup.js
(async function( $, mw ) {
'use strict';
if ((mw.config.get('wgNamespaceNumber') === mw.config.get('wgNamespaceIds').user && mw.config.get('wgTitle') === 'GeneralNotability/SpurLookup') &&
mw.config.get('wgAction') === 'view') {
await mw.loader.load(['mediawiki.util', 'mediawiki.user']);
const contentdiv = document.getElementById('spur-content');
contentdiv.textContent = ''; // clear children
const noScriptDiv = document.getElementById('spur-noscript');
noScriptDiv.textContent = ''; // nuke the "you don't have the script" warning
const ip = mw.util.getParamValue('address');
if (!ip) {
contentdiv.innerText = 'Address parameter was not specified in the URL';
return;
}
if (!mw.util.isIPAddress(ip)) {
contentdiv.innerText = `${ip} is not a valid IP address`;
return;
}
mw.config.set("wgRelevantUserName", ip);
let apiKey = mw.user.options.get('userjs-spurkey');
if (!apiKey) {
const mwapi = new mw.Api();
apiKey = prompt('Please enter your Spur API key');
if (!apiKey) {
contentdiv.innerText = 'An API key is required to use this tool';
return;
}
mw.user.options.set('userjs-spurkey', apiKey);
await mwapi.saveOption('userjs-spurkey', apiKey);
}
// Actually send the query
const apiUrl = `https://api.spur.us/v1/context/${ip}`;
let apiResponse;
try {
apiResponse = $.ajax({
async: false,
url: apiUrl,
headers: {'Token': apiKey},
dataType: 'json'
});
} catch (err) {
contentdiv.innerText = `Failed to query the Spur API: ${err}`;
return;
}
console.log(apiResponse);
const responseJson = apiResponse.responseJSON;
let newHtml = '';
newHtml += `This search took ${apiResponse.getResponseHeader('x-query-cost')} queries.
`;newHtml += `You have ${apiResponse.getResponseHeader('x-balance-remaining')} queries left this month.
`;newHtml += `
- IP: ${responseJson.ip}
- Suspected VPN/proxy: ${responseJson.anonymous}
- AS${responseJson.as.number}, belongs to ${responseJson.as.organization}
- Assignment: ${responseJson.assignment} \n`;
- Infrastructure: ${responseJson.infrastructure} \n`;
- # devices on IP (estimated): ${responseJson.devices.estimate} \n`;
- VPN operators:\n';
newHtml += '
- ';
- ${oper.name} \n`;
for (const oper of responseJson.vpnOperators.operators) {
newHtml += `
}
newHtml += '
\n';
- GeoLite data: ${JSON.stringify(responseJson.geolite)} \n`;
- Device behaviors:\n';
newHtml += '
- ';
- ${JSON.stringify(behavior.name)} \n`;
for (const behavior of responseJson.deviceBehaviors.behaviors) {
newHtml += `
}
newHtml += '
\n';
- Proxy services:\n';
newHtml += '
- ';
- ${JSON.stringify(proxy)} \n`;
for (const proxy of responseJson.proxiedTraffic.proxies) {
newHtml += `
}
newHtml += '
\n';
- Estimated user location: ${JSON.stringify(responseJson.geoPrecision)} \n`;
- Similar IPs:\n';
newHtml += '
\n \n';
- Associated SSIDs:\n';
newHtml += '
- ';
- ${wifi} \n`;
for (const wifi of responseJson.wifi.ssids) {
newHtml += `
}
newHtml += '
\n';
`;
if (responseJson.assignment.exists) {
newHtml += `
}
if (responseJson.infrastructure) {
newHtml += `
}
if (responseJson.devices && responseJson.devices.estimate) {
newHtml += `
}
if (responseJson.vpnOperators.exists) {
newHtml += '
}
if (responseJson.geolite) {
newHtml += `
}
if (responseJson.deviceBehaviors.exists) {
newHtml += '
}
if (responseJson.proxiedTraffic.exists) {
newHtml += '
}
if (responseJson.geoPrecision.exists) {
newHtml += `
}
if (responseJson.similarIPs.exists) {
newHtml += '
}
if (responseJson.wifi.exists) {
newHtml += '
}
newHtml += '
contentdiv.innerHTML = newHtml;
}
}) (jQuery, mediaWiki );