From 504c824cfe435ed944dd2b5eb4f2db8fe8244aa5 Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Sat, 27 Dec 2025 19:42:45 -0800 Subject: [PATCH 1/6] Fix: propagate metadata override created value (#11659) --- src/documents/data_models.py | 3 ++- src/documents/tests/test_bulk_edit.py | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/documents/data_models.py b/src/documents/data_models.py index ffb816053..3acc3f51b 100644 --- a/src/documents/data_models.py +++ b/src/documents/data_models.py @@ -22,7 +22,7 @@ class DocumentMetadataOverrides: document_type_id: int | None = None tag_ids: list[int] | None = None storage_path_id: int | None = None - created: datetime.datetime | None = None + created: datetime.date | None = None asn: int | None = None owner_id: int | None = None view_users: list[int] | None = None @@ -103,6 +103,7 @@ class DocumentMetadataOverrides: overrides.storage_path_id = doc.storage_path.id if doc.storage_path else None overrides.owner_id = doc.owner.id if doc.owner else None overrides.tag_ids = list(doc.tags.values_list("id", flat=True)) + overrides.created = doc.created overrides.view_users = list( get_users_with_perms( diff --git a/src/documents/tests/test_bulk_edit.py b/src/documents/tests/test_bulk_edit.py index 769ff9d66..c220c1e9b 100644 --- a/src/documents/tests/test_bulk_edit.py +++ b/src/documents/tests/test_bulk_edit.py @@ -581,7 +581,7 @@ class TestPDFActions(DirectoriesMixin, TestCase): - Consume file should be called """ doc_ids = [self.doc1.id, self.doc2.id, self.doc3.id] - metadata_document_id = self.doc1.id + metadata_document_id = self.doc2.id user = User.objects.create(username="test_user") result = bulk_edit.merge( @@ -607,7 +607,8 @@ class TestPDFActions(DirectoriesMixin, TestCase): # With metadata_document_id overrides result = bulk_edit.merge(doc_ids, metadata_document_id=metadata_document_id) consume_file_args, _ = mock_consume_file.call_args - self.assertEqual(consume_file_args[1].title, "A (merged)") + self.assertEqual(consume_file_args[1].title, "B (merged)") + self.assertEqual(consume_file_args[1].created, self.doc2.created) self.assertTrue(consume_file_args[1].skip_asn) self.assertEqual(result, "OK") From 99724a25a277b90e0f25115a8115091776f4f946 Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Sun, 28 Dec 2025 16:05:21 -0800 Subject: [PATCH 2/6] Fix: support ordering by storage path name (#11661) --- src/documents/views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/documents/views.py b/src/documents/views.py index ba265926c..d5910497f 100644 --- a/src/documents/views.py +++ b/src/documents/views.py @@ -708,6 +708,7 @@ class DocumentViewSet( "title", "correspondent__name", "document_type__name", + "storage_path__name", "created", "modified", "added", From 84715071153d5fe634a5b0e3759e450fe398ac52 Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Sun, 28 Dec 2025 20:47:44 -0800 Subject: [PATCH 3/6] Fix ref injection in translate-strings workflow --- .github/workflows/translate-strings.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/translate-strings.yml b/.github/workflows/translate-strings.yml index bd9eafae5..2d36d67ca 100644 --- a/.github/workflows/translate-strings.yml +++ b/.github/workflows/translate-strings.yml @@ -12,9 +12,11 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v6 + env: + GH_REF: ${{ github.ref }} # sonar rule:githubactions:S7630 - avoid injection with: token: ${{ secrets.PNGX_BOT_PAT }} - ref: ${{ github.head_ref }} + ref: $GH_REF - name: Set up Python id: setup-python uses: actions/setup-python@v6 From 2e6458dbcca79dc5c123479d7b852a6adbee5edc Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Sun, 28 Dec 2025 20:50:04 -0800 Subject: [PATCH 4/6] Fix environment variable reference in workflow --- .github/workflows/translate-strings.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/translate-strings.yml b/.github/workflows/translate-strings.yml index 2d36d67ca..1a82a5cee 100644 --- a/.github/workflows/translate-strings.yml +++ b/.github/workflows/translate-strings.yml @@ -16,7 +16,7 @@ jobs: GH_REF: ${{ github.ref }} # sonar rule:githubactions:S7630 - avoid injection with: token: ${{ secrets.PNGX_BOT_PAT }} - ref: $GH_REF + ref: ${{ env.GH_REF }} - name: Set up Python id: setup-python uses: actions/setup-python@v6 From a3c19b1e2d5c8eab2bc652d589de8506102a03a9 Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Mon, 29 Dec 2025 06:48:31 -0800 Subject: [PATCH 5/6] Fix: validate cf integer values within PostgreSQL range (#11666) --- src/documents/serialisers.py | 9 ++++++ src/documents/tests/test_api_documents.py | 38 +++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/documents/serialisers.py b/src/documents/serialisers.py index 5c90c6f1c..5c71de9a9 100644 --- a/src/documents/serialisers.py +++ b/src/documents/serialisers.py @@ -18,6 +18,8 @@ from django.core.exceptions import ValidationError from django.core.validators import DecimalValidator from django.core.validators import EmailValidator from django.core.validators import MaxLengthValidator +from django.core.validators import MaxValueValidator +from django.core.validators import MinValueValidator from django.core.validators import RegexValidator from django.core.validators import integer_validator from django.db.models import Count @@ -875,6 +877,13 @@ class CustomFieldInstanceSerializer(serializers.ModelSerializer): uri_validator(data["value"]) elif field.data_type == CustomField.FieldDataType.INT: integer_validator(data["value"]) + try: + value_int = int(data["value"]) + except (TypeError, ValueError): + raise serializers.ValidationError("Enter a valid integer.") + # Keep values within the PostgreSQL integer range + MinValueValidator(-2147483648)(value_int) + MaxValueValidator(2147483647)(value_int) elif ( field.data_type == CustomField.FieldDataType.MONETARY and data["value"] != "" diff --git a/src/documents/tests/test_api_documents.py b/src/documents/tests/test_api_documents.py index 87190c23b..f40ef157f 100644 --- a/src/documents/tests/test_api_documents.py +++ b/src/documents/tests/test_api_documents.py @@ -1664,6 +1664,44 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase): self.consume_file_mock.assert_not_called() + def test_patch_document_integer_custom_field_out_of_range(self): + """ + GIVEN: + - An integer custom field + - A document + WHEN: + - Patching the document with an integer value exceeding PostgreSQL's range + THEN: + - HTTP 400 is returned (validation catches the overflow) + - No custom field instance is created + """ + cf_int = CustomField.objects.create( + name="intfield", + data_type=CustomField.FieldDataType.INT, + ) + doc = Document.objects.create( + title="Doc", + checksum="123", + mime_type="application/pdf", + ) + + response = self.client.patch( + f"/api/documents/{doc.pk}/", + { + "custom_fields": [ + { + "field": cf_int.pk, + "value": 2**31, # overflow for PostgreSQL integer fields + }, + ], + }, + format="json", + ) + + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertIn("custom_fields", response.data) + self.assertEqual(CustomFieldInstance.objects.count(), 0) + def test_upload_with_webui_source(self): """ GIVEN: A document with a source file From 72fd05501b76ab67d69fbf19ffdd2e16e5e69ee3 Mon Sep 17 00:00:00 2001 From: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 29 Dec 2025 14:50:09 +0000 Subject: [PATCH 6/6] Auto translate strings --- src/locale/en_US/LC_MESSAGES/django.po | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/locale/en_US/LC_MESSAGES/django.po b/src/locale/en_US/LC_MESSAGES/django.po index 65dce1cb4..53f2b32f5 100644 --- a/src/locale/en_US/LC_MESSAGES/django.po +++ b/src/locale/en_US/LC_MESSAGES/django.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-24 05:27+0000\n" +"POT-Creation-Date: 2025-12-29 14:49+0000\n" "PO-Revision-Date: 2022-02-17 04:17\n" "Last-Translator: \n" "Language-Team: English\n" @@ -1219,35 +1219,35 @@ msgstr "" msgid "workflow runs" msgstr "" -#: documents/serialisers.py:640 +#: documents/serialisers.py:642 msgid "Invalid color." msgstr "" -#: documents/serialisers.py:1826 +#: documents/serialisers.py:1835 #, python-format msgid "File type %(type)s not supported" msgstr "" -#: documents/serialisers.py:1870 +#: documents/serialisers.py:1879 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:1877 +#: documents/serialisers.py:1886 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:1894 documents/serialisers.py:1904 +#: documents/serialisers.py:1903 documents/serialisers.py:1913 msgid "" "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:1899 +#: documents/serialisers.py:1908 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2014 +#: documents/serialisers.py:2023 msgid "Invalid variable detected." msgstr ""