mirror of
https://github.com/AletheiaVox/signal_bridge_remote.git
synced 2026-10-07 11:28:16 +08:00
feat: OAuth 2.0 support, server-side safety governor, multi-user auth mode
Publishes server work that shipped in the Android edition but never made it to this repo: - Full OAuth 2.0 flow (discovery metadata, dynamic client registration, authorize + token endpoints) so claude.ai remote connectors and the Android app can authenticate per-user instead of relying on the sole-phone fallback. - Safety governor: server-side heat model (intensity x time) with automatic cooldown, per-user overrides via GET/POST /safety/config, and governor state piggybacked on heartbeat pings so relay clients can display it. - SB_REQUIRE_MCP_AUTH env flag for multi-user deployments (disables the unauthenticated sole-phone fallback). - requirements-phone.txt and .env.example documenting the new knobs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,7 @@ import logging
|
||||
import time
|
||||
|
||||
from . import config
|
||||
from .governor import governor
|
||||
from .session_registry import registry
|
||||
|
||||
log = logging.getLogger("signal_bridge.safety")
|
||||
@@ -70,8 +71,15 @@ class DeadManSwitch:
|
||||
sessions = await registry.get_all_sessions()
|
||||
|
||||
for user_id, session in sessions.items():
|
||||
# Send ping
|
||||
ping = {"type": "heartbeat_ping", "timestamp": now}
|
||||
# Tick the governor (advances heat model)
|
||||
governor.tick(user_id)
|
||||
|
||||
# Send ping with governor state piggybacked
|
||||
ping = {
|
||||
"type": "heartbeat_ping",
|
||||
"timestamp": now,
|
||||
**governor.get_state(user_id),
|
||||
}
|
||||
try:
|
||||
await session.websocket.send(json.dumps(ping))
|
||||
except Exception:
|
||||
@@ -92,6 +100,8 @@ class DeadManSwitch:
|
||||
async def _emergency_stop(self, user_id: str, session):
|
||||
"""Send stop-all and disconnect the session."""
|
||||
log.critical(f"EMERGENCY STOP for user {user_id} — all devices halted")
|
||||
governor.record_stop(user_id)
|
||||
|
||||
try:
|
||||
stop_cmd = {"type": "stop", "device": "all", "emergency": True}
|
||||
await session.websocket.send(json.dumps(stop_cmd))
|
||||
@@ -104,6 +114,7 @@ class DeadManSwitch:
|
||||
pass
|
||||
|
||||
await registry.unregister(user_id)
|
||||
governor.remove_user(user_id)
|
||||
|
||||
|
||||
# Singleton
|
||||
|
||||
Reference in New Issue
Block a user