From 719845b1c863c7035e970054f4519a37ebac7509 Mon Sep 17 00:00:00 2001 From: pacnpal <183241239+pacnpal@users.noreply.github.com> Date: Wed, 29 Jan 2025 16:17:25 -0500 Subject: [PATCH] docs(README.md): update error handling section and improve API endpoint descriptions 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 --- README.md | 32 ++-- userscript/README.md | 38 +++-- .../simpleguardhome-404-checker.user.js | 157 ++++++++++++++++-- 3 files changed, 182 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 07a0f3f..f0660b0 100644 --- a/README.md +++ b/README.md @@ -183,7 +183,6 @@ Documentation is available at: - ReDoc: `http://localhost:8000/api/redoc` - Alternative documentation UI - OpenAPI Schema: `http://localhost:8000/api/openapi.json` - Raw OpenAPI specification -### API Endpoints ### API Endpoints All endpoints follow the official AdGuard Home API specification: @@ -251,24 +250,23 @@ simpleguardhome/ ## Error Handling -The application implements comprehensive error handling for all endpoints: +The application implements comprehensive error handling according to endpoint: -- 400 Bad Request - - Invalid domain format - - Missing required parameters - - Invalid whitelist rule format -- 500 Internal Server Error - - Failed to add domain to whitelist - - Other internal processing errors -- 502 Bad Gateway - - AdGuard Home API errors - - Invalid API responses -- 503 Service Unavailable - - AdGuard Home service unreachable - - Connection timeouts - - Network errors +GET /control/filtering/check_host: +- 400: Invalid domain format or missing name parameter +- 503: AdGuard Home service unavailable -All errors return an ErrorResponse object with a descriptive message. +GET /control/filtering/unblock_host: +- 400: Invalid domain format or missing name parameter +- 500: Failed to unblock domain +- 503: AdGuard Home service unavailable + +POST /control/filtering/set_rules: +- 400: Invalid rule format or missing rules +- 500: Failed to update rules +- 503: AdGuard Home service unavailable + +All endpoints return an ErrorResponse model with a descriptive message. ## Response Models diff --git a/userscript/README.md b/userscript/README.md index ef191b9..179551e 100644 --- a/userscript/README.md +++ b/userscript/README.md @@ -6,7 +6,8 @@ A Tampermonkey userscript that detects 404 responses while browsing and automati - Automatically detects 404 responses from both fetch and XMLHttpRequest calls - Checks failed domains against your AdGuard Home instance -- Shows notifications for blocked domains with unblock option +- Shows notifications for blocked domains with one-click unblock button +- Directly unblocks domains using SimpleGuardHome API - Configurable AdGuard Home instance settings - Caches results to minimize API calls - Error handling with configuration shortcuts @@ -20,14 +21,28 @@ A Tampermonkey userscript that detects 404 responses while browsing and automati ## Configuration +### Initial Setup 1. Click on the Tampermonkey icon in your browser -2. Select "Configure SimpleGuardHome Instance" under the script's menu -3. Enter your AdGuard Home host (e.g., `http://localhost`) -4. Enter your AdGuard Home port (default: 3000) +2. Select "⚙️ Configure SimpleGuardHome" under the script's menu +3. Review your current settings (if any) +4. Enter new host and port settings +5. Connection test will be performed automatically + - Success: Settings are saved immediately + - Failure: Option to save anyway or retry + +### Menu Options +- "⚙️ Configure SimpleGuardHome" - Open configuration dialog +- "🔄 Test Connection" - Test current settings ### Default Settings - Host: `http://localhost` -- Port: `3000` +- Port: `8000` (SimpleGuardHome default port) + +### Connection Testing +- Automatic testing when saving new settings +- Manual testing available through menu +- Clear notifications of test results +- Option to save settings even if test fails ## How It Works @@ -35,8 +50,10 @@ A Tampermonkey userscript that detects 404 responses while browsing and automati 2. When a 404 response is detected: - Extracts the domain from the failed URL - Checks if the domain is blocked by AdGuard Home - - Shows a notification if the domain is blocked - - Provides a quick "Unblock" button to open SimpleGuardHome + - Shows a notification with status if domain is blocked + - Provides a one-click "Unblock Domain" button + - Directly unblocks domain when button is clicked + - Shows success/error notification after unblock attempt 3. Error handling: - Connection issues show a notification with configuration options @@ -54,10 +71,11 @@ A Tampermonkey userscript that detects 404 responses while browsing and automati ### Cache System - Domain check results are cached for 1 hour - Cache includes: - - Block status - - Blocking reason - - Applied rules + - Block status (true/false) - Timestamp +- Cache is updated when: + - Domain is checked (status: "not blocked", "blocked") + - Domain is unblocked (status: "already unblocked", "has been unblocked") ### Error Handling - Connection failures diff --git a/userscript/simpleguardhome-404-checker.user.js b/userscript/simpleguardhome-404-checker.user.js index 741bfb0..8cdc425 100644 --- a/userscript/simpleguardhome-404-checker.user.js +++ b/userscript/simpleguardhome-404-checker.user.js @@ -19,7 +19,7 @@ // Default configuration const DEFAULT_CONFIG = { host: 'http://localhost', - port: 8000 + port: 8000 // SimpleGuardHome runs on port 8000 by default }; // Get current configuration @@ -30,27 +30,144 @@ }; } - // Show configuration dialog - function showConfigDialog() { - const config = getConfig(); - const host = prompt('Enter SimpleGuardHome host (e.g. http://localhost):', config.host); - if (host === null) return; - - const port = prompt('Enter SimpleGuardHome port:', config.port); - if (port === null) return; - - GM_setValue('host', host); - GM_setValue('port', parseInt(port, 10) || DEFAULT_CONFIG.port); - - alert('Configuration saved! The new settings will be used for future checks.'); + // 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; + } } - // Register configuration menu command - GM_registerMenuCommand('Configure SimpleGuardHome Instance', showConfigDialog); + // 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 @@ -80,9 +197,13 @@ timestamp: Date.now() }); - // If blocked, redirect to SimpleGuardHome interface + // If blocked, show notification with unblock option if (isBlocked) { - window.location.href = apiUrl; + createNotification( + `Domain ${domain} is blocked by AdGuard Home.`, + true, + domain + ); } } catch (error) { console.error('SimpleGuardHome parsing error:', error);