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);