Files
scrum-poker-internal/app/Http/Middleware/EnsureRoomParticipant.php
T
Twyco 640a2970c3
CI/CD / test_and_check_app (push) Failing after 2m7s
CI/CD / Publish immutable image (push) Skipped
Handle authenticated room instance takeover
2026-09-10 16:33:13 +02:00

128 lines
3.6 KiB
PHP

<?php
namespace App\Http\Middleware;
use App\Models\Room;
use App\Services\Rooms\RoomParticipationService;
use App\Services\Rooms\RoomPlayerInstanceService;
use Closure;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Symfony\Component\HttpFoundation\Response;
class EnsureRoomParticipant
{
public function __construct(
private readonly RoomParticipationService $roomParticipation,
private readonly RoomPlayerInstanceService $playerInstances,
) {}
/**
* Handle an incoming request.
*
* @param Closure(Request): (Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
$room = $request->route('room');
if (! $room instanceof Room) {
abort(404);
}
$sessionKey = "room_players.{$room->id}";
if ($room->trashed()) {
$request->session()->forget($sessionKey);
Inertia::flash('toast', [
'type' => 'info',
'message' => 'Dieser Raum wurde gelöscht.',
]);
return to_route('home');
}
if ($room->isClosed()) {
return to_route('room.join', [
'join_code' => $room->join_code,
])->withErrors([
'join_code' => 'Dieser Raum ist geschlossen.',
]);
}
$playerId = $request->session()->get($sessionKey);
$hasSessionPlayer = is_numeric($playerId);
$instanceId = $this->playerInstances->for($request);
$player = $hasSessionPlayer
? $room->players()->find((int) $playerId)
: null;
if ($player === null && $hasSessionPlayer) {
$request->session()->forget($sessionKey);
return to_route('room.join', [
'join_code' => $room->join_code,
])->withErrors([
'join_code' => 'Diese Spieler-Instanz ist nicht mehr aktiv.',
]);
}
if (
$player !== null
&& $player->active_instance_id !== null
&& $player->active_instance_id !== $instanceId
) {
$request->session()->forget($sessionKey);
return to_route('room.join', [
'join_code' => $room->join_code,
])->withErrors([
'join_code' => 'Dein Account ist diesem Raum in einer anderen Instanz beigetreten.',
]);
}
if ($player !== null) {
$player = $this->roomParticipation->activateInstance(
$room,
$player,
$instanceId,
);
}
if ($player === null && $request->user() !== null) {
$player = $room->players()
->where('user_id', $request->user()->id)
->first();
if ($player !== null) {
$player = $this->roomParticipation->activateInstance(
$room,
$player,
$instanceId,
);
$request->session()->put($sessionKey, $player->id);
}
}
if ($player === null) {
return to_route('room.join', [
'join_code' => $room->join_code,
])->withErrors([
'join_code' => 'Du musst diesem Raum erst beitreten.',
]);
}
if ($player->inactive_at !== null) {
return to_route('room.join', [
'join_code' => $room->join_code,
]);
}
$player->markAsSeen();
$request->attributes->set('currentPlayer', $player);
return $next($request);
}
}