<?php
declare(strict_types=1);
namespace App\Bundles\UserBundle\EventListener;
use App\Bundles\UserBundle\Service\User\UserLogoutService;
use App\Platform\Service\SessionProvider;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
#[AsEventListener(event: RequestEvent::class, method: 'onKernelRequest')]
class SessionIdleHandler
{
public function __construct(
private readonly UserLogoutService $userLogoutService,
private readonly SessionProvider $sessionProvider,
private readonly TokenStorageInterface $tokenStorage,
private readonly int $sessionIdleTime,
) {
}
public function onKernelRequest(RequestEvent $event): void
{
if ($event->getRequestType() !== HttpKernelInterface::MAIN_REQUEST) {
return;
}
if (!$token = $this->tokenStorage->getToken()) {
return;
}
if ($this->sessionIdleTime <= 0) {
return;
}
$session = $this->sessionProvider->provide();
$session->start();
$lapse = time() - $session->getMetadataBag()->getLastUsed();
if ($lapse > $this->sessionIdleTime) {
$this->logoutAndRedirectUser($event, $token, $session);
}
}
private function logoutAndRedirectUser(RequestEvent $event, TokenInterface $token, SessionInterface $session): void
{
$this->userLogoutService->logout($event->getRequest(), $token, $session);
$event->setResponse(new RedirectResponse('/login?expiredSession=true'));
}
}