From 265cb781f9c14c379fc274c47c41d492776eadbb Mon Sep 17 00:00:00 2001 From: blindxfish Date: Thu, 13 Aug 2026 08:29:35 +0200 Subject: [PATCH] Match the cover and logo upload filter to the dp-upload contract The cover and logo widgets declared allowed-types as bare extensions (png,jpg,jpeg,gif,webp), but dp-upload builds the candidate extension with a leading dot before testing membership, so every selected file was refused with "type is not allowed". The four widgets were the only hardcoded lists in the codebase: every other call site passes allowed_file_types(), which defaults to empty and therefore disables the client filter entirely, which is why nothing else exposed the mismatch. Rather than dotting a duplicated literal in four places, the effective list now comes from a new allowed_image_types() Jinja global that intersects allowed_extensions() with IMAGE_EXTENSIONS. That reuses the one server-side choke point, so the widget can never advertise a type the upload gate would reject, and narrowing the admin allowed_file_types setting narrows these widgets with it. IMAGE_EXTENSIONS rather than POST_IMAGE_EXTENSIONS is the correct set here because the route guard is _hero_attachment_uid, which accepts any is_image attachment, and bmp/tiff both upload and pass it. Co-Authored-By: Claude Opus 5 (1M context) --- devplacepy/templates/project_detail.html | 4 ++-- devplacepy/templates/projects.html | 4 ++-- devplacepy/templating.py | 12 +++++++++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/devplacepy/templates/project_detail.html b/devplacepy/templates/project_detail.html index 5bf8ceb4..a21fbb3e 100644 --- a/devplacepy/templates/project_detail.html +++ b/devplacepy/templates/project_detail.html @@ -295,11 +295,11 @@
- +
- +
diff --git a/devplacepy/templates/projects.html b/devplacepy/templates/projects.html index 70ad454b..a67662c1 100644 --- a/devplacepy/templates/projects.html +++ b/devplacepy/templates/projects.html @@ -140,11 +140,11 @@
- +
- +
diff --git a/devplacepy/templating.py b/devplacepy/templating.py index b150222a..08134506 100644 --- a/devplacepy/templating.py +++ b/devplacepy/templating.py @@ -13,7 +13,12 @@ from devplacepy.avatar import avatar_url, avatar_seed from devplacepy.utils import format_date as _format_date from devplacepy.utils import time_ago as _time_ago from devplacepy.utils import get_badge, is_admin, is_primary_admin, pretty_json -from devplacepy.attachments import format_file_size, file_icon_emoji +from devplacepy.attachments import ( + IMAGE_EXTENSIONS, + allowed_extensions, + format_file_size, + file_icon_emoji, +) from devplacepy.content import is_owner as _owns from devplacepy.content import maturity_hidden as _maturity_hidden from devplacepy.customization import custom_css_tag, custom_js_tag, page_type_for @@ -224,9 +229,14 @@ def jinja_allowed_file_types() -> str: return get_setting("allowed_file_types", "") +def jinja_allowed_image_types() -> str: + return ",".join(sorted(allowed_extensions() & IMAGE_EXTENSIONS)) + + templates.env.globals["max_upload_size_mb"] = jinja_max_upload_size_mb templates.env.globals["max_attachments_per_resource"] = jinja_max_attachments templates.env.globals["allowed_file_types"] = jinja_allowed_file_types +templates.env.globals["allowed_image_types"] = jinja_allowed_image_types _LANGUAGE_NAMES = { "python": "Python",