Merge pull request #445 from the-luap/fix/issue-426-edit-allows-clearing-expiry

fix(events): admins can clear expiration on edit even when 'Require expiration' is ON (#426)
This commit is contained in:
Paul Nothaft
2026-05-10 21:01:28 +02:00
committed by GitHub
2 changed files with 12 additions and 13 deletions
+7 -8
View File
@@ -1237,14 +1237,13 @@ router.put('/:id', adminAuth, requirePermission('events.edit'), requireEventOwne
}
// Enforce expires_at requirement based on app settings
if (Object.prototype.hasOwnProperty.call(updates, 'expires_at')) {
if (!updates.expires_at) {
const fieldReqs = await getEventFieldRequirements();
if (fieldReqs.require_expiration) {
return res.status(400).json({ error: 'Expiration date is required.' });
}
updates.expires_at = null;
}
// Allow admins to clear `expires_at` on edit even when the global
// `event_require_expiration` setting is ON (#426). The setting now
// controls only the create-time default — once an event exists, an
// admin editing it can override and remove the expiration. Empty /
// null values normalize to NULL in the column ("never expires").
if (Object.prototype.hasOwnProperty.call(updates, 'expires_at') && !updates.expires_at) {
updates.expires_at = null;
}
// Format hero logo settings if provided
@@ -459,7 +459,6 @@ export const EventDetailsPage: React.FC = () => {
}, [showMediaFilter, photoFilters.media_type]);
const { data: publicSettings } = usePublicSettings();
const requireExpiration = publicSettings?.event_require_expiration !== false;
const phoneFieldEnabled = publicSettings?.event_phone_field_enabled === true;
// Fetch categories for the event
@@ -686,10 +685,11 @@ export const EventDetailsPage: React.FC = () => {
return;
}
if (requireExpiration && !editForm.expires_at) {
toast.error(t('validation.expirationRequired', 'Expiration date is required.'));
return;
}
// No expiration-required validation on edit (#426). The global
// `event_require_expiration` setting only enforces a default at
// create-time — once an event exists, an admin can clear the
// expiration via this form. The matching backend gate was dropped
// in adminEvents.js.
// Clean up the data - remove undefined values
const updateData: any = {