fix(pres_mgmt): remove email from presenter sign-in URLs

Previously, presenters without a Person record had their email address used
as the person_id fallback in Copy Link and emailed sign-in URLs. This exposed
the email in browser history, server logs, and to anyone the link was shared
with.

Replaced .email fallback with .event_presenter_id in all three URL-building
locations:
- Copy Link clipboard value (presenter detail page)
- Email sign-in button person_id (presenter detail page)
- Email sign-in button person_id (presenter list component)

The sign-in handler's presenter_id_hint mechanism looks up the email from
Dexie using the event_presenter_id already in the URL, so cross-session auth
still works without the email being in the URL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-06-23 14:54:24 -04:00
parent 5d6008431c
commit 85870b67f5
2 changed files with 5 additions and 6 deletions

View File

@@ -290,15 +290,14 @@ let presenter_can_upload = $derived(presenter_is_authed && presenter_agree_ok);
class="flex flex-row flex-wrap items-center justify-center gap-0.25">
{#if ($lq__event_presenter_obj.person_id || $lq__event_presenter_obj.email) && $ae_loc.trusted_access}
<!-- A button to copy the access link to the clipboard. -->
<!-- person_id falls back to presenter.email for presenters without a Person record. -->
<!-- Example: /events/CHs3F44Xq76/session/Wh8UnJlbIA0?person_id=fV1dl_IJ0yY&person_pass=abc123 -->
<!-- person_id falls back to event_presenter_id (not email) — the sign-in
handler derives the email from Dexie via the presenter_id param. -->
<!-- {#snippet btn_text()}
<span class="fas fa-copy m-1"></span>
Copy Access Link
{/snippet} -->
<MyClipboard
value={`${$ae_loc.url_origin}/events/${$lq__event_presenter_obj.event_id}/session/${$lq__event_presenter_obj.event_session_id}?person_id=${encodeURIComponent($lq__event_presenter_obj.person_id ?? $lq__event_presenter_obj.email ?? '')}&person_pass=${encodeURIComponent($lq__event_presenter_obj.person_passcode ?? $lq__event_presenter_obj.passcode ?? '')}&presentation_id=${encodeURIComponent($lq__event_presenter_obj?.event_presentation_id ?? '')}&presenter_id=${encodeURIComponent($lq__event_presenter_obj?.event_presenter_id ?? '')}`}
value={`${$ae_loc.url_origin}/events/${$lq__event_presenter_obj.event_id}/session/${$lq__event_presenter_obj.event_session_id}?person_id=${encodeURIComponent($lq__event_presenter_obj.person_id ?? $lq__event_presenter_obj.event_presenter_id ?? '')}&person_pass=${encodeURIComponent($lq__event_presenter_obj.person_passcode ?? $lq__event_presenter_obj.passcode ?? '')}&presentation_id=${encodeURIComponent($lq__event_presenter_obj?.event_presentation_id ?? '')}&presenter_id=${encodeURIComponent($lq__event_presenter_obj?.event_presenter_id ?? '')}`}
btn_text="Copy Access Link"
btn_title="Copy the presenter access link to the clipboard."
btn_class="btn btn-sm preset-tonal-secondary hover:preset-filled-secondary-500 border border-secondary-500 hover:preset-filled-secondary-500"
@@ -319,7 +318,7 @@ let presenter_can_upload = $derived(presenter_is_authed && presenter_agree_ok);
// presenter.email (from the spreadsheet import) for the ~75% of
// LCI presenters who have no Person record in iMIS.
const use_email = $lq__event_presenter_obj.person_primary_email ?? $lq__event_presenter_obj.email;
const use_person_id = $lq__event_presenter_obj.person_id ?? $lq__event_presenter_obj.email;
const use_person_id = $lq__event_presenter_obj.person_id ?? $lq__event_presenter_obj.event_presenter_id;
const use_passcode = $lq__event_presenter_obj.person_passcode ?? $lq__event_presenter_obj.passcode;
if (!use_email) {

View File

@@ -193,7 +193,7 @@ let ae_tmp: key_val = $state({});
// Prefer Person-record email; fall back to presenter.email for
// presenters without a Person record (common for LCI/iMIS gaps).
const use_email = event_presenter_obj.person_primary_email ?? event_presenter_obj.email;
const use_person_id = event_presenter_obj.person_id ?? event_presenter_obj.email;
const use_person_id = event_presenter_obj.person_id ?? event_presenter_obj.event_presenter_id;
const use_passcode = event_presenter_obj.person_passcode ?? event_presenter_obj.passcode;
if (!use_email) {