<?php
namespace Mm\Escmid\EaaBundle\EventSubscriber;
use Mm\Escmid\EaaBundle\Platform\RouteChecker;
use Mm\Escmid\EaaBundle\Platform\SystemClock;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
final readonly class LogoutAfterInactivePeriodSubscriber implements EventSubscriberInterface
{
public function __construct(
private RouteChecker $routeChecker,
private SystemClock $clock,
) {
// --
}
public static function getSubscribedEvents(): array
{
return [
ResponseEvent::class => ['onKernelResponse'],
];
}
public function onKernelResponse(ResponseEvent $event): void
{
if (!$event->isMainRequest()) {
return;
}
$request = $event->getRequest();
if ($this->routeChecker->checkIfThisRouteRequireNoLogin($request->getRequestUri())) {
return;
}
$session = $request->getSession();
$shouldLogoutAt = $session->get('shouldLogoutAt');
$this->handleUserLogout($shouldLogoutAt,
function () use ($event) {
$event->setResponse(new RedirectResponse('/logout'));
},
function () use ($session) {
$session->set('shouldLogoutAt', $this->clock->now()->modify('+30 minutes'));
}
);
}
public function handleUserLogout(?\DateTimeImmutable $logoutTime, \Closure $onLogout, \Closure $onContinueSession): void
{
if ($logoutTime instanceof \DateTimeImmutable && $this->clock->now() > $logoutTime) {
$onLogout();
return;
}
$onContinueSession();
}
}