Fix speaker token ignored after badge verification or active join.
Deploy Ladill Meet / deploy (push) Successful in 1m0s

Process ?speaker= before registration gate and already-joined redirects so Events speakers get panelist role even when they previously registered as attendees.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-07-03 18:35:03 +00:00
co-authored by Cursor
parent 3d68f7a83b
commit ee3f7410f4
3 changed files with 126 additions and 15 deletions
+45 -11
View File
@@ -61,6 +61,31 @@ class JoinController extends Controller
]);
}
$speakerToken = trim((string) $request->query('speaker', ''));
if ($speakerToken !== '' && $this->acceptsEventsSpeakerToken($room, $request)) {
if ($this->verifyAndStoreSpeaker($request, $room, $speakerToken)) {
$session = $room->activeSession();
if ($session) {
$participantUuid = $request->session()->get("meet.participant.{$session->uuid}");
$participant = $participantUuid
? Participant::where('uuid', $participantUuid)->where('session_id', $session->id)->first()
: null;
if ($participant?->status === 'joined') {
$this->sessions->syncEventsSpeakerRole($request, $participant);
return redirect()->route('meet.room', $session);
}
}
return redirect()->route('meet.join', $room);
}
return $this->gateView($request, $room)->withErrors([
'speaker' => 'Speaker invitation link is invalid or expired.',
]);
}
$session = $room->activeSession();
if ($session) {
$participantUuid = $request->session()->get("meet.participant.{$session->uuid}");
@@ -88,17 +113,6 @@ class JoinController extends Controller
]);
}
$speakerToken = trim((string) $request->query('speaker', ''));
if ($speakerToken !== '' && $this->requiresEventsRegistration($room, $request)) {
if ($this->verifyAndStoreSpeaker($request, $room, $speakerToken)) {
return redirect()->route('meet.join', $room);
}
return $this->gateView($request, $room)->withErrors([
'speaker' => 'Speaker invitation link is invalid or expired.',
]);
}
if ($this->requiresEventsRegistration($room, $request)) {
return $this->gateView($request, $room);
}
@@ -142,6 +156,11 @@ class JoinController extends Controller
return redirect()->route('meet.join', $room);
}
$speakerToken = trim((string) $request->query('speaker', ''));
if ($speakerToken !== '' && $this->acceptsEventsSpeakerToken($room, $request)) {
$this->verifyAndStoreSpeaker($request, $room, $speakerToken);
}
if ($this->requiresEventsRegistration($room, $request)) {
return redirect()->route('meet.join', $room);
}
@@ -164,9 +183,15 @@ class JoinController extends Controller
$user = $request->user();
$registration = EventsRegistrationSession::get($request, $room);
$speakerVerified = EventsRegistrationSession::isSpeakerVerified($request, $room);
$displayName = $user?->name ?? ($validated['display_name'] ?? ($registration['name'] ?? 'Guest'));
$email = $user?->email ?? ($registration['email'] ?? null);
if ($speakerVerified && filled($registration['email'] ?? null)) {
$email = (string) $registration['email'];
$displayName = (string) ($registration['name'] ?? $displayName);
}
$kind = $room->isConference() ? 'conference' : ($room->isWebinar() ? 'webinar' : 'meeting');
[$allowed, $reason] = $this->security->canJoin($room, $user, $email ?? $displayName.'@guest.local');
@@ -353,6 +378,15 @@ class JoinController extends Controller
return ! EventsRegistrationSession::canJoinEventsLinked($request, $room);
}
protected function acceptsEventsSpeakerToken(Room $room, Request $request): bool
{
if (! $room->isEventsLinked() || $this->isRoomHost($request, $room)) {
return false;
}
return $room->isWebinar() || $room->isConference();
}
protected function verifyAndStoreSpeaker(Request $request, Room $room, string $speakerToken): bool
{
$eventId = EventsSourceLink::eventId($room);
+6 -4
View File
@@ -42,11 +42,13 @@ class EventsRegistrationSession
/** @param array{email?: ?string, name?: ?string, badge_code?: ?string, speaker_token?: ?string} $data */
public static function store(Request $request, Room $room, array $data): void
{
$existing = self::get($request, $room) ?? [];
$request->session()->put(self::key($room), [
'email' => $data['email'] ?? null,
'name' => $data['name'] ?? null,
'badge_code' => $data['badge_code'] ?? null,
'speaker_token' => $data['speaker_token'] ?? null,
'email' => array_key_exists('email', $data) ? $data['email'] : ($existing['email'] ?? null),
'name' => array_key_exists('name', $data) ? $data['name'] : ($existing['name'] ?? null),
'badge_code' => array_key_exists('badge_code', $data) ? $data['badge_code'] : ($existing['badge_code'] ?? null),
'speaker_token' => array_key_exists('speaker_token', $data) ? $data['speaker_token'] : ($existing['speaker_token'] ?? null),
]);
}