diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-10-07 22:12:54 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-10-07 22:20:45 +0200 |
| commit | 462d76898a306981fbeac859cd54da1468e80639 (patch) | |
| tree | 9a49723da751b4a7225e3dd37181ecceed192f3a /packages/meshbay-node/tests/test_roster_pairing.py | |
| parent | 92e6b9823119b5461efc304a81e79e186a928e6d (diff) | |
| download | meshbay-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/tests/test_roster_pairing.py')
| -rw-r--r-- | packages/meshbay-node/tests/test_roster_pairing.py | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/packages/meshbay-node/tests/test_roster_pairing.py b/packages/meshbay-node/tests/test_roster_pairing.py index 585a909..5687215 100644 --- a/packages/meshbay-node/tests/test_roster_pairing.py +++ b/packages/meshbay-node/tests/test_roster_pairing.py @@ -1339,3 +1339,39 @@ async def test_an_operator_cannot_revoke_themselves(tmp_path, roster): session._do_member_revoke({"user_id": session._user_id}) assert _last(session).get("detail") == "Cannot revoke yourself" + + +# ── Names from the token ────────────────────────────────────────────────────── + +async def test_link_admission_is_named_from_the_token(roster): + """A link carries no name, so the account was pinned nameless and the audit + log showed it as a bare id. The token's name fills it.""" + _, pk_ed, pk_x = _keypair() + await roster.pin_identity(user_id="u-link", username="", pk_ed25519=pk_ed, + pk_x25519=pk_x, via="link") + assert await roster.name_identity("u-link", "StephISGoD") + assert (await roster.get_identity("u-link"))["username"] == "StephISGoD" + + +async def test_token_name_never_overwrites_the_invitation(roster): + _, pk_ed, pk_x = _keypair() + await roster.pin_identity(user_id="u-code", username="grenet", pk_ed25519=pk_ed, + pk_x25519=pk_x, via="code") + assert not await roster.name_identity("u-code", "someone-else") + assert not await roster.name_identity("u-code", "") + assert (await roster.get_identity("u-code"))["username"] == "grenet" + + +async def test_handshake_records_the_token_name(roster): + _, pk_ed, pk_x = _keypair() + await roster.pin_identity(user_id="u-open", username="", pk_ed25519=pk_ed, + pk_x25519=pk_x, via="tofu") + + class _Session: + _ctx = {"roster": roster} + _user_id = "u-open" + _username = "alice" + + await WebRTCPeerSession._name_identity(_Session()) + assert (await roster.get_identity("u-open"))["username"] == "alice" + assert "self._spawn(self._name_identity())" in session_method("_complete_handshake") |