src/AppBundle/EventListener/AuthenticationSuccessListener.php line 74

Open in your IDE?
  1. <?php
  2. namespace AppBundle\EventListener;
  3. use AppBundle\Entity\User;
  4. use CodersLab\Lms\SharedKernel\Application\Command\UpdateUserLanguage;
  5. use CodersLab\Lms\SharedKernel\Application\Listener\IAuthenticationListener;
  6. use CodersLab\Lms\SharedKernel\Common\Exception\UserMismatchException;
  7. use CodersLab\Lms\SharedKernel\Domain\Bus\CommandBus;
  8. use CodersLab\Lms\SharedKernel\Domain\IdentityAccess\UserLanguage;
  9. use DateInterval;
  10. use DateTime;
  11. use Lexik\Bundle\JWTAuthenticationBundle\Encoder\JWTEncoderInterface;
  12. use Lexik\Bundle\JWTAuthenticationBundle\Exception\JWTDecodeFailureException;
  13. use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
  14. use Symfony\Component\HttpFoundation\Cookie;
  15. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  16. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  17. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  18. use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
  19. final class AuthenticationSuccessListener implements IAuthenticationListener
  20. {
  21.     private const JWT_ATTRIBUTE_NAME 'jwt';
  22.     private JWTTokenManagerInterface $jwtManager;
  23.     private JWTEncoderInterface $JWTEncoder;
  24.     private TokenStorageInterface $tokenStorage;
  25.     private SessionInterface $session;
  26.     private CommandBus $commandBus;
  27.     public function __construct(
  28.         JWTTokenManagerInterface $jwtManager,
  29.         JWTEncoderInterface $JWTEncoder,
  30.         TokenStorageInterface $tokenStorage,
  31.         SessionInterface $session,
  32.         CommandBus $commandBus
  33.     ) {
  34.         $this->jwtManager $jwtManager;
  35.         $this->JWTEncoder $JWTEncoder;
  36.         $this->tokenStorage $tokenStorage;
  37.         $this->session $session;
  38.         $this->commandBus $commandBus;
  39.     }
  40.     public function onSecurityInteractiveLogin(InteractiveLoginEvent $event): void
  41.     {
  42.         $request $event->getRequest();
  43.         $jwt $request->cookies->get(IAuthenticationListener::COOKIE_NAME'');
  44.         $sessionUser $this->tokenStorage->getToken()->getUser();
  45.         try {
  46.             $token $this->JWTEncoder->decode($jwt);
  47.             if ($sessionUser->getUsername() !== $token['username']) {
  48.                 throw new UserMismatchException();
  49.             }
  50.         } catch (JWTDecodeFailureException UserMismatchException $exception) {
  51.             /** @var User $user */
  52.             $user $event->getAuthenticationToken()->getUser();
  53.             $jwt $this->jwtManager->create($user);
  54.             if ($this->session->get('_locale') !== null) {
  55.                 $this->commandBus->dispatch(
  56.                     new UpdateUserLanguage(
  57.                         $user->getId(),
  58.                         new UserLanguage($this->session->get('_locale'))
  59.                     )
  60.                 );
  61.             }
  62.         }
  63.         $request->attributes->set(self::JWT_ATTRIBUTE_NAME$jwt);
  64.     }
  65.     public function onKernelResponse(ResponseEvent $event): void
  66.     {
  67.         $attributes $event->getRequest()->attributes;
  68.         if (!$attributes->has(self::JWT_ATTRIBUTE_NAME)) {
  69.             return;
  70.         }
  71.         $cookie = new Cookie(
  72.             IAuthenticationListener::COOKIE_NAME,
  73.             $attributes->get(self::JWT_ATTRIBUTE_NAME),
  74.             (new DateTime())->add(new DateInterval('P365D')),
  75.             '/',
  76.             null,
  77.             false,
  78.             false
  79.         );
  80.         $headers $event->getResponse()->headers;
  81.         $headers->setCookie($cookie);
  82.     }
  83. }