mirror of
https://github.com/pacnpal/simpleguardhome.git
synced 2025-12-20 04:21:13 -05:00
docs(userscript/README.md): enhance configuration instructions and clarify connection testing feat(userscript/simpleguardhome-404-checker.user.js): add connection testing and notification features for unblocking domains
252 lines
9.1 KiB
JavaScript
252 lines
9.1 KiB
JavaScript
// ==UserScript==
|
|
// @name SimpleGuardHome 404 Checker
|
|
// @namespace http://tampermonkey.net/
|
|
// @version 0.1
|
|
// @description Detects 404 responses and checks if they are blocked by AdGuard Home
|
|
// @author SimpleGuardHome
|
|
// @match *://*/*
|
|
// @grant GM_xmlhttpRequest
|
|
// @grant GM_getValue
|
|
// @grant GM_setValue
|
|
// @grant GM_registerMenuCommand
|
|
// @connect *
|
|
// @run-at document-start
|
|
// ==/UserScript==
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
// Default configuration
|
|
const DEFAULT_CONFIG = {
|
|
host: 'http://localhost',
|
|
port: 8000 // SimpleGuardHome runs on port 8000 by default
|
|
};
|
|
|
|
// Get current configuration
|
|
function getConfig() {
|
|
return {
|
|
host: GM_getValue('host', DEFAULT_CONFIG.host),
|
|
port: GM_getValue('port', DEFAULT_CONFIG.port)
|
|
};
|
|
}
|
|
|
|
// Test SimpleGuardHome connection
|
|
async function testConnection(host, port) {
|
|
try {
|
|
const response = await new Promise((resolve, reject) => {
|
|
GM_xmlhttpRequest({
|
|
method: 'GET',
|
|
url: `${host}:${port}/health`,
|
|
headers: {'Accept': 'application/json'},
|
|
onload: resolve,
|
|
onerror: reject
|
|
});
|
|
});
|
|
return response.status === 200;
|
|
} catch (error) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Show configuration dialog
|
|
async function showConfigDialog() {
|
|
const config = getConfig();
|
|
const currentSettings = `Current Settings:
|
|
- Host: ${config.host}
|
|
- Port: ${config.port}
|
|
|
|
Enter new settings or cancel to keep current.`;
|
|
|
|
const host = prompt(currentSettings + '\n\nEnter SimpleGuardHome host (e.g. http://localhost):', config.host);
|
|
if (host === null) return;
|
|
|
|
const port = prompt('Enter SimpleGuardHome port (default: 8000):', config.port);
|
|
if (port === null) return;
|
|
|
|
const newPort = parseInt(port, 10) || DEFAULT_CONFIG.port;
|
|
|
|
// Test connection with new settings
|
|
const success = await testConnection(host, newPort);
|
|
if (success) {
|
|
GM_setValue('host', host);
|
|
GM_setValue('port', newPort);
|
|
createNotification('SimpleGuardHome configuration saved and connection tested successfully!');
|
|
} else {
|
|
const save = confirm('Could not connect to SimpleGuardHome with these settings. Save anyway?');
|
|
if (save) {
|
|
GM_setValue('host', host);
|
|
GM_setValue('port', newPort);
|
|
createNotification('Configuration saved, but connection test failed. Please verify your settings.');
|
|
}
|
|
}
|
|
}
|
|
|
|
// Register configuration menu commands
|
|
GM_registerMenuCommand('⚙️ Configure SimpleGuardHome', showConfigDialog);
|
|
GM_registerMenuCommand('🔄 Test Connection', async () => {
|
|
const config = getConfig();
|
|
const success = await testConnection(config.host, config.port);
|
|
createNotification(success ?
|
|
'Successfully connected to SimpleGuardHome!' :
|
|
'Could not connect to SimpleGuardHome. Please check your settings.');
|
|
});
|
|
|
|
// Store check results to avoid repeated API calls
|
|
const checkedDomains = new Map();
|
|
|
|
// Create notification container
|
|
function createNotification(message, showUnblockButton = false, domain = '') {
|
|
const notif = document.createElement('div');
|
|
notif.style.cssText = `
|
|
position: fixed;
|
|
bottom: 20px;
|
|
right: 20px;
|
|
background: #333;
|
|
color: white;
|
|
padding: 15px;
|
|
border-radius: 5px;
|
|
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
|
|
z-index: 9999;
|
|
font-family: sans-serif;
|
|
max-width: 300px;
|
|
`;
|
|
|
|
const messageDiv = document.createElement('div');
|
|
messageDiv.textContent = message;
|
|
notif.appendChild(messageDiv);
|
|
|
|
if (showUnblockButton) {
|
|
const button = document.createElement('button');
|
|
button.textContent = 'Unblock Domain';
|
|
button.style.cssText = `
|
|
margin-top: 10px;
|
|
padding: 5px 10px;
|
|
background: #007bff;
|
|
color: white;
|
|
border: none;
|
|
border-radius: 3px;
|
|
cursor: pointer;
|
|
`;
|
|
button.onclick = () => unblockDomain(domain);
|
|
notif.appendChild(button);
|
|
}
|
|
|
|
document.body.appendChild(notif);
|
|
setTimeout(() => notif.remove(), 10000); // Remove after 10 seconds
|
|
}
|
|
|
|
// Unblock a domain
|
|
async function unblockDomain(domain) {
|
|
const config = getConfig();
|
|
const apiUrl = `${config.host}:${config.port}/control/filtering/unblock_host?name=${encodeURIComponent(domain)}`;
|
|
|
|
GM_xmlhttpRequest({
|
|
method: 'GET',
|
|
url: apiUrl,
|
|
headers: {'Accept': 'application/json'},
|
|
onload: function(response) {
|
|
try {
|
|
const data = JSON.parse(response.responseText);
|
|
createNotification(data.message);
|
|
|
|
// Update cache if successful
|
|
if (data.message.includes('unblocked')) {
|
|
checkedDomains.set(domain, {
|
|
isBlocked: false,
|
|
timestamp: Date.now()
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('SimpleGuardHome unblock error:', error);
|
|
createNotification('Failed to unblock domain. Please try again.');
|
|
}
|
|
},
|
|
onerror: function(error) {
|
|
console.error('SimpleGuardHome API error:', error);
|
|
createNotification('Error connecting to SimpleGuardHome. Please check your settings.');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Check if domain is blocked by AdGuard Home
|
|
async function checkDomain(domain) {
|
|
// Skip if already checked recently
|
|
if (checkedDomains.has(domain)) {
|
|
const cachedResult = checkedDomains.get(domain);
|
|
if (Date.now() - cachedResult.timestamp < 3600000) { // Cache for 1 hour
|
|
return;
|
|
}
|
|
}
|
|
|
|
try {
|
|
const config = getConfig();
|
|
const apiUrl = `${config.host}:${config.port}/control/filtering/check_host?name=${encodeURIComponent(domain)}`;
|
|
|
|
GM_xmlhttpRequest({
|
|
method: 'GET',
|
|
url: apiUrl,
|
|
headers: {'Accept': 'application/json'},
|
|
onload: function(response) {
|
|
try {
|
|
const data = JSON.parse(response.responseText);
|
|
const isBlocked = data.reason.startsWith('Filtered');
|
|
|
|
// Cache the result
|
|
checkedDomains.set(domain, {
|
|
isBlocked,
|
|
timestamp: Date.now()
|
|
});
|
|
|
|
// If blocked, show notification with unblock option
|
|
if (isBlocked) {
|
|
createNotification(
|
|
`Domain ${domain} is blocked by AdGuard Home.`,
|
|
true,
|
|
domain
|
|
);
|
|
}
|
|
} catch (error) {
|
|
console.error('SimpleGuardHome parsing error:', error);
|
|
}
|
|
},
|
|
onerror: function(error) {
|
|
console.error('SimpleGuardHome API error:', error);
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error('SimpleGuardHome check error:', error);
|
|
}
|
|
}
|
|
|
|
// Intercept 404 responses using a fetch handler
|
|
const originalFetch = window.fetch;
|
|
window.fetch = async function(...args) {
|
|
try {
|
|
const response = await originalFetch.apply(this, args);
|
|
if (response.status === 404) {
|
|
const url = new URL(args[0].toString());
|
|
checkDomain(url.hostname);
|
|
}
|
|
return response;
|
|
} catch (error) {
|
|
console.error('SimpleGuardHome 404 Checker Error:', error);
|
|
return originalFetch.apply(this, args);
|
|
}
|
|
};
|
|
|
|
// Also intercept XHR for broader compatibility
|
|
const originalXHROpen = XMLHttpRequest.prototype.open;
|
|
XMLHttpRequest.prototype.open = function(method, url, ...rest) {
|
|
const originalOnReadyStateChange = this.onreadystatechange;
|
|
this.onreadystatechange = function() {
|
|
if (this.readyState === 4 && this.status === 404) {
|
|
const urlObj = new URL(url, window.location.href);
|
|
checkDomain(urlObj.hostname);
|
|
}
|
|
if (originalOnReadyStateChange) {
|
|
originalOnReadyStateChange.apply(this, arguments);
|
|
}
|
|
};
|
|
originalXHROpen.apply(this, [method, url, ...rest]);
|
|
};
|
|
})(); |