Gate Events-linked joins behind registration and badge check-in.
Deploy Ladill Meet / deploy (push) Successful in 43s
Deploy Ladill Meet / deploy (push) Successful in 43s
Attendees register or sign in with a badge before the display-name screen; email is no longer collected on the Meet join form. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -6,11 +6,13 @@ use App\Http\Controllers\Controller;
|
||||
use App\Models\Participant;
|
||||
use App\Models\Room;
|
||||
use App\Models\Session;
|
||||
use App\Services\Integrations\EventsClient;
|
||||
use App\Services\Meet\ConferenceService;
|
||||
use App\Services\Meet\InvitationService;
|
||||
use App\Services\Meet\SecurityPolicyService;
|
||||
use App\Services\Meet\SessionService;
|
||||
use App\Services\Meet\SpaceService;
|
||||
use App\Support\EventsRegistrationSession;
|
||||
use App\Support\EventsSourceLink;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
@@ -25,6 +27,7 @@ class JoinController extends Controller
|
||||
protected SecurityPolicyService $security,
|
||||
protected SpaceService $spaces,
|
||||
protected ConferenceService $conferences,
|
||||
protected EventsClient $events,
|
||||
) {}
|
||||
|
||||
public function show(Request $request, Room $room): View|RedirectResponse
|
||||
@@ -74,11 +77,38 @@ class JoinController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
return view('meet.join.show', [
|
||||
'room' => $room,
|
||||
'organization' => $room->organization,
|
||||
'user' => $request->user(),
|
||||
'isWebinar' => $room->isWebinar(),
|
||||
$badge = trim((string) $request->query('badge', ''));
|
||||
if ($badge !== '' && $this->requiresEventsRegistration($room, $request)) {
|
||||
if ($this->verifyAndStoreBadge($request, $room, $badge)) {
|
||||
return redirect()->route('meet.join', $room);
|
||||
}
|
||||
|
||||
return $this->gateView($request, $room)->withErrors([
|
||||
'badge_code' => 'Badge code not found or registration is not confirmed.',
|
||||
]);
|
||||
}
|
||||
|
||||
if ($this->requiresEventsRegistration($room, $request)) {
|
||||
return $this->gateView($request, $room);
|
||||
}
|
||||
|
||||
return $this->displayNameView($request, $room);
|
||||
}
|
||||
|
||||
public function verifyBadge(Request $request, Room $room): RedirectResponse
|
||||
{
|
||||
if ($room->passcode && ! $request->session()->get("meet.passcode.{$room->uuid}")) {
|
||||
return redirect()->route('meet.join', $room);
|
||||
}
|
||||
|
||||
$request->validate(['badge_code' => ['required', 'string', 'max:16']]);
|
||||
|
||||
if ($this->verifyAndStoreBadge($request, $room, $request->input('badge_code'))) {
|
||||
return redirect()->route('meet.join', $room);
|
||||
}
|
||||
|
||||
return back()->withErrors([
|
||||
'badge_code' => 'Badge code not found or registration is not confirmed.',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -101,6 +131,10 @@ class JoinController extends Controller
|
||||
return redirect()->route('meet.join', $room);
|
||||
}
|
||||
|
||||
if ($this->requiresEventsRegistration($room, $request)) {
|
||||
return redirect()->route('meet.join', $room);
|
||||
}
|
||||
|
||||
$rules = [
|
||||
'email' => ['nullable', 'email'],
|
||||
];
|
||||
@@ -118,10 +152,11 @@ class JoinController extends Controller
|
||||
}
|
||||
|
||||
$user = $request->user();
|
||||
$displayName = $user?->name ?? ($validated['display_name'] ?? 'Guest');
|
||||
$email = $user?->email ?? ($validated['email'] ?? null);
|
||||
$registration = EventsRegistrationSession::get($request, $room);
|
||||
$displayName = $user?->name ?? ($validated['display_name'] ?? ($registration['name'] ?? 'Guest'));
|
||||
$email = $user?->email ?? ($registration['email'] ?? null);
|
||||
|
||||
$kind = $room->isConference() ? 'conference' : 'meeting';
|
||||
$kind = $room->isConference() ? 'conference' : ($room->isWebinar() ? 'webinar' : 'meeting');
|
||||
|
||||
[$allowed, $reason] = $this->security->canJoin($room, $user, $email ?? $displayName.'@guest.local');
|
||||
if (! $allowed && $reason !== 'passcode_required') {
|
||||
@@ -164,30 +199,9 @@ class JoinController extends Controller
|
||||
$role = $this->spaces->resolveJoinRole($room, $user, $role);
|
||||
} elseif ($room->isConference() && $role !== 'host') {
|
||||
$role = $this->conferences->resolveJoinRole($room, $user, $email, $role);
|
||||
|
||||
if ($role === 'attendee' && $room->isEventsLinked()) {
|
||||
$joinEmail = $email ?? $user?->email;
|
||||
if (! $room->hasEventsRegistrationInvite($joinEmail)) {
|
||||
$registrationUrl = EventsSourceLink::eventRegistrationUrl($room);
|
||||
|
||||
return $registrationUrl
|
||||
? redirect()->away($registrationUrl)
|
||||
: back()->withErrors(['join' => 'Register for this conference in Ladill Events before joining.']);
|
||||
}
|
||||
}
|
||||
} elseif ($room->isWebinar() && $role !== 'host') {
|
||||
if ($room->isEventsLinked()) {
|
||||
$joinEmail = $email ?? $user?->email;
|
||||
if (! $room->hasEventsRegistrationInvite($joinEmail)) {
|
||||
$registrationUrl = EventsSourceLink::eventRegistrationUrl($room);
|
||||
|
||||
return $registrationUrl
|
||||
? redirect()->away($registrationUrl)
|
||||
: back()->withErrors(['join' => 'Register for this webinar in Ladill Events before joining.']);
|
||||
}
|
||||
|
||||
$role = 'attendee';
|
||||
$displayName = $displayName ?? $user?->name;
|
||||
} else {
|
||||
return back()->withErrors([
|
||||
'join' => 'This webinar must be linked to a Ladill Events event before attendees can register and join.',
|
||||
@@ -301,4 +315,79 @@ class JoinController extends Controller
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function isRoomHost(Request $request, Room $room): bool
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
return $user && $user->ownerRef() === $room->host_user_ref;
|
||||
}
|
||||
|
||||
protected function requiresEventsRegistration(Room $room, Request $request): bool
|
||||
{
|
||||
if (! $room->isEventsLinked()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->isRoomHost($request, $room)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $room->isWebinar() && ! $room->isConference()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ! EventsRegistrationSession::isVerified($request, $room);
|
||||
}
|
||||
|
||||
protected function verifyAndStoreBadge(Request $request, Room $room, string $badgeCode): bool
|
||||
{
|
||||
$eventId = EventsSourceLink::eventId($room);
|
||||
if (! $eventId || ! $this->events->isConfigured()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$registration = $this->events->verifyRegistration($eventId, $room->owner_ref, $badgeCode);
|
||||
if (! $registration) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EventsRegistrationSession::store($request, $room, [
|
||||
'email' => $registration['attendee_email'] ?? null,
|
||||
'name' => $registration['attendee_name'] ?? null,
|
||||
'badge_code' => $registration['badge_code'] ?? $badgeCode,
|
||||
]);
|
||||
|
||||
return EventsRegistrationSession::isVerified($request, $room);
|
||||
}
|
||||
|
||||
protected function gateView(Request $request, Room $room): View
|
||||
{
|
||||
$meetReturn = EventsSourceLink::meetReturnUrl($room);
|
||||
$registrationUrl = EventsSourceLink::eventRegistrationUrl($room, $meetReturn);
|
||||
$sessionNoun = $room->isConference() ? 'conference' : 'webinar';
|
||||
|
||||
return view('meet.join.gate', [
|
||||
'room' => $room,
|
||||
'organization' => $room->organization,
|
||||
'eventTitle' => EventsSourceLink::eventTitle($room),
|
||||
'registrationUrl' => $registrationUrl,
|
||||
'sessionNoun' => $sessionNoun,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function displayNameView(Request $request, Room $room): View
|
||||
{
|
||||
$registration = EventsRegistrationSession::get($request, $room);
|
||||
$sessionNoun = $room->isConference() ? 'conference' : ($room->isWebinar() ? 'webinar' : 'meeting');
|
||||
|
||||
return view('meet.join.show', [
|
||||
'room' => $room,
|
||||
'organization' => $room->organization,
|
||||
'user' => $request->user(),
|
||||
'isWebinar' => $room->isWebinar(),
|
||||
'sessionNoun' => $sessionNoun,
|
||||
'defaultDisplayName' => $registration['name'] ?? '',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user