mirror of
https://github.com/smittix/intercept.git
synced 2026-04-24 06:40:00 -07:00
fix: browser hangs when navigating from WeFax to ADS-B dashboard
SSE EventSources and running processes were not cleaned up during dashboard navigation, saturating the browser's per-origin connection limit. Extract moduleDestroyMap into shared getModuleDestroyFn() and call destroyCurrentMode() before navigation. Also expand stopActiveLocalScansForNavigation() to cover wefax, weathersat, sstv, subghz, meshtastic, and gps modes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4039,6 +4039,43 @@
|
||||
'/satellite/dashboard',
|
||||
]);
|
||||
|
||||
// Shared module destroy map — closes SSE EventSources, timers, etc.
|
||||
// Used by both switchMode() and dashboard navigation cleanup.
|
||||
function getModuleDestroyFn(mode) {
|
||||
const moduleDestroyMap = {
|
||||
subghz: () => typeof SubGhz !== 'undefined' && SubGhz.destroy(),
|
||||
morse: () => typeof MorseMode !== 'undefined' && MorseMode.destroy?.(),
|
||||
spaceweather: () => typeof SpaceWeather !== 'undefined' && SpaceWeather.destroy?.(),
|
||||
weathersat: () => typeof WeatherSat !== 'undefined' && WeatherSat.suspend?.(),
|
||||
wefax: () => typeof WeFax !== 'undefined' && WeFax.destroy?.(),
|
||||
system: () => typeof SystemHealth !== 'undefined' && SystemHealth.destroy?.(),
|
||||
waterfall: () => typeof Waterfall !== 'undefined' && Waterfall.destroy?.(),
|
||||
gps: () => typeof GPS !== 'undefined' && GPS.destroy?.(),
|
||||
meshtastic: () => typeof Meshtastic !== 'undefined' && Meshtastic.destroy?.(),
|
||||
bluetooth: () => typeof BluetoothMode !== 'undefined' && BluetoothMode.destroy?.(),
|
||||
wifi: () => typeof WiFiMode !== 'undefined' && WiFiMode.destroy?.(),
|
||||
bt_locate: () => typeof BtLocate !== 'undefined' && BtLocate.destroy?.(),
|
||||
sstv: () => typeof SSTV !== 'undefined' && SSTV.destroy?.(),
|
||||
sstv_general: () => typeof SSTVGeneral !== 'undefined' && SSTVGeneral.destroy?.(),
|
||||
websdr: () => typeof WebSDR !== 'undefined' && WebSDR.destroy?.(),
|
||||
spystations: () => typeof SpyStations !== 'undefined' && SpyStations.destroy?.(),
|
||||
ais: () => { if (aisEventSource) { aisEventSource.close(); aisEventSource = null; } },
|
||||
acars: () => { if (acarsMainEventSource) { acarsMainEventSource.close(); acarsMainEventSource = null; } },
|
||||
vdl2: () => { if (vdl2MainEventSource) { vdl2MainEventSource.close(); vdl2MainEventSource = null; } },
|
||||
radiosonde: () => { if (radiosondeEventSource) { radiosondeEventSource.close(); radiosondeEventSource = null; } },
|
||||
meteor: () => typeof MeteorScatter !== 'undefined' && MeteorScatter.destroy?.(),
|
||||
};
|
||||
return moduleDestroyMap[mode] || null;
|
||||
}
|
||||
|
||||
function destroyCurrentMode() {
|
||||
if (!currentMode) return;
|
||||
const destroyFn = getModuleDestroyFn(currentMode);
|
||||
if (destroyFn) {
|
||||
try { destroyFn(); } catch(e) { console.warn(`[destroyCurrentMode] destroy ${currentMode} failed:`, e); }
|
||||
}
|
||||
}
|
||||
|
||||
function getActiveScanSummary() {
|
||||
return {
|
||||
pager: Boolean(isRunning),
|
||||
@@ -4100,6 +4137,29 @@
|
||||
if (typeof isTscmRunning !== 'undefined' && isTscmRunning && typeof stopTscmSweep === 'function') {
|
||||
Promise.resolve(stopTscmSweep()).catch(() => { });
|
||||
}
|
||||
|
||||
// Additional modes with server-side processes that need stopping
|
||||
if (typeof WeFax !== 'undefined' && typeof WeFax.stop === 'function') {
|
||||
Promise.resolve(WeFax.stop()).catch(() => { });
|
||||
}
|
||||
if (typeof WeatherSat !== 'undefined' && typeof WeatherSat.stop === 'function') {
|
||||
Promise.resolve(WeatherSat.stop()).catch(() => { });
|
||||
}
|
||||
if (typeof SSTV !== 'undefined' && typeof SSTV.stop === 'function') {
|
||||
Promise.resolve(SSTV.stop()).catch(() => { });
|
||||
}
|
||||
if (typeof SSTVGeneral !== 'undefined' && typeof SSTVGeneral.stop === 'function') {
|
||||
Promise.resolve(SSTVGeneral.stop()).catch(() => { });
|
||||
}
|
||||
if (typeof SubGhz !== 'undefined' && typeof SubGhz.stop === 'function') {
|
||||
Promise.resolve(SubGhz.stop()).catch(() => { });
|
||||
}
|
||||
if (typeof Meshtastic !== 'undefined' && typeof Meshtastic.stop === 'function') {
|
||||
Promise.resolve(Meshtastic.stop()).catch(() => { });
|
||||
}
|
||||
if (typeof GPS !== 'undefined' && typeof GPS.stop === 'function') {
|
||||
Promise.resolve(GPS.stop()).catch(() => { });
|
||||
}
|
||||
}
|
||||
|
||||
if (!window._dashboardNavigationStopHookBound) {
|
||||
@@ -4125,6 +4185,7 @@
|
||||
activeScans: getActiveScanSummary(),
|
||||
});
|
||||
}
|
||||
destroyCurrentMode();
|
||||
stopActiveLocalScansForNavigation();
|
||||
} catch (_) {
|
||||
// Ignore malformed hrefs.
|
||||
@@ -4239,31 +4300,11 @@
|
||||
await styleReadyPromise;
|
||||
|
||||
// Generic module cleanup — destroy previous mode's timers, SSE, etc.
|
||||
const moduleDestroyMap = {
|
||||
subghz: () => typeof SubGhz !== 'undefined' && SubGhz.destroy(),
|
||||
morse: () => typeof MorseMode !== 'undefined' && MorseMode.destroy?.(),
|
||||
spaceweather: () => typeof SpaceWeather !== 'undefined' && SpaceWeather.destroy?.(),
|
||||
weathersat: () => typeof WeatherSat !== 'undefined' && WeatherSat.suspend?.(),
|
||||
wefax: () => typeof WeFax !== 'undefined' && WeFax.destroy?.(),
|
||||
system: () => typeof SystemHealth !== 'undefined' && SystemHealth.destroy?.(),
|
||||
waterfall: () => typeof Waterfall !== 'undefined' && Waterfall.destroy?.(),
|
||||
gps: () => typeof GPS !== 'undefined' && GPS.destroy?.(),
|
||||
meshtastic: () => typeof Meshtastic !== 'undefined' && Meshtastic.destroy?.(),
|
||||
bluetooth: () => typeof BluetoothMode !== 'undefined' && BluetoothMode.destroy?.(),
|
||||
wifi: () => typeof WiFiMode !== 'undefined' && WiFiMode.destroy?.(),
|
||||
bt_locate: () => typeof BtLocate !== 'undefined' && BtLocate.destroy?.(),
|
||||
sstv: () => typeof SSTV !== 'undefined' && SSTV.destroy?.(),
|
||||
sstv_general: () => typeof SSTVGeneral !== 'undefined' && SSTVGeneral.destroy?.(),
|
||||
websdr: () => typeof WebSDR !== 'undefined' && WebSDR.destroy?.(),
|
||||
spystations: () => typeof SpyStations !== 'undefined' && SpyStations.destroy?.(),
|
||||
ais: () => { if (aisEventSource) { aisEventSource.close(); aisEventSource = null; } },
|
||||
acars: () => { if (acarsMainEventSource) { acarsMainEventSource.close(); acarsMainEventSource = null; } },
|
||||
vdl2: () => { if (vdl2MainEventSource) { vdl2MainEventSource.close(); vdl2MainEventSource = null; } },
|
||||
radiosonde: () => { if (radiosondeEventSource) { radiosondeEventSource.close(); radiosondeEventSource = null; } },
|
||||
meteor: () => typeof MeteorScatter !== 'undefined' && MeteorScatter.destroy?.(),
|
||||
};
|
||||
if (previousMode && previousMode !== mode && moduleDestroyMap[previousMode]) {
|
||||
try { moduleDestroyMap[previousMode](); } catch(e) { console.warn(`[switchMode] destroy ${previousMode} failed:`, e); }
|
||||
if (previousMode && previousMode !== mode) {
|
||||
const destroyFn = getModuleDestroyFn(previousMode);
|
||||
if (destroyFn) {
|
||||
try { destroyFn(); } catch(e) { console.warn(`[switchMode] destroy ${previousMode} failed:`, e); }
|
||||
}
|
||||
}
|
||||
|
||||
currentMode = mode;
|
||||
@@ -11687,6 +11728,7 @@
|
||||
tscmBaselineComparison = null;
|
||||
tscmIdentityClusters = [];
|
||||
tscmIdentitySummary = null;
|
||||
tscmHighInterestDevices = [];
|
||||
updateTscmDisplays();
|
||||
updateTscmThreatCounts();
|
||||
|
||||
@@ -12522,7 +12564,7 @@
|
||||
const exists = tscmWifiDevices.some(d => d.bssid === device.bssid);
|
||||
if (!exists) {
|
||||
tscmWifiDevices.push(device);
|
||||
updateTscmDisplays();
|
||||
debouncedUpdateTscmDisplays();
|
||||
updateTscmThreatCounts();
|
||||
// Add to findings panel if score >= 3 (review level or higher)
|
||||
if (device.score >= 3) {
|
||||
@@ -12551,7 +12593,7 @@
|
||||
if (!client.mac) client.mac = mac;
|
||||
client.is_client = true;
|
||||
tscmWifiClients.push(client);
|
||||
updateTscmDisplays();
|
||||
debouncedUpdateTscmDisplays();
|
||||
updateTscmThreatCounts();
|
||||
if (client.score >= 3) {
|
||||
addHighInterestDevice(client, 'wifi');
|
||||
@@ -12573,7 +12615,7 @@
|
||||
if (!exists) {
|
||||
if (!device.mac && mac) device.mac = mac;
|
||||
tscmBtDevices.push(device);
|
||||
updateTscmDisplays();
|
||||
debouncedUpdateTscmDisplays();
|
||||
updateTscmThreatCounts();
|
||||
// Add to threats panel if score >= 3 (review level or higher)
|
||||
if (device.score >= 3) {
|
||||
@@ -12607,7 +12649,7 @@
|
||||
: 3;
|
||||
if (!exists) {
|
||||
tscmRfSignals.push(signal);
|
||||
updateTscmDisplays();
|
||||
debouncedUpdateTscmDisplays();
|
||||
updateTscmThreatCounts();
|
||||
// Add to findings panel if score >= 3 (review level or higher)
|
||||
if (signal.score >= 3) {
|
||||
@@ -12649,6 +12691,18 @@
|
||||
// If there are signals, updateTscmDisplays() will handle the display
|
||||
}
|
||||
|
||||
// Debounced versions of expensive display updates to batch rapid-fire device additions
|
||||
let _tscmDisplayTimer = null;
|
||||
function debouncedUpdateTscmDisplays() {
|
||||
if (_tscmDisplayTimer) clearTimeout(_tscmDisplayTimer);
|
||||
_tscmDisplayTimer = setTimeout(() => { _tscmDisplayTimer = null; updateTscmDisplays(); }, 250);
|
||||
}
|
||||
let _tscmHighInterestTimer = null;
|
||||
function debouncedUpdateHighInterestPanel() {
|
||||
if (_tscmHighInterestTimer) clearTimeout(_tscmHighInterestTimer);
|
||||
_tscmHighInterestTimer = setTimeout(() => { _tscmHighInterestTimer = null; updateHighInterestPanel(); }, 250);
|
||||
}
|
||||
|
||||
// Track high-interest devices for the threats panel
|
||||
let tscmHighInterestDevices = [];
|
||||
function addHighInterestDevice(device, protocol) {
|
||||
@@ -12662,10 +12716,9 @@
|
||||
score: device.score,
|
||||
classification: device.classification,
|
||||
indicators: device.indicators || [],
|
||||
recommended_action: device.recommended_action,
|
||||
device: device
|
||||
recommended_action: device.recommended_action
|
||||
});
|
||||
updateHighInterestPanel();
|
||||
debouncedUpdateHighInterestPanel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12730,7 +12783,7 @@
|
||||
|
||||
// Update dashboard counts
|
||||
updateTscmThreatCounts();
|
||||
updateTscmDisplays();
|
||||
debouncedUpdateTscmDisplays();
|
||||
}
|
||||
|
||||
function readTscmFilters() {
|
||||
|
||||
Reference in New Issue
Block a user