<?php
namespace Aqarmap\Bundle\UserBundle\EventListener;
use Aqarmap\Bundle\UserBundle\Entity\User;
use Aqarmap\Bundle\UserBundle\Services\UserActivityService;
use FOS\UserBundle\Event\UserEvent;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Model\UserManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
class UserLoginListener implements EventSubscriberInterface
{
private UserManagerInterface $userManager;
/** @var EventDispatcherInterface */
private $dispatcher;
/** @var UserActivityService */
private $userActivityService;
private LoggerInterface $logger;
public function __construct(UserManagerInterface $userManager, EventDispatcherInterface $dispatcher, UserActivityService $userActivityService, LoggerInterface $logger)
{
$this->userManager = $userManager;
$this->dispatcher = $dispatcher;
$this->userActivityService = $userActivityService;
$this->logger = $logger;
}
public static function getSubscribedEvents()
{
return [
SecurityEvents::INTERACTIVE_LOGIN => [['updateLegacyPasswordsListener'], ['setAuthTokenInCookies']],
FOSUserEvents::SECURITY_IMPLICIT_LOGIN => 'onImplisictLogin',
];
}
/**
* Updated the legacy user passwords after logging in, with the new password encoder.
*/
public function updateLegacyPasswordsListener(InteractiveLoginEvent $event): void
{
$request = $event->getRequest();
/** @var User $user */
$user = $event->getAuthenticationToken()->getUser();
$plainPassword = $request->request->get('_password');
if ($user->getLegacy() && !empty($plainPassword)) {
$user->setPlainPassword($plainPassword);
$user->setLegacy(false);
$this->userManager->updateUser($user);
$event = new UserEvent($user, $event->getRequest());
$this->dispatcher->dispatch($event, FOSUserEvents::USER_PASSWORD_CHANGED);
}
$this->userActivityService->setSyncInCookies(true);
}
/**
* Set the user token in cookies after login for the use on the frontend (BFF).
*/
public function setAuthTokenInCookies(InteractiveLoginEvent $event): void
{
$this->logger->debug('Setting auth token in cookies');
/** @var User $user */
$user = $event->getAuthenticationToken()->getUser();
$response = new Response();
$accessTokenCookie = Cookie::create('access_token', $user->getUserAccessToken())
->withHttpOnly(false)
->withExpires(new \DateTime('+30 day'))
;
$refreshTokenCookie = Cookie::create('refresh_token', $user->getUserRefreshToken())
->withHttpOnly(false)
->withExpires(new \DateTime('+30 day'))
;
$response->headers->setCookie($accessTokenCookie);
$response->headers->setCookie($refreshTokenCookie);
$response->sendHeaders();
}
/**
* Listen when user login programmatically.
*/
public function onImplisictLogin(UserEvent $userEvent): void
{
$this->userActivityService->setSyncInCookies(true);
}
}