diff options
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node')
4 files changed, 28 insertions, 3 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/roster.py b/packages/meshbay-node/src/meshbay_node/roster.py index eb8c031..07b9ea6 100644 --- a/packages/meshbay-node/src/meshbay_node/roster.py +++ b/packages/meshbay-node/src/meshbay_node/roster.py @@ -398,6 +398,24 @@ class Roster: (user_id,)) as cur: return [dict(r) for r in await cur.fetchall()] + async def name_identity(self, user_id: str, username: str) -> bool: + """ + Give a nameless account the name its hub token carries. + + Only an empty name is filled: an invitation names the person the + operator meant, and that stays. Links, devices and open groups pin an + account with no name, which left the audit log showing a bare id. + """ + assert self._db + if not username: + return False + cur = await self._db.execute( + "UPDATE identities SET username = ? " + "WHERE user_id = ? AND username = ''", + (username, user_id)) + await self._db.commit() + return cur.rowcount > 0 + async def revoke_device(self, user_id: str, pk_ed25519: str) -> bool: """ Retire one device, leaving the account's others alone. 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() |