mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-07-11 06:43:49 +02:00
144 lines
3.8 KiB
JavaScript
144 lines
3.8 KiB
JavaScript
/* global chrome, CSAI_LIMITS, shouldCaptureEntry */
|
|
|
|
importScripts('../lib/constants.js', '../lib/capture.js');
|
|
|
|
/** Background hub: per-tab capture queue + panel subscriptions. */
|
|
|
|
const capturesByTab = new Map();
|
|
const portsByTab = new Map();
|
|
const filterApiByTab = new Map();
|
|
let captureEnabled = true;
|
|
|
|
function getCaptures(tabId) {
|
|
if (!capturesByTab.has(tabId)) capturesByTab.set(tabId, []);
|
|
return capturesByTab.get(tabId);
|
|
}
|
|
|
|
function trimCaptures(list) {
|
|
if (list.length > CSAI_LIMITS.MAX_CAPTURED) {
|
|
list.length = CSAI_LIMITS.MAX_CAPTURED;
|
|
}
|
|
}
|
|
|
|
function broadcastTab(tabId, message) {
|
|
const ports = portsByTab.get(tabId);
|
|
if (!ports) return;
|
|
for (const port of ports) {
|
|
try {
|
|
port.postMessage(message);
|
|
} catch (_) {
|
|
ports.delete(port);
|
|
}
|
|
}
|
|
}
|
|
|
|
function cleanupOldTabs(activeTabId) {
|
|
if (capturesByTab.size <= CSAI_LIMITS.MAX_TAB_CAPTURES) return;
|
|
for (const tabId of capturesByTab.keys()) {
|
|
if (tabId !== activeTabId) {
|
|
capturesByTab.delete(tabId);
|
|
portsByTab.delete(tabId);
|
|
filterApiByTab.delete(tabId);
|
|
}
|
|
if (capturesByTab.size <= CSAI_LIMITS.MAX_TAB_CAPTURES) break;
|
|
}
|
|
}
|
|
|
|
chrome.runtime.onConnect.addListener((port) => {
|
|
if (port.name !== 'cyberstrike-panel') return;
|
|
|
|
port.onDisconnect.addListener(() => {
|
|
for (const [tabId, set] of portsByTab.entries()) {
|
|
set.delete(port);
|
|
if (set.size === 0) portsByTab.delete(tabId);
|
|
}
|
|
});
|
|
|
|
port.onMessage.addListener((msg) => {
|
|
if (!msg || msg.type !== 'subscribe') return;
|
|
const tabId = msg.tabId;
|
|
if (tabId == null) return;
|
|
|
|
if (!portsByTab.has(tabId)) portsByTab.set(tabId, new Set());
|
|
portsByTab.get(tabId).add(port);
|
|
|
|
if (typeof msg.filterApiOnly === 'boolean') {
|
|
filterApiByTab.set(tabId, msg.filterApiOnly);
|
|
}
|
|
|
|
port.postMessage({ type: 'list', entries: getCaptures(tabId) });
|
|
cleanupOldTabs(tabId);
|
|
});
|
|
});
|
|
|
|
chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
|
|
if (!msg || !msg.type) return false;
|
|
|
|
if (msg.type === 'capture-entry') {
|
|
const tabId = msg.tabId;
|
|
if (tabId == null) return false;
|
|
if (!captureEnabled) {
|
|
sendResponse({ ok: true, skipped: true });
|
|
return false;
|
|
}
|
|
const filterApi = filterApiByTab.has(tabId) ? filterApiByTab.get(tabId) : true;
|
|
const entry = msg.entry;
|
|
if (!shouldCaptureEntry(entry, filterApi)) {
|
|
sendResponse({ ok: true, skipped: true });
|
|
return false;
|
|
}
|
|
const list = getCaptures(tabId);
|
|
list.unshift(entry);
|
|
trimCaptures(list);
|
|
broadcastTab(tabId, { type: 'entry', entry });
|
|
sendResponse({ ok: true });
|
|
return false;
|
|
}
|
|
|
|
if (msg.type === 'clear-captures') {
|
|
const tabId = msg.tabId;
|
|
if (tabId != null) {
|
|
capturesByTab.set(tabId, []);
|
|
broadcastTab(tabId, { type: 'list', entries: [] });
|
|
}
|
|
sendResponse({ ok: true });
|
|
return false;
|
|
}
|
|
|
|
if (msg.type === 'set-filter-api') {
|
|
const tabId = msg.tabId;
|
|
if (tabId != null && typeof msg.filterApiOnly === 'boolean') {
|
|
filterApiByTab.set(tabId, msg.filterApiOnly);
|
|
}
|
|
sendResponse({ ok: true });
|
|
return false;
|
|
}
|
|
|
|
if (msg.type === 'set-capture-enabled') {
|
|
if (typeof msg.enabled === 'boolean') {
|
|
captureEnabled = msg.enabled;
|
|
}
|
|
sendResponse({ ok: true });
|
|
return false;
|
|
}
|
|
|
|
if (msg.type === 'get-latest-api') {
|
|
const tabId = msg.tabId;
|
|
const list = getCaptures(tabId);
|
|
const latest = list.find((e) => {
|
|
const rt = (e.resourceType || '').toLowerCase();
|
|
return rt === 'xhr' || rt === 'fetch';
|
|
});
|
|
sendResponse({ entry: latest || null });
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
});
|
|
|
|
chrome.runtime.onInstalled.addListener(() => {
|
|
if (chrome.contextMenus && chrome.contextMenus.removeAll) {
|
|
chrome.contextMenus.removeAll();
|
|
}
|
|
});
|