<?php
namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Security;
use App\Entity\User;
class PasswordExpirySubscriber implements EventSubscriberInterface
{
private RouterInterface $router;
private Security $security;
public function __construct(Security $security, RouterInterface $router)
{
$this->security = $security;
$this->router = $router;
}
public static function getSubscribedEvents(): array
{
return [
RequestEvent::class => 'onKernelRequest',
];
}
public function onKernelRequest(RequestEvent $event)
{
if (!$event->isMainRequest()) {
return;
}
$request = $event->getRequest();
$allowedRoutes = [
'app_change_password',
'app_logout',
'app_login',
];
$route = $request->attributes->get('_route');
$path = $request->getPathInfo();
if (!$route) {
return;
}
$allowedRoutes = [
'app_change_password',
'app_logout',
'app_login',
];
if (in_array($route, $allowedRoutes) || str_contains($path, '/change-password')) {
return;
}
$user = $this->security->getUser();
if (!$user instanceof User) {
return;
}
$passwordChangedAt = $user->getPasswordChangedAt();
$now = new \DateTime();
if (!$passwordChangedAt) {
$event->setResponse(
new RedirectResponse($this->router->generate('app_change_password'))
);
return;
}
$expireDate = (clone $passwordChangedAt)->modify('+90 days');
if ($now >= $expireDate) {
$event->setResponse(
new RedirectResponse($this->router->generate('app_change_password'))
);
}
}
}