diff --git a/firefox_addon_image.png b/firefox_addon_image.png new file mode 100644 index 0000000..2c920b1 Binary files /dev/null and b/firefox_addon_image.png differ diff --git a/js/background.js b/js/background.js new file mode 100644 index 0000000..b8a2962 --- /dev/null +++ b/js/background.js @@ -0,0 +1,123 @@ +const filterListURL = + "https://raw.githubusercontent.com/fmhy/FMHYFilterlist/main/filterlist-domains.txt"; + +let unsafeSites = []; +let potentiallyUnsafeSites = []; + +// Fetch the filter list +function fetchFilterList() { + console.log("Fetching filter list..."); + + fetch(filterListURL) + .then((response) => response.text()) + .then((text) => { + console.log("Filter list fetched successfully!"); + const lines = text.split("\n"); + let isPotentiallyUnsafeSection = false; // Track whether we're in the "potentially unsafe" section + + lines.forEach((line) => { + // Ignore comments and blank lines + if (line.startsWith("#")) { + if (line.includes("not recommended/potentially unsafe")) { + isPotentiallyUnsafeSection = true; + } + } else if (line.trim()) { + const domain = line.trim(); // Trim whitespace + if (isPotentiallyUnsafeSection) { + potentiallyUnsafeSites.push(domain); // Add to potentially unsafe sites + } else { + unsafeSites.push(domain); // Add to unsafe sites + } + } + }); + console.log("Parsed Unsafe Sites:", unsafeSites); // Check if unsafe sites are populated + console.log("Parsed Potentially Unsafe Sites:", potentiallyUnsafeSites); // Check potentially unsafe sites + }) + .catch((error) => console.error("Error fetching filter list:", error)); +} + +// Update the toolbar icon based on the site's status +function updateIcon(status, tabId) { + let iconPath = "res/ext_icon_144.png"; // Default extension icon for unknown sites + + if (status === "safe") { + iconPath = "res/icons/safe.png"; // Icon for safe sites + } else if (status === "unsafe") { + iconPath = "res/icons/unsafe.png"; // Icon for unsafe sites + } else if (status === "potentially_unsafe") { + iconPath = "res/icons/potentially_unsafe.png"; // Icon for potentially unsafe sites + } + + browser.browserAction.setIcon({ + path: iconPath, + tabId: tabId, + }); +} + +// Check the site status for a given tab and URL +function checkSiteAndUpdateIcon(tabId, url) { + if (!url) return; + + const currentUrl = new URL(url).hostname.replace("www.", ""); + console.log("Checking site status for toolbar icon:", currentUrl); + + // Check if the site is unsafe or potentially unsafe + let isUnsafe = unsafeSites.some((site) => currentUrl.includes(site)); + let isPotentiallyUnsafe = potentiallyUnsafeSites.some((site) => + currentUrl.includes(site) + ); + + if (isUnsafe) { + console.log("Updating toolbar icon to unsafe for:", currentUrl); + updateIcon("unsafe", tabId); // Update the toolbar icon to unsafe + } else if (isPotentiallyUnsafe) { + console.log("Updating toolbar icon to potentially unsafe for:", currentUrl); + updateIcon("potentially_unsafe", tabId); // Update the toolbar icon to potentially unsafe + } else { + console.log("No data for this site:", currentUrl); + updateIcon("default", tabId); // Use default extension icon for unknown sites + } +} + +// Listen for messages from the popup +browser.runtime.onMessage.addListener((message, sender, sendResponse) => { + if (message.action === "checkSiteStatus") { + const currentUrl = message.url; + console.log("Checking site status for popup:", currentUrl); + + // Check if the site is unsafe or potentially unsafe + let isUnsafe = unsafeSites.some((site) => currentUrl.includes(site)); + let isPotentiallyUnsafe = potentiallyUnsafeSites.some((site) => + currentUrl.includes(site) + ); + + if (isUnsafe) { + sendResponse({ status: "unsafe", url: currentUrl }); + } else if (isPotentiallyUnsafe) { + sendResponse({ status: "potentially_unsafe", url: currentUrl }); + } else { + console.log("No data for this site:", currentUrl); + sendResponse({ status: "no_data", url: currentUrl }); // Return no data status + } + } + return true; // Indicates we will respond asynchronously +}); + +// Listen for when a tab is updated (e.g., new URL loaded) +browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { + if (changeInfo.status === "complete" && tab.url) { + checkSiteAndUpdateIcon(tabId, tab.url); + } +}); + +// Listen for when a tab is activated (e.g., tab switched) +browser.tabs.onActivated.addListener((activeInfo) => { + browser.tabs.get(activeInfo.tabId, (tab) => { + if (tab.url) { + checkSiteAndUpdateIcon(tab.id, tab.url); + } + }); +}); + +// Fetch the filter list when the extension is loaded +fetchFilterList(); diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..1cf48ac --- /dev/null +++ b/manifest.json @@ -0,0 +1,26 @@ +{ + "manifest_version": 2, + "name": "FMHY SafeGuard", + "version": "1.0.0", + "icons": { + "128": "res/ext_icon_144.png" + }, + "browser_action": { + "default_icon": { + "128": "res/ext_icon_144.png" + }, + "default_popup": "pub/index.html" + }, + "permissions": [ + "activeTab", + "", + "webRequest", + "webRequestBlocking", + "storage", + "notifications" + ], + "background": { + "scripts": ["js/background.js"], + "persistent": true + } +} diff --git a/pub/index.html b/pub/index.html new file mode 100644 index 0000000..4d9bdc9 --- /dev/null +++ b/pub/index.html @@ -0,0 +1,93 @@ + + + + + + FMHY SafeGuard + + + +
+

FMHY SafeGuard

+
+ +
+ + Status Icon + +

Checking site status...

+
+ + +

+ + + + + + diff --git a/pub/index.js b/pub/index.js new file mode 100644 index 0000000..be8879f --- /dev/null +++ b/pub/index.js @@ -0,0 +1,45 @@ +document.addEventListener('DOMContentLoaded', function() { + console.log("Popup loaded, attempting to get site status..."); + + const statusIcon = document.getElementById('status-icon'); + const statusMessage = document.getElementById('status-message'); + const errorMessage = document.getElementById('error-message'); + + // Query the active tab to get its URL + browser.tabs.query({active: true, currentWindow: true}, function(tabs) { + if (tabs.length === 0) { + console.error("No active tab found."); + statusMessage.textContent = "Error: No active tab found."; + return; + } + + const currentUrl = new URL(tabs[0].url).hostname.replace('www.', ''); + console.log("Sending message to background to check site status for:", currentUrl); + + // Send a message to the background script to check the site's status + browser.runtime.sendMessage({action: "checkSiteStatus", url: tabs[0].url}, function(response) { + if (!response) { + console.error("No response from background script."); + statusMessage.textContent = "Error: Could not retrieve site status."; + return; + } + + if (response.status === "unsafe") { + console.log("Popup: Site is unsafe:", currentUrl); + // Update popup for unsafe site + statusIcon.src = '../res/icons/unsafe.png'; // Update icon to unsafe + statusMessage.textContent = `${currentUrl} is unsafe. Be cautious!`; // Update message + } else if (response.status === "potentially_unsafe") { + console.log("Popup: Site is potentially unsafe:", currentUrl); + // Update popup for potentially unsafe site + statusIcon.src = '../res/icons/potentially_unsafe.png'; // Update icon to potentially unsafe + statusMessage.textContent = `${currentUrl} is potentially unsafe. Be cautious!`; // Update message + } else if (response.status === "no_data") { + console.log("Popup: No data for this site:", currentUrl); + // Update popup for no data + statusIcon.src = '../res/ext_icon_144.png'; // Default extension icon + statusMessage.textContent = "There is no data for this site yet."; // Update message for no data + } + }); + }); +}); diff --git a/res/ext_icon_144.png b/res/ext_icon_144.png new file mode 100644 index 0000000..f0d4f74 Binary files /dev/null and b/res/ext_icon_144.png differ diff --git a/res/icons/potentially_unsafe.png b/res/icons/potentially_unsafe.png new file mode 100644 index 0000000..8caa947 Binary files /dev/null and b/res/icons/potentially_unsafe.png differ diff --git a/res/icons/safe.png b/res/icons/safe.png new file mode 100644 index 0000000..9c51a93 Binary files /dev/null and b/res/icons/safe.png differ diff --git a/res/icons/unsafe.png b/res/icons/unsafe.png new file mode 100644 index 0000000..dacf003 Binary files /dev/null and b/res/icons/unsafe.png differ