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="grid-2col">
|
||||||
<div class="auth-field">
|
<div class="auth-field">
|
||||||
<label>Cover image{% if cover %} (replaces current){% endif %}</label>
|
<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>
|
||||||
<div class="auth-field">
|
<div class="auth-field">
|
||||||
<label>Project logo{% if logo %} (replaces current){% endif %}</label>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -140,11 +140,11 @@
|
|||||||
<div class="grid-2col">
|
<div class="grid-2col">
|
||||||
<div class="auth-field">
|
<div class="auth-field">
|
||||||
<label>Cover image (optional)</label>
|
<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>
|
||||||
<div class="auth-field">
|
<div class="auth-field">
|
||||||
<label>Project logo (optional)</label>
|
<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>
|
||||||
</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 format_date as _format_date
|
||||||
from devplacepy.utils import time_ago as _time_ago
|
from devplacepy.utils import time_ago as _time_ago
|
||||||
from devplacepy.utils import get_badge, is_admin, is_primary_admin, pretty_json
|
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 is_owner as _owns
|
||||||
from devplacepy.content import maturity_hidden as _maturity_hidden
|
from devplacepy.content import maturity_hidden as _maturity_hidden
|
||||||
from devplacepy.customization import custom_css_tag, custom_js_tag, page_type_for
|
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", "")
|
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_upload_size_mb"] = jinja_max_upload_size_mb
|
||||||
templates.env.globals["max_attachments_per_resource"] = jinja_max_attachments
|
templates.env.globals["max_attachments_per_resource"] = jinja_max_attachments
|
||||||
templates.env.globals["allowed_file_types"] = jinja_allowed_file_types
|
templates.env.globals["allowed_file_types"] = jinja_allowed_file_types
|
||||||
|
templates.env.globals["allowed_image_types"] = jinja_allowed_image_types
|
||||||
|
|
||||||
_LANGUAGE_NAMES = {
|
_LANGUAGE_NAMES = {
|
||||||
"python": "Python",
|
"python": "Python",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user