aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/transport
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-07 22:12:54 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-07 22:20:45 +0200
commit462d76898a306981fbeac859cd54da1468e80639 (patch)
tree9a49723da751b4a7225e3dd37181ecceed192f3a /packages/meshbay-node/src/meshbay_node/transport
parent92e6b9823119b5461efc304a81e79e186a928e6d (diff)
downloadmeshbay-462d76898a306981fbeac859cd54da1468e80639.tar.gz
fix(node): name members admitted without an invitation name
A member who joined by link, by a new device or into an open group was pinned in the roster with no name, so the audit log showed only the first characters of their id. The hub's MNP token now carries the account's username, and after the handshake the node writes it into the roster for an account whose name is empty. An invitation's name is never overwritten; the name is a label, authority stays on `sub`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/transport')
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/webrtc/admin.py7
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/webrtc/admission.py5
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/webrtc/handshake.py1
3 files changed, 10 insertions, 3 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc/admin.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc/admin.py
index 9a6cbd1..48734ab 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/webrtc/admin.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc/admin.py
@@ -157,6 +157,13 @@ class AdminMixin:
if ident and not self._device_confirmed:
self._pinned_pk = ident["pk_ed25519"]
+ async def _name_identity(self) -> None:
+ """Record the token's username for an account the roster has unnamed."""
+ roster = self._ctx.get("roster")
+ if roster is None or not self._user_id or not self._username:
+ return
+ await roster.name_identity(self._user_id, self._username)
+
def _is_node_admin(self) -> bool:
"""
Whether the **account** on this connection is the one the node belongs to.
diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc/admission.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc/admission.py
index 20ebc79..fd9c756 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/webrtc/admission.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc/admission.py
@@ -380,9 +380,8 @@ class AdmissionMixin:
return
await self._pin_and_admit(
- # The name comes from the invitation, not from the token: the hub does
- # not put a username claim in a JWT, so pinning from the session alone
- # left the roster nameless and `member revoke <name>` unable to match.
+ # The invitation's name first: it is the person the operator meant.
+ # The token's name covers an invitation that carries none.
roster, user_id, invite["username"] or username, pk_ed_b64, pk_x_b64,
group_id=invite["group_id"], role=invite["role"],
approved_by=invite["created_by"],
diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc/handshake.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc/handshake.py
index 7822186..f3f4aee 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/webrtc/handshake.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc/handshake.py
@@ -212,6 +212,7 @@ class HandshakeMixin:
self._group_id = self._pending_group
self._username = self._pending_username
self._spawn(self._load_pinned_pk())
+ self._spawn(self._name_identity())
self._register_peer()