mirror of
https://github.com/smittix/intercept.git
synced 2026-07-11 02:58:12 -07:00
fix(drone): conform to established SPA patterns throughout
- Device population: move refreshDroneDevices() inline to index.html
(same pattern as refreshTscmDevices) and call it from switchMode
alongside DroneMode.init(); remove _refreshDevices/populateSelect
from drone.js which was never guaranteed to run before lazy-load
completed, causing selects to stay on "Loading…" permanently
- IIFE pattern: change from named IIFE + window.DroneMode assignment
to var DroneMode = (function(){...return{...}})() matching OOK/
SpyStations convention
- Init guard: add _initialized flag (OOK state.initialized pattern);
re-entry after destroy() re-registers map/SSE cleanly without
duplicating click listeners on every mode switch
- Lifecycle: destroy() resets _initialized = false so map and SSE
are correctly rebuilt on re-entry
- Stop phase: add isDroneRunning tracking variable in index.html;
_setRunningUI() syncs it; switchMode stop phase now POSTs
/drone/stop when leaving drone mode while active, matching TSCM
- /drone/devices: add monitor_capable field to WiFi interfaces,
add running_as_root and warnings array to response (mirrors
/tscm/devices shape); add os import; show privilege warning div
in drone.html when not running as root
- drone.html: remove for= attribute from SDR label (plain <label>
inside .form-group matches TSCM convention); add droneDeviceWarnings
div for privilege warnings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+32
-3
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
import platform
|
||||
import queue
|
||||
import subprocess
|
||||
@@ -80,7 +81,12 @@ def devices():
|
||||
if "Device:" in lines[j]:
|
||||
dev = lines[j].split("Device:")[1].strip()
|
||||
result["wifi_interfaces"].append(
|
||||
{"name": dev, "display_name": f"{port} ({dev})", "type": "internal"}
|
||||
{
|
||||
"name": dev,
|
||||
"display_name": f"{port} ({dev})",
|
||||
"type": "internal",
|
||||
"monitor_capable": False,
|
||||
}
|
||||
)
|
||||
break
|
||||
except (FileNotFoundError, subprocess.TimeoutExpired, subprocess.SubprocessError):
|
||||
@@ -100,6 +106,7 @@ def devices():
|
||||
"name": current,
|
||||
"display_name": f"{current} ({iface_type})",
|
||||
"type": iface_type,
|
||||
"monitor_capable": True,
|
||||
}
|
||||
)
|
||||
current = None
|
||||
@@ -110,7 +117,12 @@ def devices():
|
||||
if "IEEE 802.11" in line:
|
||||
iface = line.split()[0]
|
||||
result["wifi_interfaces"].append(
|
||||
{"name": iface, "display_name": f"{iface} (managed)", "type": "managed"}
|
||||
{
|
||||
"name": iface,
|
||||
"display_name": f"{iface} (managed)",
|
||||
"type": "managed",
|
||||
"monitor_capable": True,
|
||||
}
|
||||
)
|
||||
except (FileNotFoundError, subprocess.TimeoutExpired, subprocess.SubprocessError):
|
||||
pass
|
||||
@@ -130,7 +142,24 @@ def devices():
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return jsonify({"status": "ok", "devices": result})
|
||||
running_as_root = os.geteuid() == 0
|
||||
warnings = []
|
||||
if not running_as_root:
|
||||
warnings.append(
|
||||
{
|
||||
"type": "privileges",
|
||||
"message": "Not running as root — WiFi monitor mode may be unavailable.",
|
||||
}
|
||||
)
|
||||
|
||||
return jsonify(
|
||||
{
|
||||
"status": "ok",
|
||||
"devices": result,
|
||||
"running_as_root": running_as_root,
|
||||
"warnings": warnings,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@drone_bp.route("/status")
|
||||
|
||||
Reference in New Issue
Block a user