From cd5649b96e0175690f779daed203a4fe7b762779 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sat, 13 Jun 2026 23:22:11 +0200 Subject: [PATCH] fix(timeline): harden curator event precision field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Validate the submitted precision against the DatePrecision allow-list in parseEventForm (falls back to DAY) so an untrusted token can't flow into the request body — symmetric with the existing `type` narrowing. - Parameterize the precision input name via DatePrecisionField's new precisionInputName prop; the timeline form now submits `precision` instead of the misleading document-domain `metaDatePrecision`. Document form keeps the default, so its behaviour is unchanged. - Capture EventTypeSelect's onchange into EventForm's `type` state so it no longer goes stale (the submitted value was already correct via the hidden input; this keeps the local state in sync). Addresses PR #832 review (#781). Co-Authored-By: Claude Opus 4.8 --- .../primitives/DatePrecisionField.svelte | 8 +++++-- frontend/src/lib/timeline/EventForm.svelte | 8 +++++-- frontend/src/lib/timeline/eventFormServer.ts | 18 ++++++++++++++- .../zeitstrahl/events/new/page.server.spec.ts | 23 ++++++++++++++++++- 4 files changed, 51 insertions(+), 6 deletions(-) diff --git a/frontend/src/lib/shared/primitives/DatePrecisionField.svelte b/frontend/src/lib/shared/primitives/DatePrecisionField.svelte index 36403ac4..9f54132b 100644 --- a/frontend/src/lib/shared/primitives/DatePrecisionField.svelte +++ b/frontend/src/lib/shared/primitives/DatePrecisionField.svelte @@ -16,7 +16,9 @@ import type { DatePrecision } from '$lib/shared/utils/documentDate'; * Exposed (shared contract — both WhoWhenSection and EventForm depend on it): * - dateIso, precision, endDateIso — $bindable; the parent's binding IS the * state (no redundant $state mirror). - * - dateInputName / endDateInputName — names of the hidden ISO inputs. + * - dateInputName / endDateInputName / precisionInputName — submitted field + * names; defaults match the document form (`metaDatePrecision`), the timeline + * form overrides precisionInputName to `precision`. * - initialDateIso / suggestedDateIso — seeding inputs (see onMount + $effect). * - dateTestId / precisionTestId / endDateInnerTestId — forwarded data-testid * attributes so existing WhoWhenSection selectors survive the extraction. @@ -28,6 +30,7 @@ let { endDateIso = $bindable(''), dateInputName = 'documentDate', endDateInputName = 'metaDateEnd', + precisionInputName = 'metaDatePrecision', initialDateIso = '', suggestedDateIso = '', dateLabel = m.form_label_date(), @@ -41,6 +44,7 @@ let { endDateIso?: string; dateInputName?: string; endDateInputName?: string; + precisionInputName?: string; initialDateIso?: string; suggestedDateIso?: string; dateLabel?: string; @@ -145,7 +149,7 @@ $effect(() => {