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',
|
'/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() {
|
function getActiveScanSummary() {
|
||||||
return {
|
return {
|
||||||
pager: Boolean(isRunning),
|
pager: Boolean(isRunning),
|
||||||
@@ -4100,6 +4137,29 @@
|
|||||||
if (typeof isTscmRunning !== 'undefined' && isTscmRunning && typeof stopTscmSweep === 'function') {
|
if (typeof isTscmRunning !== 'undefined' && isTscmRunning && typeof stopTscmSweep === 'function') {
|
||||||
Promise.resolve(stopTscmSweep()).catch(() => { });
|
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) {
|
if (!window._dashboardNavigationStopHookBound) {
|
||||||
@@ -4125,6 +4185,7 @@
|
|||||||
activeScans: getActiveScanSummary(),
|
activeScans: getActiveScanSummary(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
destroyCurrentMode();
|
||||||
stopActiveLocalScansForNavigation();
|
stopActiveLocalScansForNavigation();
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
// Ignore malformed hrefs.
|
// Ignore malformed hrefs.
|
||||||
@@ -4239,31 +4300,11 @@
|
|||||||
await styleReadyPromise;
|
await styleReadyPromise;
|
||||||
|
|
||||||
// Generic module cleanup — destroy previous mode's timers, SSE, etc.
|
// Generic module cleanup — destroy previous mode's timers, SSE, etc.
|
||||||
const moduleDestroyMap = {
|
if (previousMode && previousMode !== mode) {
|
||||||
subghz: () => typeof SubGhz !== 'undefined' && SubGhz.destroy(),
|
const destroyFn = getModuleDestroyFn(previousMode);
|
||||||
morse: () => typeof MorseMode !== 'undefined' && MorseMode.destroy?.(),
|
if (destroyFn) {
|
||||||
spaceweather: () => typeof SpaceWeather !== 'undefined' && SpaceWeather.destroy?.(),
|
try { destroyFn(); } catch(e) { console.warn(`[switchMode] destroy ${previousMode} failed:`, e); }
|
||||||
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); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
currentMode = mode;
|
currentMode = mode;
|
||||||
@@ -11687,6 +11728,7 @@
|
|||||||
tscmBaselineComparison = null;
|
tscmBaselineComparison = null;
|
||||||
tscmIdentityClusters = [];
|
tscmIdentityClusters = [];
|
||||||
tscmIdentitySummary = null;
|
tscmIdentitySummary = null;
|
||||||
|
tscmHighInterestDevices = [];
|
||||||
updateTscmDisplays();
|
updateTscmDisplays();
|
||||||
updateTscmThreatCounts();
|
updateTscmThreatCounts();
|
||||||
|
|
||||||
@@ -12522,7 +12564,7 @@
|
|||||||
const exists = tscmWifiDevices.some(d => d.bssid === device.bssid);
|
const exists = tscmWifiDevices.some(d => d.bssid === device.bssid);
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
tscmWifiDevices.push(device);
|
tscmWifiDevices.push(device);
|
||||||
updateTscmDisplays();
|
debouncedUpdateTscmDisplays();
|
||||||
updateTscmThreatCounts();
|
updateTscmThreatCounts();
|
||||||
// Add to findings panel if score >= 3 (review level or higher)
|
// Add to findings panel if score >= 3 (review level or higher)
|
||||||
if (device.score >= 3) {
|
if (device.score >= 3) {
|
||||||
@@ -12551,7 +12593,7 @@
|
|||||||
if (!client.mac) client.mac = mac;
|
if (!client.mac) client.mac = mac;
|
||||||
client.is_client = true;
|
client.is_client = true;
|
||||||
tscmWifiClients.push(client);
|
tscmWifiClients.push(client);
|
||||||
updateTscmDisplays();
|
debouncedUpdateTscmDisplays();
|
||||||
updateTscmThreatCounts();
|
updateTscmThreatCounts();
|
||||||
if (client.score >= 3) {
|
if (client.score >= 3) {
|
||||||
addHighInterestDevice(client, 'wifi');
|
addHighInterestDevice(client, 'wifi');
|
||||||
@@ -12573,7 +12615,7 @@
|
|||||||
if (!exists) {
|
if (!exists) {
|
||||||
if (!device.mac && mac) device.mac = mac;
|
if (!device.mac && mac) device.mac = mac;
|
||||||
tscmBtDevices.push(device);
|
tscmBtDevices.push(device);
|
||||||
updateTscmDisplays();
|
debouncedUpdateTscmDisplays();
|
||||||
updateTscmThreatCounts();
|
updateTscmThreatCounts();
|
||||||
// Add to threats panel if score >= 3 (review level or higher)
|
// Add to threats panel if score >= 3 (review level or higher)
|
||||||
if (device.score >= 3) {
|
if (device.score >= 3) {
|
||||||
@@ -12607,7 +12649,7 @@
|
|||||||
: 3;
|
: 3;
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
tscmRfSignals.push(signal);
|
tscmRfSignals.push(signal);
|
||||||
updateTscmDisplays();
|
debouncedUpdateTscmDisplays();
|
||||||
updateTscmThreatCounts();
|
updateTscmThreatCounts();
|
||||||
// Add to findings panel if score >= 3 (review level or higher)
|
// Add to findings panel if score >= 3 (review level or higher)
|
||||||
if (signal.score >= 3) {
|
if (signal.score >= 3) {
|
||||||
@@ -12649,6 +12691,18 @@
|
|||||||
// If there are signals, updateTscmDisplays() will handle the display
|
// 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
|
// Track high-interest devices for the threats panel
|
||||||
let tscmHighInterestDevices = [];
|
let tscmHighInterestDevices = [];
|
||||||
function addHighInterestDevice(device, protocol) {
|
function addHighInterestDevice(device, protocol) {
|
||||||
@@ -12662,10 +12716,9 @@
|
|||||||
score: device.score,
|
score: device.score,
|
||||||
classification: device.classification,
|
classification: device.classification,
|
||||||
indicators: device.indicators || [],
|
indicators: device.indicators || [],
|
||||||
recommended_action: device.recommended_action,
|
recommended_action: device.recommended_action
|
||||||
device: device
|
|
||||||
});
|
});
|
||||||
updateHighInterestPanel();
|
debouncedUpdateHighInterestPanel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12730,7 +12783,7 @@
|
|||||||
|
|
||||||
// Update dashboard counts
|
// Update dashboard counts
|
||||||
updateTscmThreatCounts();
|
updateTscmThreatCounts();
|
||||||
updateTscmDisplays();
|
debouncedUpdateTscmDisplays();
|
||||||
}
|
}
|
||||||
|
|
||||||
function readTscmFilters() {
|
function readTscmFilters() {
|
||||||
|
|||||||
Reference in New Issue
Block a user