moved files for structure

This commit is contained in:
2025-11-13 20:12:28 +01:00
parent 73a12148e8
commit 1ff1ececb4
10 changed files with 378 additions and 1 deletions
+50
View File
@@ -0,0 +1,50 @@
{
"manifest_version": 2,
"name": "File-Leak",
"version": "1.0",
"description": "Find hidden files on websites you visit which are not supposed to be there",
"homepage_url": "https://agres.online",
"icons": {
"32": "static/icons/icon32.png",
"48": "static/icons/icon48.png"
},
"permissions": [
"webNavigation",
"storage",
"<all_urls>",
"http://*/*",
"https://*/*"
],
"browser_action": {
"default_icon": "static/icons/icon48.png",
"default_title": "File-leak",
"default_popup": "popup/html/main.html"
},
"background": {
"scripts": ["popup/js/background.js"],
"persistent": false
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["popup/js/visual.js"]
}
],
"browser_specific_settings": {
"gecko": {
"id": "dominik@agres.online",
"strict_min_version": "120.0",
"data_collection_permissions": {
"collects_diagnostic_data": false,
"collects_usage_data": false,
"required": ["none"]
}
}
}
}
+71
View File
@@ -0,0 +1,71 @@
body {
margin: 0;
padding: 0;
font-family: sans-serif;
background: #1e2430;
color: #e4e7ec;
}
#popup-content {
padding: 12px;
width: 260px;
}
h1 {
margin-top: 0;
font-size: 18px;
color: #f0f3f8;
}
label, button {
display: block;
margin: 8px 0;
}
button {
padding: 6px 10px;
background: #2d3441;
border: 1px solid #3a4253;
color: #e4e7ec;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #3a4253;
}
#entry-box {
margin-top: 10px;
background: #252b36;
border: 1px solid #333b49;
border-radius: 4px;
max-height: 250px;
overflow-y: auto;
padding: 6px;
}
.entry {
display: grid;
grid-template-columns: 1.2fr 1fr auto auto;
align-items: center;
gap: 6px;
padding: 6px;
background: #2b3240;
border-radius: 3px;
margin-bottom: 6px;
font-size: 12px;
}
.entry span {
font-size: 12px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-width: 0;
}
.entry button {
padding: 4px 6px;
font-size: 12px;
}
+32
View File
@@ -0,0 +1,32 @@
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="../css/styles.css" />
</head>
<body>
<div id="popup-content">
<h1> Hidden Files </h1>
<label>
<input type="checkbox" id="listenerToggle"> Enable scanning
</label>
<button id="runOnceBtn">Scan this site</button>
<div id="entry-box">
<div id="entry-list"></div>
</div>
</div>
<script src="../js/visual.js"></script>
</body>
</html>
+129
View File
@@ -0,0 +1,129 @@
// function to scan the url the tab is on for hidden files
async function onTabUpdate(tabId, changeInfo, tab) {
if (changeInfo.status !== "complete") return;
const url = new URL(tab.url);
const hostname = url.hostname;
const stored = await browser.storage.local.get("entries");
const existingEntries = stored.entries || [];
const alreadyDone = existingEntries.some(e => e.domainField === hostname);
if (alreadyDone) return;
async function tryFetch(pathname) {
const target = url.origin + pathname;
let response;
try {
response = await fetch(target, { redirect: "manual" });
} catch {
return null;
}
return response.status === 200 ? target : null;
}
const results = {
env: await tryFetch("/.env"),
git: await tryFetch("/.git"),
dsstore: await tryFetch("/.DS_Store"),
config: await tryFetch("/.config"),
svn: await tryFetch("/.svn"),
npm: await tryFetch("/.npm"),
hg: await tryFetch("/.hg"),
docker: await tryFetch("/.docker"),
};
const newEntries = [...existingEntries];
for (const [key, foundPath] of Object.entries(results)) {
if (!foundPath) continue;
const entry = {
domainField: hostname,
pathField: foundPath,
type: key
};
newEntries.push(entry);
}
await browser.storage.local.set({ entries: newEntries });
}
// Enable, Idsable automatic listener and the message listener for it
function enableListener() {
if (!browser.tabs.onUpdated.hasListener(onTabUpdate)) {
browser.tabs.onUpdated.addListener(onTabUpdate);
}
}
function disableListener() {
if (browser.tabs.onUpdated.hasListener(onTabUpdate)) {
browser.tabs.onUpdated.removeListener(onTabUpdate);
}
}
browser.runtime.onMessage.addListener((msg) => {
if (msg.type === "toggleListener") {
if (msg.enabled) enableListener();
else disableListener();
}
});
// Singe run, can be merged with onTabUpdate function
async function runSingleScan() {
const tabs = await browser.tabs.query({ active: true, currentWindow: true });
if (!tabs.length) return;
const tab = tabs[0];
const url = new URL(tab.url);
const hostname = url.hostname;
async function tryFetch(path) {
const target = url.origin + path;
let response;
try {
response = await fetch(target, { redirect: "manual" });
} catch {
return null;
}
return response.status === 200 ? target : null;
}
const results = {
env: await tryFetch("/.env"),
git: await tryFetch("/.git"),
dsstore: await tryFetch("/.DS_Store"),
config: await tryFetch("/.config"),
svn: await tryFetch("/.svn"),
npm: await tryFetch("/.npm"),
hg: await tryFetch("/.hg"),
docker: await tryFetch("/.docker"),
};
const stored = await browser.storage.local.get("entries");
const entries = stored.entries || [];
for (const [key, foundPath] of Object.entries(results)) {
if (!foundPath) continue;
entries.push({
domainField: hostname,
pathField: foundPath,
type: key
});
}
await browser.storage.local.set({ entries });
}
browser.runtime.onMessage.addListener((msg) => {
if (msg.type === "runOnce") {
runSingleScan();
}
});
+89
View File
@@ -0,0 +1,89 @@
// Handling of adding saving and loading list entries
function addEntry(domain, path) {
const list = document.getElementById("entry-list");
const entry = document.createElement("div");
entry.className = "entry";
const domainField = document.createElement("span");
domainField.textContent = domain;
const pathField = document.createElement("span");
pathField.textContent = path;
const deleteButton = document.createElement("button");
deleteButton.textContent = "Delete";
deleteButton.addEventListener("click", function () {
entry.remove();
saveAllEntries();
})
const openButton = document.createElement("button");
openButton.textContent = "Open";
openButton.addEventListener("click", function () {
const url = pathField.textContent;
if (url) {
window.open(url, "_blank");
}
});
entry.appendChild(domainField);
entry.appendChild(pathField);
entry.appendChild(deleteButton);
entry.appendChild(openButton);
list.appendChild(entry);
saveAllEntries();
}
function saveAllEntries() {
const entries = [];
document.querySelectorAll(".entry").forEach(entry => {
const spans = entry.querySelectorAll("span");
entries.push({
domainField: spans[0].textContent,
pathField: spans[1].textContent
});
});
browser.storage.local.set({ entries });
}
async function loadEntries() {
const stored = await browser.storage.local.get("entries");
if (!stored.entries) return;
for (const data of stored.entries) {
addEntry(data.domainField, data.pathField);
}
}
// Load entries when popup starts
document.addEventListener("DOMContentLoaded", () => {
loadEntries();
});
// Handle persistance for toggle button
const toggle = document.getElementById("listenerToggle");
browser.storage.local.get("listenerEnabled").then(({ listenerEnabled }) => {
toggle.checked = !!listenerEnabled;
});
toggle.addEventListener("change", (e) => {
const enabled = e.target.checked;
browser.storage.local.set({ listenerEnabled: enabled });
browser.runtime.sendMessage({ type: "toggleListener", enabled });
});
// Run one scan on button press
document.getElementById("runOnceBtn").addEventListener("click", () => {
browser.runtime.sendMessage({ type: "runOnce" });
});
Binary file not shown.

After

Width:  |  Height:  |  Size: 662 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 869 B