fix(pres_mgmt): enforce presenter agreement before file upload

presenter_is_authed only checked sign-in state, never .agree, so a
presenter could upload without ever agreeing whenever the admin's
"Require Presenter Agreement" setting was on.

Added presenter_agree_ok (trusted_access || !require__presenter_agree ||
auth__event_presenter_obj.agree) and presenter_can_upload
(presenter_is_authed && presenter_agree_ok) in
presenter/[presenter_id]/+page.svelte, swapped into every place the
upload UI / file-list permissions are gated in both the default and
manage_files alt views. The alt view's public_access identity bypass is
preserved but now also requires presenter_agree_ok.

Added an inline warning message in place of the upload section when
signed in but pending agreement, instead of it silently disappearing.

Marked done in TODO__Agents.md; all three open LCI Pres Mgmt restoration
items are now resolved (2 were already fixed and just needed verifying).

svelte-check: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-06-16 15:27:12 -04:00
parent fa179eb7f4
commit 5321eb0d70
2 changed files with 45 additions and 19 deletions

View File

@@ -5,7 +5,7 @@
> **Status:** Stable — ongoing development.
> **Scope:** Active/open work only. Completed detail lives in archive files.
## 🔴 LCI October — Pres Mgmt Restoration (in progress 2026-06-12)
## LCI October — Pres Mgmt Restoration (complete 2026-06-16)
These features regressed over the last 6 months and must be working before the LCI conference.
Reference commit for original working implementation: `bb993a102`.
@@ -52,18 +52,16 @@ wrong to users.
session page) reads `presenter_id`/`presentation_id` from the URL and grants presenter-level
auth via `auth__kv.presenter`/`auth__kv.presentation`, not just session read access.
- [ ] **[Pres Mgmt] Presenter agreement not enforced before file upload** (verified still open,
2026-06-16) `presenter_is_authed` in `presenter/[presenter_id]/+page.svelte` — the gate used
everywhere the upload UI is shown (`Comp_event_files_upload`, `Element_manage_event_file_li_wrap`)
— only checks sign-in state (`auth__kv.presenter`/`auth__kv.session`/person match). It has no
dependency on `.agree` at all. `require__presenter_agree` (`pres_mgmt_loc.current`) is read in
exactly one place (`presenter_page_menu.svelte`) to decide whether to *show* the Agreed/Not
Agreed button — it never blocks anything. A presenter who signs in but has not agreed can still
see and use the upload section when this setting is on. Confirmed `ae_comp__event_files_upload.svelte`
has no internal agreement check either — there is no enforcement anywhere in the chain.
Fix: gate the upload sections (and ideally `allow_basic`/`allow_moderator` on the file list too)
on `!pres_mgmt_loc.current.require__presenter_agree || $lq__auth__event_presenter_obj?.agree`
in addition to `presenter_is_authed`.
- [x] **[Pres Mgmt] Presenter agreement not enforced before file upload** (fixed 2026-06-16)
`presenter_is_authed` only checked sign-in state, never `.agree`, so a presenter could upload
without agreeing whenever `require__presenter_agree` was on. Added a new derived
`presenter_agree_ok` (`trusted_access || !require__presenter_agree || auth__event_presenter_obj.agree`)
and `presenter_can_upload` (`presenter_is_authed && presenter_agree_ok`) in
`presenter/[presenter_id]/+page.svelte`, and swapped it in everywhere the upload UI/file-list
permissions are gated (both the default view and the `manage_files` alt view — the latter's
`public_access` identity bypass is preserved but still requires `presenter_agree_ok`). Also
added an inline warning message in place of the upload section when signed in but pending
agreement, instead of it just silently disappearing.
### Session POC Sign-In

View File

@@ -149,6 +149,22 @@ let presenter_is_authed = $derived(
)
);
// True when the admin's "Require Presenter Agreement" setting (if on) is satisfied —
// either the requirement is off, the presenter has agreed, or staff is managing this
// on their behalf. Trusted staff always bypass it, same as the "agreed" message above.
// WHY this exists separately from presenter_is_authed: a presenter can be signed in
// (authed) without having agreed yet — being signed in must not be enough to upload
// when an agreement is required. See TODO__Agents.md "Presenter agreement not enforced
// before file upload".
let presenter_agree_ok = $derived(
$ae_loc.trusted_access ||
!pres_mgmt_loc.current.require__presenter_agree ||
!!$lq__auth__event_presenter_obj?.agree
);
// The actual gate for showing/using the upload UI — signed in AND (if required) agreed.
let presenter_can_upload = $derived(presenter_is_authed && presenter_agree_ok);
// if (browser && $lq__event_presenter_obj) {
// console.log('Pres Mgmt [page]: +presenter.svelte');
// $events_slct.event_presenter_obj = $lq__event_presenter_obj;
@@ -379,7 +395,7 @@ let presenter_is_authed = $derived(
</h3>
<!-- Yes... This is a duplicate of what is shown when they press "Presenter Files" button. It can be cleaned up later. -->
{#if presenter_is_authed}
{#if presenter_can_upload}
<Comp_event_files_upload
class_li="border border-surface-200-800 rounded-xl p-4 bg-surface-50-900 hover:bg-surface-100-900 transition-colors duration-200"
link_to_type="event_presenter"
@@ -404,14 +420,20 @@ let presenter_is_authed = $derived(
</span>
{/snippet}
</Comp_event_files_upload>
{:else if presenter_is_authed}
<p class="bg-warning-100 border-warning-300 text-warning-800 flex items-center gap-2 rounded-md border p-3 text-sm">
<TriangleAlert size="1em" class="flex-none" />
File upload is locked until you agree to the presenter terms — see the
Agreed/Not Agreed action in the Options menu above.
</p>
{/if}
<div class="w-max max-w-full overflow-x-auto">
<Element_manage_event_file_li_wrap
link_to_type={'event_presenter'}
link_to_id={$lq__event_presenter_obj?.event_presenter_id}
allow_basic={presenter_is_authed}
allow_moderator={presenter_is_authed}
allow_basic={presenter_can_upload}
allow_moderator={presenter_can_upload}
container_class_li={''} />
</div>
{:else if pres_mgmt_loc.current.show_content__presenter_view == 'manage_files' && $ae_loc.authenticated_access}
@@ -428,7 +450,7 @@ let presenter_is_authed = $derived(
</span>
</h3>
{#if presenter_is_authed || $ae_loc.public_access}
{#if presenter_can_upload || ($ae_loc.public_access && presenter_agree_ok)}
<Comp_event_files_upload
class_li="border border-surface-200-800 rounded-xl p-4 bg-surface-50-900 hover:bg-surface-100-900 transition-colors duration-200"
link_to_type="event_presenter"
@@ -454,14 +476,20 @@ let presenter_is_authed = $derived(
</span>
{/snippet}
</Comp_event_files_upload>
{:else if presenter_is_authed}
<p class="bg-warning-100 border-warning-300 text-warning-800 flex items-center gap-2 rounded-md border p-3 text-sm">
<TriangleAlert size="1em" class="flex-none" />
File upload is locked until you agree to the presenter terms — see the
Agreed/Not Agreed action in the Options menu above.
</p>
{/if}
<div class="w-max max-w-full overflow-x-auto">
<Element_manage_event_file_li_wrap
link_to_type={'event_presenter'}
link_to_id={$lq__event_presenter_obj?.event_presenter_id}
allow_basic={presenter_is_authed || $ae_loc.public_access}
allow_moderator={presenter_is_authed}
allow_basic={presenter_can_upload || ($ae_loc.public_access && presenter_agree_ok)}
allow_moderator={presenter_can_upload}
container_class_li={''} />
</div>
</div>