From 05a67320b1f9791bfe8ac6a18857c9cbbbcc93e0 Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Fri, 10 Jul 2026 14:16:38 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=A9=B9(backend)=20fix=20the=20LiveKit=20t?= =?UTF-8?q?oken=20to=20use=20full=20name=20as=20display=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the user's full name as the display name in the emitted LiveKit token instead of the email. Requested by several self-hosters. --- src/backend/core/tests/test_utils.py | 57 +++++++++++++++++++++++++++- src/backend/core/utils.py | 2 +- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/backend/core/tests/test_utils.py b/src/backend/core/tests/test_utils.py index 9f1f491f..907a7143 100644 --- a/src/backend/core/tests/test_utils.py +++ b/src/backend/core/tests/test_utils.py @@ -2,13 +2,68 @@ Test utils functions """ +# pylint: disable=W0621 import json from unittest import mock +from django.conf import settings + +import jwt import pytest from livekit.api import TwirpError -from core.utils import NotificationError, create_livekit_client, notify_participants +from core.factories import UserFactory +from core.utils import ( + NotificationError, + create_livekit_client, + generate_token, + notify_participants, +) + +pytestmark = pytest.mark.django_db + + +def decode_token(token: str) -> dict: + """Decode a LiveKit JWT access token for inspection.""" + return jwt.decode( + token, + settings.LIVEKIT_CONFIGURATION["api_secret"], + algorithms=["HS256"], + ) + + +def test_generate_token_authenticated_uses_full_name(): + """The token's display name should default to the user's full name.""" + user = UserFactory(full_name="Jane Doe") + + token = generate_token(room="my-room", user=user) + + claims = decode_token(token) + assert claims["name"] == "Jane Doe" + assert claims["sub"] == str(user.sub) + + +def test_generate_token_authenticated_fallback_user_representation(): + """ + When the user has no full name, the token's display name should fall back + to the user's string representation. + """ + user = UserFactory(full_name=None) + + token = generate_token(room="my-room", user=user) + + claims = decode_token(token) + assert claims["name"] == str(user) + + +def test_generate_token_explicit_username_overrides_default(): + """An explicitly provided username should take precedence over the full name.""" + user = UserFactory(full_name="Jane Doe") + + token = generate_token(room="my-room", user=user, username="Custom Name") + + claims = decode_token(token) + assert claims["name"] == "Custom Name" @mock.patch("asyncio.get_running_loop") diff --git a/src/backend/core/utils.py b/src/backend/core/utils.py index 8a8e09fa..88980eed 100644 --- a/src/backend/core/utils.py +++ b/src/backend/core/utils.py @@ -109,7 +109,7 @@ def generate_token( default_username = "Anonymous" else: identity = str(user.sub) - default_username = str(user) + default_username = user.full_name or str(user) if color is None: color = generate_color(identity)