Repository: paperless-ngx/paperless-ngx

Issue:
[BUG] Users first name is ignored when building their display name
### Description

The dashboard greeting ("Hello \<user\>, welcome to Paperless-ngx") and the user drop-down button in the upper right corner of the app display a user's username even if they have configured their first name.

**Analysis**
The display name of a user is constructed using `first_name ?? username ?? ''` in [`SettingsService`](https://github.com/paperless-ngx/paperless-ngx/blob/dev/src-ui/src/app/services/settings.service.ts#LL87-L93C4), so if `first_name` is set, it should be used instead of `username`. Unfortunately, this doesn't work because `first_name` is never set. The user object used here is fetched from `/api/ui_settings` which doesn't provide a `first_name` field (see [`UiSettingsView`](https://github.com/paperless-ngx/paperless-ngx/blob/dev/src/documents/views.py#L1035-L1040)).



### Steps to reproduce

1. Configure a first name for your user
2. Refresh page

Expected behavior: dashboard greeting and user drop-down button show the configured first name
Actual behavior: dashboard greeting and user drop-down button show the username

### Webserver logs

```bash
n/a
```


### Browser logs

_No response_

### Paperless-ngx version

1.15.1

### Host OS

Ubuntu 22.04

### Installation method

Docker - official image

### Browser

_No response_

### Configuration changes

_No response_

### Other

_No response_


Discussion:

Resolving patch:
diff --git a/src/documents/views.py b/src/documents/views.py
--- a/src/documents/views.py
+++ b/src/documents/views.py
@@ -1028,16 +1028,23 @@ def get(self, request, format=None):
             ui_settings["update_checking"] = {
                 "backend_setting": settings.ENABLE_UPDATE_CHECK,
             }
+        user_resp = {
+            "id": user.id,
+            "username": user.username,
+            "is_superuser": user.is_superuser,
+            "groups": list(user.groups.values_list("id", flat=True)),
+        }
+
+        if len(user.first_name) > 0:
+            user_resp["first_name"] = user.first_name
+        if len(user.last_name) > 0:
+            user_resp["last_name"] = user.last_name
+
         # strip <app_label>.
         roles = map(lambda perm: re.sub(r"^\w+.", "", perm), user.get_all_permissions())
         return Response(
             {
-                "user": {
-                    "id": user.id,
-                    "username": user.username,
-                    "is_superuser": user.is_superuser,
-                    "groups": user.groups.values_list("id", flat=True),
-                },
+                "user": user_resp,
                 "settings": ui_settings,
                 "permissions": roles,
             },


Test patch:
diff --git a/src/documents/tests/test_api.py b/src/documents/tests/test_api.py
--- a/src/documents/tests/test_api.py
+++ b/src/documents/tests/test_api.py
@@ -2594,11 +2594,25 @@ class TestApiUiSettings(DirectoriesMixin, APITestCase):
     def setUp(self):
         super().setUp()
         self.test_user = User.objects.create_superuser(username="test")
+        self.test_user.first_name = "Test"
+        self.test_user.last_name = "User"
+        self.test_user.save()
         self.client.force_authenticate(user=self.test_user)
 
     def test_api_get_ui_settings(self):
         response = self.client.get(self.ENDPOINT, format="json")
         self.assertEqual(response.status_code, status.HTTP_200_OK)
+        self.assertDictEqual(
+            response.data["user"],
+            {
+                "id": self.test_user.id,
+                "username": self.test_user.username,
+                "is_superuser": True,
+                "groups": [],
+                "first_name": self.test_user.first_name,
+                "last_name": self.test_user.last_name,
+            },
+        )
         self.assertDictEqual(
             response.data["settings"],
             {