aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-08-29 11:15:54 +0200
committerChristophe Besson <cbesson@gmail.com>2026-08-29 11:15:54 +0200
commitb7733e812fadd6007976d262bd1d793572a36ba7 (patch)
tree52e2ac07c9ba4929fa50b6ba8d19f94f86e8b304 /packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
parent09a007937f03fad04a390323f3817f1ae7d7c2a9 (diff)
downloadmeshbay-b7733e812fadd6007976d262bd1d793572a36ba7.tar.gz
feat: node workflow redesign — wizard auto-config, reset, MusicBrainz contact
Wizard (Electron): - Auto-provisions node config (hub URL + username) from logged-in user - node:start handles both cold start and restart of misconfigured daemon - Waits for daemon to reach 'running', auto-links node key on hub - probeNode accepts intermediate states for wizard progress feedback Reset (meshbay-node reset): - Unlinks node key from hub (DELETE /me/node_key, best-effort) - Stops and disables daemon (systemctl --user disable --now) - Erases ~/.config/meshbay, ~/.local/share/meshbay, ~/.local/state/meshbay MusicBrainz contact: - Resolved from owner's hub email instead of per-node roster config - Removed musicbrainz_contact UI and WebRTC handshake field - Removed set_musicbrainz_contact/musicbrainz_contact from roster Node pairing: - Added operator pairing banner on NodePage - Added operator_paired flag to list_groups Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py')
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py61
1 files changed, 0 insertions, 61 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 dfa775e..dd68e18 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
@@ -70,7 +70,6 @@ from meshbay_common.adminop import (
OP_TMDB_ENABLED,
OP_VIDEO_ROOT,
OP_TMDB_OVERRIDE,
- OP_MUSICBRAINZ_CONFIG,
OP_MUSICBRAINZ_ENABLED,
OP_AUDIO_ROOT,
OP_PHOTO_ROOTS,
@@ -476,8 +475,6 @@ class WebRTCPeerSession:
self._spawn(self._do_tmdb_search_request(msg))
elif mtype == MNP.TMDB_OVERRIDE:
self._do_tmdb_override(msg)
- elif mtype == MNP.MUSICBRAINZ_CONFIG:
- self._do_musicbrainz_config(msg)
elif mtype == MNP.MUSICBRAINZ_ENABLED:
self._do_musicbrainz_enabled(msg)
elif mtype == MNP.MUSIC_META_REQ:
@@ -753,8 +750,6 @@ class WebRTCPeerSession:
# fields above. No language field: MusicBrainz search doesn't
# take one the way TMDB does.
"musicbrainz_enabled": bool(self._group_ctx().get("musicbrainz_enabled", True)),
- "musicbrainz_contact_configured": bool(
- self._ctx.get("daemon_state", {}).get("musicbrainz_contact_configured", False)),
# Which folder the Music app treats as its entry point for this
# group — same shape as video_root above, "" means unset (the
# Music tab shows nothing yet).
@@ -2069,59 +2064,6 @@ class WebRTCPeerSession:
except Exception:
pass
- def _do_musicbrainz_config(self, msg: dict) -> None:
- """
- Set (or clear) the node-wide MusicBrainz User-Agent contact string
- (docs/musicbay.md §3.2). Unlike tmdb_config there is no token field —
- MusicBrainz's read endpoints need no credential, only a descriptive
- client identity. Signed like tmdb_config: this changes outbound
- third-party network traffic the node did not have before the Music
- app (§8) — an unsigned change would let any member alter egress the
- operator never agreed to.
- """
- contact = msg.get("contact")
- if contact is not None and not isinstance(contact, str):
- self._send({"type": "error", "detail": "Invalid 'contact'"})
- return
- if not self._has_admin_authority():
- self._send({"type": "error", "detail": "No authorized key for this"})
- return
- # Not a secret (unlike tmdb_config's token) — a contact address is
- # meant to be visible to whoever receives it (MusicBrainz), but it is
- # still not committed to the audit log's subject line as free text:
- # the same "yes/no configured" shape as tmdb_config keeps the audit
- # log itself free of a personal address.
- subject = f"contact_configured={'yes' if contact else 'no'}"
- self._issue_admin_challenge(
- OP_MUSICBRAINZ_CONFIG, subject,
- payload={"contact": contact}, group_id="")
-
- async def _admin_exec_musicbrainz_config(
- self, pending: dict, transcript: bytes, sig: bytes,
- ) -> None:
- if not await self._verify_admin_sig(transcript, sig):
- self._send({"type": "error", "detail": "Signature verification failed"})
- self._audit("admin_auth_failed", f"musicbrainz_config:{pending['subject']}")
- return
- p = pending.get("payload") or {}
- try:
- result = await self._run_op(ops.set_musicbrainz_config, p.get("contact"))
- except ops.OpError as e:
- self._send({"type": "error", "detail": e.message})
- return
- self._audit("musicbrainz_config", pending["subject"])
-
- notice = {
- "type": MNP.MUSICBRAINZ_CONFIG_ACK, "v": MNP_VERSION,
- "contact_configured": result["contact_configured"],
- }
- for gctx in self._ctx.get("groups", {}).values():
- for session in list(gctx.get("_peers", {}).values()):
- try:
- session._send(notice)
- except Exception:
- pass
-
def _do_musicbrainz_enabled(self, msg: dict) -> None:
"""
Whether MusicBrainz lookups run for this group at all. Per-group
@@ -3859,9 +3801,6 @@ class WebRTCPeerSession:
elif pending["op"] == OP_TMDB_OVERRIDE:
self._spawn(
self._admin_exec_tmdb_override(pending, transcript, sig_bytes))
- elif pending["op"] == OP_MUSICBRAINZ_CONFIG:
- self._spawn(
- self._admin_exec_musicbrainz_config(pending, transcript, sig_bytes))
elif pending["op"] == OP_MUSICBRAINZ_ENABLED:
self._spawn(
self._admin_exec_musicbrainz_enabled(pending, transcript, sig_bytes))