From 84b032c65e17267d41e04605e79eea82a6f5a59f Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Sat, 15 Aug 2026 02:34:19 +0200 Subject: feat(groups): editable description, and one source of operator authority MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A description could only be set the moment a group was created, so every group made before anyone thought of one stayed blank for good. The owner can now edit it from the group's page, and PATCH /v1/groups/{id} takes it. That endpoint takes the description and nothing else, deliberately. The name, the visibility and the join policy are the terms members joined on; a private group that can quietly become public is not the group they agreed to be in. Changing those needs a decision about who gets told, not a field on a form — there is a test saying so. Separately, the legacy operator key is gone. `admin_pk_ed25519` in node.toml named the operator before the roster existed and was kept so that an existing deployment would keep working; nothing uses it, and a second source of node authority is not something to carry around out of politeness. Authority is the roster, read fresh on every check. It is removed rather than ignored: a config that still names the key gets a warning at startup pointing at the file. Dropping it in silence would refuse invites and file deletion with a signature error that looks like a bug somewhere else — which is exactly how finding M3 presented. Two tests were verifying admin operations by naming a key in the context, which was the legacy path. They now pair an operator into a roster, the way an operator does. The authority test anchored on the deleted function and passed vacuously once it disappeared; it states the invariant against the verifier and the daemon instead. Also defined .btn-secondary, used in four places and styled in none. Co-Authored-By: Claude Opus 5 --- .../src/meshbay_node/transport/webrtc_server.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'packages/meshbay-node/src/meshbay_node/transport') 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 572f6fd..64df7ac 100644 --- a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py +++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py @@ -1415,8 +1415,7 @@ class WebRTCPeerSession: `_verify_admin_sig`. The flag is set at startup and refreshed in-process when an operator pairs. """ - return bool(self._ctx.get("admin_pk_ed25519") - or self._ctx.get("has_admin_authority")) + return bool(self._ctx.get("has_admin_authority")) async def _verify_admin_sig(self, transcript: bytes, sig: bytes) -> bool: """ @@ -1424,14 +1423,12 @@ class WebRTCPeerSession: Read from the roster on each call rather than cached: revoking a paired browser must take effect immediately, and admin operations are rare enough - that a SQLite read costs nothing. `admin_pk_ed25519` in node.toml is still - honoured so an existing deployment keeps working until its operator pairs - (M3) — it is the legacy form of the same statement. - """ - legacy = self._ctx.get("admin_pk_ed25519") - if self._verify_sig(legacy, transcript, sig): - return True + that a SQLite read costs nothing. + There is one source of operator authority and this is it. `admin_pk_ed25519` + in node.toml used to be honoured alongside the roster; it is gone, and a + config that still names it is warned about at startup rather than obeyed. + """ roster = self._ctx.get("roster") if roster is None: return False -- cgit v1.2.3