aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/transport
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-08-29 18:42:43 +0200
committerChristophe Besson <cbesson@gmail.com>2026-08-29 18:52:53 +0200
commit1f8a52484412b48205e5ff6aac506428e2fb77ed (patch)
tree5598419ee4caef21f607876de6af2d30d6452191 /packages/meshbay-node/src/meshbay_node/transport
parent8de80b7e19738b716d9973c0b4ba3b42085f7359 (diff)
downloadmeshbay-1f8a52484412b48205e5ff6aac506428e2fb77ed.tar.gz
feat(node): editable node settings in the Node page (D5)
Expose invite_ttl_hours, pair_ttl_hours, device_request_ttl_minutes, max_concurrent_streams and transcode_incompatible_video in the Node management panel. Changes are applied immediately via roster.db and written back to node.toml so they survive a DB wipe. On startup, roster overrides take precedence over node.toml defaults. Draft v6 §2.11 documents the design; MNP gains node_settings_set / node_settings_set_ack for the browser path. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/transport')
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py20
1 files changed, 20 insertions, 0 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
index 1bd7203..a934418 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
@@ -504,6 +504,8 @@ class WebRTCPeerSession:
self._do_group_attach(msg)
elif mtype == MNP.GROUP_DETACH:
self._do_group_detach(msg)
+ elif mtype == MNP.NODE_SETTINGS_SET:
+ self._spawn(self._do_node_settings_set(msg))
elif mtype == MNP.NODE_RELOAD:
self._spawn(self._do_node_reload(msg))
elif mtype == MNP.KEYPAIR_BUNDLE_STORE:
@@ -2187,6 +2189,24 @@ class WebRTCPeerSession:
log.error("node_status failed: %s", e, exc_info=True)
self._send({"type": "error", "detail": "Internal error"})
+ async def _do_node_settings_set(self, msg: dict) -> None:
+ if not self._is_node_admin():
+ self._send({"type": "error", "detail": "Not the node operator"})
+ return
+ settings = msg.get("settings", {})
+ if not settings:
+ self._send({"type": "error", "detail": "No settings provided"})
+ return
+ try:
+ result = await self._run_op(ops.set_node_settings, settings)
+ self._send({"type": MNP.NODE_SETTINGS_SET_ACK, "v": MNP_VERSION,
+ **result})
+ except ops.OpError as e:
+ self._send({"type": "error", "detail": e.message})
+ except Exception as e:
+ log.error("node_settings_set failed: %s", e, exc_info=True)
+ self._send({"type": "error", "detail": "Internal error"})
+
async def _do_roster_read(self, msg: dict) -> None:
if not self._is_node_admin():
self._send({"type": "error", "detail": "Not the node operator"})