// ==UserScript==
// @name (Show IP) - Show information tooltips on various sites (mutation observer)
// @namespace Violentmonkey Scripts
// @match https://portal.azure.com/*
// @grant none
// @version 1.5
// @author chaoscreater
// @description 1/16/2024, 8:12:42 PM
// @downloadURL none
// ==/UserScript==
(function()
{
'use strict';
var ipAddress = ""; // Global variable
async function fetchIPAddress() {
try {
let response = await fetch("https://api64.ipify.org?format=json");
let data = await response.json();
ipAddress = data.ip; // Assign to the global variable
console.log("Fetched IP:", ipAddress);
document.querySelector(".ipaddress").textContent = ipAddress;
return ipAddress;
} catch (error) {
console.error("Error fetching IP:", error);
}
}
// Example: Call the function and make use of ipAddress globally
fetchIPAddress().then(() => {
console.log("Global IP Address:", ipAddress); // This works globally after the async function resolves
// $(document).ready(function () {
// $.getJSON("http://jsonip.com/?callback=?", function (data) {
// console.log(data);
// // alert(data.ip);
// });
// });
// // Main function to display IP address
// function displayIPAddress() {
// getPublicIPAddress().then(ipAddress => {
// alert('Your public IP address is: ' + ipAddress);
// });
// }
// // Call the function when the page loads
// window.addEventListener('load', displayIPAddress);
//getIPAddress.then(function(ipAddress)
//{
var reminderDiv = document.createElement('div');
var site = location.hostname;
var contentHTML = '';
// testing
var site = window.location.href;
function transformAzureUrl(currentUrl) {
const url = new URL(currentUrl);
const hash = url.hash;
// Find the "providers" part in the URL hash
const parts = hash.split('/');
const providersIndex = parts.indexOf('providers');
if (providersIndex !== -1 && providersIndex + 1 < parts.length) {
// Extract the provider and service part
const providerPath = parts.slice(providersIndex + 1, providersIndex + 3).join('/');
// Encode '/' as '%2F'
const encodedPath = encodeURIComponent(providerPath);
// Construct the new URL
return `https://portal.azure.com/#browse/${encodedPath}`;
}
return null; // Return null if "providers" is not found
}
//console.log("Rickscriptxxx - 4th step --- " + site);
if (site.includes('portal.azure.com')) {
var DisplayPopup = true;
var Delay_Load = true;
contentHTML = 'Shift + F : Filter by keyword
' +
'CTRL+Shift + F : Filter by keyword and click on Load More
' +
'CTRL+SHIFT+ L (hold CTRL+SHIFT while releasing L) to click on Load More
' +
'CTRL+Shift + Z (hold CTRL+SHIFT while releasing Z) : Reset filter
' +
'Great for checking Activity Logs, Sign-in logs or blobs in a Storage account container etc...' +
'
Public IP Address: ' + ipAddress + '
';
if ((site.includes('portal.azure.com')) && (site.includes('Microsoft.Compute/virtualMachines')))
{
//console.log("Rickscript - catch-all")
// open in new tab
//contentHTML = 'Virtual Machines
';
// open in current tab
//contentHTML += '
Virtual Machines
';
const newUrl = transformAzureUrl(site);
contentHTML += '
Virtual Machines
'; // open in current tab
}
}
// Version 2
function createPopup()
{
if (DisplayPopup === true)
{
var reminderDiv = document.createElement('div');
reminderDiv.id = 'yourPopupId';
var dragHandle = document.createElement('div');
dragHandle.style.height = '20px';
dragHandle.style.backgroundColor = '#ccc';
dragHandle.style.cursor = 'move';
dragHandle.innerHTML = 'Drag here';
dragHandle.style.textAlign = 'center';
reminderDiv.appendChild(dragHandle);
var toggleButton = document.createElement('button');
toggleButton.innerHTML = 'Show / Hide';
toggleButton.style.marginTop = '10px';
toggleButton.style.marginBottom = '10px';
reminderDiv.appendChild(toggleButton);
var contentDiv = document.createElement('div');
/*
if (!site.toLowerCase().includes('temu.com/nz/bgt_orders.html') && !site.toLowerCase().includes('temu.com/bgt_orders.html')) {
contentHTML += '
Long running deals
Forum
';
}
*/
contentDiv.innerHTML = contentHTML;
reminderDiv.appendChild(contentDiv);
reminderDiv.style.position = 'fixed';
reminderDiv.style.padding = '10px 10px 0px 10px';
reminderDiv.style.backgroundColor = 'cyan';
reminderDiv.style.border = '2px solid black';
reminderDiv.style.zIndex = '10000';
reminderDiv.style.width = localStorage.getItem('popupWidth_' + window.location.origin) || '290px';
reminderDiv.style.maxWidth = '500px';
reminderDiv.style.maxHeight = '900px';
reminderDiv.style.wordWrap = 'break-word';
reminderDiv.style.resize = 'both';
reminderDiv.style.overflow = 'auto';
reminderDiv.style.top = localStorage.getItem('popupTop_' + window.location.origin) || '50%';
reminderDiv.style.left = localStorage.getItem('popupLeft_' + window.location.origin) || '10px';
// Check if isContentVisible is not found in local storage, default to true
var isContentVisible = localStorage.getItem('isContentVisible_' + window.location.origin);
if (isContentVisible === null) {
isContentVisible = true;
} else {
isContentVisible = isContentVisible === 'true';
}
if (!isContentVisible) {
contentDiv.style.display = 'none';
reminderDiv.style.height = 'auto';
localStorage.setItem('popupOriginalWidth_' + window.location.origin, reminderDiv.style.width);
dragHandle.style.width = toggleButton.offsetWidth + 'px';
reminderDiv.style.width = 'auto';
dragHandle.style.width = '';
}
toggleButton.addEventListener('click', function () {
isContentVisible = !isContentVisible;
localStorage.setItem('isContentVisible_' + window.location.origin, isContentVisible);
if (!isContentVisible) {
contentDiv.style.display = 'none';
reminderDiv.style.height = 'auto';
localStorage.setItem('popupOriginalWidth_' + window.location.origin, reminderDiv.style.width);
dragHandle.style.width = toggleButton.offsetWidth + 'px';
reminderDiv.style.width = 'auto';
} else {
contentDiv.style.display = 'block';
reminderDiv.style.height = 'auto';
reminderDiv.style.width = localStorage.getItem('popupOriginalWidth_' + window.location.origin);
dragHandle.style.width = '';
}
});
var currentUrl = window.location.href;
//console.log("Rickscript - currentUrl is ---" + currentUrl);
// This bit is only for specific Azure pages that we don't want to move the popup box freely, unless Alt key is pressed
if ((currentUrl.includes('https://portal.azure.com/#view/Microsoft_Azure_PIMCommon/ActivationMenuBlade/~/aadmigratedroles')) || (currentUrl.includes('/providers/Microsoft.Sql/servers'))) {
dragHandle.addEventListener('mousedown', function (e) {
if (!e.altKey) return; // Only proceed if Alt key is pressed
var offsetX = e.clientX - parseInt(window.getComputedStyle(reminderDiv).left);
var offsetY = e.clientY - parseInt(window.getComputedStyle(reminderDiv).top);
function mouseMoveHandler(e) {
if (!e.altKey) {
mouseUpHandler(); // Stop dragging if Alt key is released
return;
}
reminderDiv.style.top = (e.clientY - offsetY) + 'px';
reminderDiv.style.left = (e.clientX - offsetX) + 'px';
}
function mouseUpHandler() {
window.removeEventListener('mousemove', mouseMoveHandler);
window.removeEventListener('mouseup', mouseUpHandler);
localStorage.setItem('popupTop_' + window.location.origin, reminderDiv.style.top);
localStorage.setItem('popupLeft_' + window.location.origin, reminderDiv.style.left);
}
window.addEventListener('mousemove', mouseMoveHandler);
window.addEventListener('mouseup', mouseUpHandler);
});
} else {
// Allow dragging without Alt key for other websites
dragHandle.addEventListener('mousedown', function (e) {
var offsetX = e.clientX - parseInt(window.getComputedStyle(reminderDiv).left);
var offsetY = e.clientY - parseInt(window.getComputedStyle(reminderDiv).top);
function mouseMoveHandler(e) {
reminderDiv.style.top = (e.clientY - offsetY) + 'px';
reminderDiv.style.left = (e.clientX - offsetX) + 'px';
}
function mouseUpHandler() {
window.removeEventListener('mousemove', mouseMoveHandler);
window.removeEventListener('mouseup', mouseUpHandler);
localStorage.setItem('popupTop_' + window.location.origin, reminderDiv.style.top);
localStorage.setItem('popupLeft_' + window.location.origin, reminderDiv.style.left);
}
window.addEventListener('mousemove', mouseMoveHandler);
window.addEventListener('mouseup', mouseUpHandler);
});
}
document.body.appendChild(reminderDiv);
// Calculate maximum allowable top and left positions
var maxTop = window.innerHeight - reminderDiv.offsetHeight;
var maxLeft = window.innerWidth - reminderDiv.offsetWidth;
var storedTop = parseInt(localStorage.getItem('popupTop_' + window.location.origin)) || 0;
var storedLeft = parseInt(localStorage.getItem('popupLeft_' + window.location.origin)) || 0;
//reminderDiv.style.top = Math.min(Math.max(storedTop, 0), maxTop) + 'px';
reminderDiv.style.top = Math.min(Math.max(storedTop, 80), maxTop) + 'px';
reminderDiv.style.left = Math.min(Math.max(storedLeft, 0), maxLeft) + 'px';
reminderDiv.addEventListener('mousemove', function () {
if (isContentVisible) {
localStorage.setItem('popupWidth_' + window.location.origin, reminderDiv.style.width);
localStorage.setItem('popupHeight_' + window.location.origin, reminderDiv.style.height);
}
});
}
}
function displayPopup() {
if (DisplayPopup === true)
{
var existingPopup = document.getElementById('yourPopupId');
if (!existingPopup) {
//console.log("Rickscript - popup doesn't exist")
createPopup();
} else {
//console.log("Rickscript - popup exists already!")
existingPopup.parentNode.removeChild(existingPopup);
var popupTop = localStorage.getItem('popupTop_' + window.location.origin) || '50%';
var popupLeft = localStorage.getItem('popupLeft_' + window.location.origin) || '10px';
var popupWidth = localStorage.getItem('popupWidth_' + window.location.origin) || '290px';
var popupHeight = localStorage.getItem('popupHeight_' + window.location.origin) || 'auto';
var maxTop = window.innerHeight - existingPopup.offsetHeight;
var maxLeft = window.innerWidth - existingPopup.offsetWidth;
var storedTop = parseInt(localStorage.getItem('popupTop_' + window.location.origin)) || 0;
var storedLeft = parseInt(localStorage.getItem('popupLeft_' + window.location.origin)) || 0;
existingPopup.style.top = Math.min(Math.max(storedTop, 0), maxTop) + 'px';
existingPopup.style.left = Math.min(Math.max(storedLeft, 0), maxLeft) + 'px';
//existingPopup.style.top = popupTop;
//existingPopup.style.left = popupLeft;
existingPopup.style.width = popupWidth;
existingPopup.style.height = popupHeight;
createPopup();
}
}
}
if (DisplayPopup === true) {
if (Delay_Load === true) {
setTimeout(function() {
// Your logic to check if popup should be displayed
if (DisplayPopup === true) {
if (!sessionStorage.getItem('popupCreated')) {
displayPopup();
sessionStorage.setItem('popupCreated', 'true');
}
window.addEventListener('beforeunload', function() {
sessionStorage.removeItem('popupCreated');
});
}
}, 2000); // Wait for 2 seconds before executing
} else {
// Your logic to check if popup should be displayed without delay
if (!sessionStorage.getItem('popupCreated')) {
displayPopup();
sessionStorage.setItem('popupCreated', 'true');
}
window.addEventListener('beforeunload', function() {
sessionStorage.removeItem('popupCreated');
});
}
}
// Function to handle URL changes
function handleUrlChange(mutationsList, observer) {
for (let mutation of mutationsList) {
if (mutation.type === 'childList' || mutation.type === 'attributes') {
const currentUrl = window.location.href;
if (currentUrl !== observer.previousUrl)
{
//console.log("Rickscript - currentUrl is ---" + currentUrl);
//console.log("Rickscript - previousUrl is ---" + observer.previousUrl);
// Show Azure Pricing Calculator API results - for a future project?
/*
fetch('https://prices.azure.com/api/retail/prices')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
// Work with JSON data here
console.log(data);
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
*/
// Sentinel
//if (!observer.previousUrl.includes('Microsoft_Azure_Security_Insights') && currentUrl.includes('Microsoft_Azure_Security_Insights')) {
if (!observer.previousUrl.includes('Microsoft_Azure_Security_Insights') && currentUrl.includes('Microsoft_Azure_Security_Insights')) {
// Transition from a URL without 'Microsoft_Azure_Security_Insights' to a URL with 'Microsoft_Azure_Security_Insights'
//console.log("Rickscript - Transition from a URL without 'Microsoft_Azure_Security_Insights' to a URL with 'Microsoft_Azure_Security_Insights'")
observer.previousUrl = currentUrl;
if (currentUrl.includes('portal.azure.com') && currentUrl.includes('Microsoft_Azure_Security_Insights')) {
var DisplayPopup = true;
//var Delay_Load = true;
//contentHTML += '$2/GB : Filter by keyword
'
contentHTML += '
$2/GB
'
displayPopup()
}
// console.log("Rickscript - URL change - GOOOOOOOOOOOOOOOOOOOOOOOOOD!");
} else if (!observer.previousUrl.includes('Microsoft.OperationalInsights/workspaces') && currentUrl.includes('Microsoft.OperationalInsights/workspaces')) {
//console.log("Rickscript - Transition from a URL without 'Microsoft.OperationalInsights/workspaces' to a URL with 'Microsoft.OperationalInsights/workspaces'")
observer.previousUrl = currentUrl;
//console.log("Rickscript - fuuuuuuuck")
if (currentUrl.includes('portal.azure.com') && currentUrl.includes('Microsoft.OperationalInsights/workspaces')) {
var DisplayPopup = true;
//var Delay_Load = true;
contentHTML += '
First 5GB free, then $2.30/GB
'
displayPopup()
}
} else if (!observer.previousUrl.includes('Microsoft.Compute/virtualMachines') && currentUrl.includes('Microsoft.Compute/virtualMachines')) {
//console.log("Rickscript - Transition from a URL without 'Microsoft.Compute/virtualMachines' to a URL with 'Microsoft.Compute/virtualMachines'")
observer.previousUrl = currentUrl;
//console.log("Rickscript - fuuuuuuuck")
if (currentUrl.includes('portal.azure.com') && currentUrl.includes('Microsoft.Compute/virtualMachines')) {
var DisplayPopup = true;
//var Delay_Load = true;
const newUrl = transformAzureUrl(currentUrl);
//console.log("Rickscript ---", newUrl);
contentHTML += '
B4ms 4 cores, 16GB RAM - ~$122
' +
//'Virtual Machines
'; // open in current tab
'Virtual Machines
'; // open in current tab
displayPopup()
}
} else if (!observer.previousUrl.includes('Microsoft_AAD_ConditionalAccess') && currentUrl.includes('Microsoft_AAD_ConditionalAccess')) {
//console.log("Rickscript - Transition from a URL without 'Microsoft_AAD_ConditionalAccess' to a URL with 'Microsoft_AAD_ConditionalAccess'")
observer.previousUrl = currentUrl;
//console.log("Rickscript - fuuuuuuuck")
if (currentUrl.includes('portal.azure.com') && currentUrl.includes('Microsoft_AAD_ConditionalAccess')) {
var DisplayPopup = true;
//var Delay_Load = true;
contentHTML += '
$9.072/user/month
'
displayPopup()
}
} else if (!observer.previousUrl.includes('Microsoft_Azure_Security') && currentUrl.includes('Microsoft_Azure_Security')) {
//console.log("Rickscript - Transition from a URL without 'Microsoft_Azure_Security' to a URL with 'Microsoft_Azure_Security'")
observer.previousUrl = currentUrl;
//console.log("Rickscript - fuuuuuuuck")
if (currentUrl.includes('portal.azure.com') && currentUrl.includes('Microsoft_Azure_Security')) {
var DisplayPopup = true;
//var Delay_Load = true;
contentHTML += '
~$22/item/month for Servers/AppService/SQL
'
displayPopup()
}
} else if (!observer.previousUrl.includes('Microsoft.Storage') && currentUrl.includes('Microsoft.Storage')) {
//console.log("Rickscript - Transition from a URL without 'Microsoft.Storage' to a URL with 'Microsoft.Storage'")
observer.previousUrl = currentUrl;
//console.log("Rickscript - fuuuuuuuck")
if (currentUrl.includes('portal.azure.com') && currentUrl.includes('Microsoft.Storage')) {
var DisplayPopup = true;
//var Delay_Load = true;
contentHTML += '
Block Blob Storage, General Purpose V2, LRS, Hot Access - $2.60/GB
'
displayPopup()
}
} else if (!observer.previousUrl.includes('Microsoft.Network/firewallPolicies') && currentUrl.includes('Microsoft.Network/firewallPolicies')) {
//console.log("Rickscript - Transition from a URL without 'Microsoft.Network/firewallPolicies' to a URL with 'Microsoft.Network/firewallPolicies'")
observer.previousUrl = currentUrl;
//console.log("Rickscript - fuuuuuuuck")
if (currentUrl.includes('portal.azure.com') && currentUrl.includes('Microsoft.Network/firewallPolicies')) {
var DisplayPopup = true;
//var Delay_Load = true;
contentHTML += '
$151.20/policy/region
'
displayPopup()
}
} else if (!observer.previousUrl.includes('Microsoft.Web') && currentUrl.includes('Microsoft.Web')) {
//console.log("Rickscript - Transition from a URL without 'Microsoft.Web' to a URL with 'Microsoft.Web'")
observer.previousUrl = currentUrl;
//console.log("Rickscript - fuuuuuuuck")
if (currentUrl.includes('portal.azure.com') && currentUrl.includes('Microsoft.Web')) {
var DisplayPopup = true;
//var Delay_Load = true;
contentHTML += '
$0.02548 - $3.948 per hour per instance per month
' +
'Azure Functions : $0.392 - $0.784 per million executions per month
'
displayPopup()
}
} else {
//console.log("Rickscript - catch-all")
observer.previousUrl = currentUrl;
/*
contentHTML = ""
console.log("Rickscript --- currentUrl:", currentUrl);
console.log("Rickscript --- site:", site);
if ((site.includes('portal.azure.com')) && (site.includes('Microsoft.Compute/virtualMachines')))
{
//console.log("Rickscript - catch-all")
// open in new tab
//contentHTML = 'Virtual Machines
';
// open in current tab
contentHTML = 'Virtual Machines
';
}
*/
if ((site.includes('portal.azure.com')) && !(currentUrl.includes('Microsoft_Azure_Security_Insights') || currentUrl.includes('Microsoft.OperationalInsights/workspaces') || currentUrl.includes('Microsoft.Compute/virtualMachines') || currentUrl.includes('Microsoft_AAD_ConditionalAccess') || currentUrl.includes('Microsoft_Azure_Security') || currentUrl.includes('Microsoft.Storage') || currentUrl.includes('Microsoft.Web') || currentUrl.includes('Microsoft.Network/firewallPolicies')))
{
var DisplayPopup = true;
var Delay_Load = true;
contentHTML = 'MutationObserver
' +
'Shift + F : Filter by keyword
' +
'CTRL+Shift + F : Filter by keyword and click on Load More
' +
'CTRL+SHIFT+ L (hold CTRL+SHIFT while releasing L) to click on Load More
' +
'CTRL+Shift + Z (hold CTRL+SHIFT while releasing Z) : Reset filter
' +
'Great for checking Activity Logs, Sign-in logs or blobs in a Storage account container etc...' +
'
Public IP Address: ' + ipAddress + '
';
displayPopup()
}
}
}
break;
}
}
}
// Start observing the DOM for URL changes
const observer = new MutationObserver(handleUrlChange);
observer.observe(document.documentElement, { subtree: true, childList: true, attributes: true });
observer.previousUrl = window.location.href;
});
})();