aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
diff options
context:
space:
mode:
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.py13
1 files changed, 12 insertions, 1 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 10dfcb0..416e84c 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
@@ -390,6 +390,13 @@ class WebRTCPeerSession:
"type": MNP.HANDSHAKE_CHALLENGE,
"v": MNP_VERSION,
"nonce": base64.b64encode(self._gek_challenge).decode(),
+ # Announced here because a first-time joiner needs it *before* the
+ # ack: join_request signs a transcript naming this node, and someone
+ # who has never held the GEK cannot complete the handshake to learn
+ # it. Unverified at this point — the ack proves it, the client checks
+ # the two match, and a wrong value only makes our own verification
+ # fail. It is never a substitute for the ack's proof and signature.
+ "node_pk": self._node_pk_b64(),
})
def _do_handshake_response(self, msg: dict) -> None:
@@ -731,7 +738,10 @@ class WebRTCPeerSession:
return
await self._pin_and_admit(
- roster, user_id, username, pk_ed_b64, pk_x_b64,
+ # 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.
+ 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"], via="code")
await self._join_ok(user_id, pk_x_raw, invite["group_id"],
@@ -1332,6 +1342,7 @@ class WebRTCPeerSession:
role=ROLE_MEMBER,
created_by=self._user_id or "",
ttl=self._ctx.get("invite_ttl", DEFAULT_INVITE_TTL),
+ username=payload.get("username", ""),
)
invites = await roster.list_invites()
expires = next(