Match the cover and logo upload filter to the dp-upload contract
Some checks are pending
DevPlace CI / test (pull_request) Blocked by required conditions
Some checks are pending
DevPlace CI / test (pull_request) Blocked by required conditions
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) <noreply@anthropic.com>
This commit is contained in:
parent
72e088c160
commit
265cb781f9
@ -295,11 +295,11 @@
|
||||
<div class="grid-2col">
|
||||
<div class="auth-field">
|
||||
<label>Cover image{% if cover %} (replaces current){% endif %}</label>
|
||||
<dp-upload name="cover_attachment_uid" max-files="1" accept="image/*" allowed-types="png,jpg,jpeg,gif,webp" max-size="{{ max_upload_size_mb() }}" label="Upload cover"></dp-upload>
|
||||
<dp-upload name="cover_attachment_uid" max-files="1" accept="image/*" allowed-types="{{ allowed_image_types() }}" max-size="{{ max_upload_size_mb() }}" label="Upload cover"></dp-upload>
|
||||
</div>
|
||||
<div class="auth-field">
|
||||
<label>Project logo{% if logo %} (replaces current){% endif %}</label>
|
||||
<dp-upload name="logo_attachment_uid" max-files="1" accept="image/*" allowed-types="png,jpg,jpeg,gif,webp" max-size="{{ max_upload_size_mb() }}" label="Upload logo"></dp-upload>
|
||||
<dp-upload name="logo_attachment_uid" max-files="1" accept="image/*" allowed-types="{{ allowed_image_types() }}" max-size="{{ max_upload_size_mb() }}" label="Upload logo"></dp-upload>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -140,11 +140,11 @@
|
||||
<div class="grid-2col">
|
||||
<div class="auth-field">
|
||||
<label>Cover image (optional)</label>
|
||||
<dp-upload name="cover_attachment_uid" max-files="1" accept="image/*" allowed-types="png,jpg,jpeg,gif,webp" max-size="{{ max_upload_size_mb() }}" label="Upload cover"></dp-upload>
|
||||
<dp-upload name="cover_attachment_uid" max-files="1" accept="image/*" allowed-types="{{ allowed_image_types() }}" max-size="{{ max_upload_size_mb() }}" label="Upload cover"></dp-upload>
|
||||
</div>
|
||||
<div class="auth-field">
|
||||
<label>Project logo (optional)</label>
|
||||
<dp-upload name="logo_attachment_uid" max-files="1" accept="image/*" allowed-types="png,jpg,jpeg,gif,webp" max-size="{{ max_upload_size_mb() }}" label="Upload logo"></dp-upload>
|
||||
<dp-upload name="logo_attachment_uid" max-files="1" accept="image/*" allowed-types="{{ allowed_image_types() }}" max-size="{{ max_upload_size_mb() }}" label="Upload logo"></dp-upload>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -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",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user