<?php
namespace App\Service;
use App\Entity\User;
use JMS\Serializer\ArrayTransformerInterface;
use JMS\Serializer\SerializationContext;
use JMS\Serializer\SerializerInterface;
use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTCreatedEvent;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* Class JWTDataExtender is used to add additional information into JWT token itself
* related to User entity serialisation config ( all fields marked by "token" group)
* @package App\EventListener
*/
class JWTDataExtender
{
const REMEMBER_ME_EXPIRATION_DAYS = 30;
/** @var ArrayTransformerInterface */
private $transformer;
/**
* @var RequestStack
*/
private $requestStack;
public function __construct(ArrayTransformerInterface $transformer, RequestStack $requestStack)
{
/** @var SerializerInterface serializer */
$this->transformer = $transformer;
$this->requestStack = $requestStack;
}
public function onCreated(JWTCreatedEvent $event)
{
$data = $event->getData();
$user = $event->getUser();
if (!$user instanceof UserInterface) {
return;
}
$this->rememberMe($data);
$this->addImpersonator($user, $data);
$context = SerializationContext::create()
->setGroups('token');
$serialized = $this->transformer->toArray($user, $context);
$data = array_merge($data, $serialized);
$event->setData($data);
}
private function rememberMe(array &$data)
{
$request = $this->requestStack->getCurrentRequest();
if ($request->getContentType() === 'json') {
$requestData = json_decode($request->getContent(), true);
if (!empty($requestData['remember_me']) && $requestData['remember_me']) {
$expiration = new \DateTime('+' . self::REMEMBER_ME_EXPIRATION_DAYS . ' days');
$data['exp'] = $expiration->getTimestamp();
}
}
}
private function addImpersonator(User $user, array &$data)
{
if (!is_null($user->getImpersonatorId())) {
$data['impersonator_id'] = $user->getImpersonatorId();
}
}
}