Phase 4 enhancements: WebSocket auth, HTTPS UI, plugin hooks, build fixes

Security:
- Add token-based WebSocket authentication (closes critical security gap)
  - In-memory token store with 24h TTL (token_store.py)
  - POST /api/auth/token exchanges Basic Auth for WS token
  - GET /api/auth/status public endpoint for auth check
  - WebSocket validates token query param, rejects with close code 4401
  - Frontend LoginPrompt modal for credential entry
  - WebSocket manager handles full auth flow with auth_required state
  - No-op when AUTH_ENABLED=false (preserves existing behavior)

HTTPS:
- Wire HTTPS toggle in Settings UI (POST /api/system/ssl/toggle)
- Add certificate regeneration button
- Display SSL info (expiration, SANs, SHA256 fingerprint)

Plugins:
- Wire trigger_hook("pm3_command") in PM3 service
- Wire trigger_hook("update_check") in update manager

Build/Infrastructure:
- Enable NetworkManager in pi-gen AP setup stage
- Add HF booster board detection patch for Proxmark3
- Update LED PWM control patch
- Fix BLE adapter, UPS drivers, WiFi manager improvements
- Update HTTPS support stage script

Documentation:
- Update PROJECT_STATUS.md and IMPLEMENTATION_PRIORITIES.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
michael
2026-03-03 11:45:11 -08:00
parent 4f35df1781
commit 2ec89041ef
24 changed files with 1249 additions and 362 deletions

View File

@@ -1,6 +1,8 @@
"""WebSocket endpoint routes."""
from fastapi import APIRouter, WebSocket, WebSocketDisconnect
from .manager import ws_manager
from ..api.token_store import validate_token
from .. import config
router = APIRouter()
@@ -9,6 +11,11 @@ router = APIRouter()
async def websocket_endpoint(websocket: WebSocket):
"""WebSocket endpoint for real-time event streaming.
When AUTH_ENABLED=true, a valid token must be provided as a query
parameter: ws://host/ws/events?token=<token>
Tokens are obtained via POST /api/auth/token with Basic Auth.
Unauthorized connections are closed with code 4401.
Events include:
- connected: Initial connection confirmation
- system_stats: CPU, memory, temperature updates (every 5s)
@@ -22,6 +29,15 @@ async def websocket_endpoint(websocket: WebSocket):
- update_available: New version available
- update_downloading: Download progress
"""
# Validate auth token when authentication is enabled
if config.AUTH_ENABLED:
token = websocket.query_params.get("token")
if not token or not validate_token(token):
# Must accept before sending close code so client receives it
await websocket.accept()
await websocket.close(code=4401, reason="Authentication required")
return
await ws_manager.connect(websocket)
try:
while True: