Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions nmapui/handlers/connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ def on_connect(auth=None):
if auto_scan_config is not None:
emit_to_client(new_sid, "auto_scan_status", build_auto_scan_status_payload(auto_scan_config))

# #237: ignore zombie jobs whose owner tab has disconnected.
if owner_sid and owner_sid not in getattr(broadcaster, "_connected_sids", set()):
_complete = getattr(job_registry, "complete", None)
if callable(_complete):
_complete(owner_sid, active_job_type or "scan", status="completed")
broadcaster.end_job(owner_sid, job_type=active_job_type or "scan")
job = None
job = job_registry.get(owner_sid, active_job_type) if owner_sid else None
is_scanning = bool(job and job.get("status") in ("running", "cancelling"))
last_scan_target = source_state.get("last_scan_target") or ""
Expand Down Expand Up @@ -197,6 +204,14 @@ def on_get_initial_data():
)

job = job_registry.get(owner_sid, active_job_type) if owner_sid else None
# #237 follow-up: a job whose owner tab is gone is a zombie - it would
# otherwise disable scan buttons for every future page load.
if owner_sid and owner_sid not in getattr(broadcaster, "_connected_sids", set()):
job = None
_complete = getattr(job_registry, "complete", None)
if callable(_complete):
_complete(owner_sid, active_job_type or "scan", status="completed")
broadcaster.end_job(owner_sid, job_type=active_job_type or "scan")
is_scanning = bool(job and job.get("status") in ("running", "cancelling"))
last_scan_target = source_state.get("last_scan_target") or ""
network_key = source_state.get("network_key") or {}
Expand Down
8 changes: 8 additions & 0 deletions static/js/app_bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ async function bootstrapApp() {
}
// Request the legacy sync snapshot now that all listeners are wired (#230 bridge).
socket.emit('get_initial_data');
// Transport-level reconnect = new server session; closures hold the dead socket.
// Reload to rebuild everything against the live session (#237 follow-up).
if (socket.io) {
socket.io.on('reconnect', () => { location.reload(); });
}
if (typeof initializeScanButtonWiring === 'function') {
initializeScanButtonWiring(socket);
}
if (typeof initializeDiscoveryUI === 'function') {
initializeDiscoveryUI(socket);
}
Expand Down
2 changes: 1 addition & 1 deletion static/js/scan_runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ function updateHostRow(data) {
updateCVESummaries();
}

function initializeDiscoveryUI(socket) {
function initializeScanButtonWiring(socket) {
const startScanBtn = document.getElementById('start-scan-btn');
const completeScanBtn = document.getElementById('generate-report-btn');
const dragnetScanBtn = document.getElementById('dragnet-scan-btn');
Expand Down
7 changes: 7 additions & 0 deletions templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1650,6 +1650,13 @@ <h3 class="text-xl font-display italic text-emerald-900">Scan Complete!</h3>
}
// Request the legacy sync snapshot now that all listeners are wired (#230 bridge).
socket.emit('get_initial_data');
// A transport-level reconnect creates a new server session; module
// closures still hold the dead socket, so events would vanish. Reload
// to rebuild everything against the live session (#237 follow-up).
socket.io.on('reconnect', () => { location.reload(); });
if (typeof initializeScanButtonWiring === 'function') {
initializeScanButtonWiring(socket);
}
if (typeof initializeDiscoveryUI === 'function') {
initializeDiscoveryUI(socket);
}
Expand Down
Loading