<?php
namespace App\EventSubscriber;
use App\Entity\Account\LoginLog;
use App\Entity\User;
use Carbon\CarbonImmutable;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ManagerRegistry;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class UserLoginSubscriber implements EventSubscriberInterface
{
private EntityManagerInterface $em;
public function __construct(
private LoggerInterface $logger,
ManagerRegistry $registry
)
{
$this->em = $registry->getManagerForClass(LoginLog::class);
}
public static function getSubscribedEvents()
{
return [
InteractiveLoginEvent::class => 'onLogin',
];
}
public function onLogin(InteractiveLoginEvent $event): void
{
$authenticationToken = $event->getAuthenticationToken();
$user = $authenticationToken->getUser();
if (!$user instanceof User) {
return;
}
$request = $event->getRequest();
$clientIp = $request->getClientIp();
$mode = in_array(AuthenticatedVoter::IS_AUTHENTICATED_REMEMBERED, $authenticationToken->getRoleNames())
? 'remember_me' : 'password';
$this->logger->info('User {user} [{user_id}] authenticated with "{mode}".', [
'user' => $user->getUsername(),
'user_id' => $user->getId(),
'mode' => $mode,
'client_ip' => $clientIp,
]);
$logRecord = new LoginLog($user, CarbonImmutable::now(), $mode, $clientIp);
$this->em->persist($logRecord);
$this->em->flush();
}
}