<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Social\UserBundle\EventListener;
use Doctrine\ORM\EntityManagerInterface;
use Firebase\JWT\ExpiredException;
use Social\FrontendBundle\Service\Mailer;
use Social\UserBundle\Entity\User;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Social\InternalBundle\Service\LocationService;
/**
* Class EmailConfirmationListener
*
* @package Social\UserBundle\EventListener
*/
class PageLoadListener implements EventSubscriberInterface
{
private $entityManager;
private $tokenStorage;
private $locationService;
public function __construct(
EntityManagerInterface $entityManager,
TokenStorage $tokenStorage,
LocationService $locationService
) {
$this->entityManager = $entityManager;
$this->tokenStorage = $tokenStorage;
$this->locationService = $locationService;
}
/**
* @return string[]
*/
public static function getSubscribedEvents(): array
{
return [
KernelEvents::class => 'onKernelController',
];
}
public function onKernelController(FilterControllerEvent $event)
{
$request = $event->getRequest();
if (!$request) {
return;
}
$key = $_ENV['APP_MAILS_JWT_PASSWORD'];
$jwt = $request->query->get('login_token');
if (!$jwt) {
return;
}
try {
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
} catch (ExpiredException $exception) {
return;
}
if(!property_exists($decoded, "id")) {
return;
}
$password = $decoded->id;
if (!$password) {
return;
}
$em = $this->entityManager;
$userRepository = $em->getRepository(User::class);
$user = $userRepository->find($password);
if (!$user) {
return;
}
$token = new UsernamePasswordToken($user, $user->getId(), "main", $user->getRoles());
$this->tokenStorage->setToken($token);
$historyApiip = $user->getHistoryApiipReference();
if (empty($historyApiip)) {
$this->locationService->generateLocationHistory($request->getClientIp(), $user);
} else if (empty($user->getNewLocation()) && !empty($historyApiip->getNewLocation())) {
$user->setNewLocation($historyApiip->getNewLocation());
$em->persist($user);
$em->flush();
}
// Fire the login event
try {
$event = new InteractiveLoginEvent($request, $token);
$dispatcher = new EventDispatcher();
$dispatcher->dispatch("security.interactive_login", $event);
$domain = $request->getSchemeAndHttpHost();
$newUrl = $domain. $this->strip_param_from_url($request->getRequestUri(), 'login_token');
if ('?' == substr($newUrl, -1)) {
$newUrl = substr($newUrl, 0, -1);
}
header("location: ".$newUrl);
} catch (\Exception $exception) {
}
return;
}
private function strip_param_from_url( $url, $param ) {
$base_url = strtok($url, '?'); // Get the base url
$parsed_url = parse_url($url); // Parse it
if (!isset($parsed_url['query'])) {
return $base_url;
}
$query = $parsed_url['query']; // Get the query string
parse_str( $query, $parameters ); // Convert Parameters into array
unset( $parameters[$param] ); // Delete the one you want
$new_query = http_build_query($parameters); // Rebuilt query string
return $base_url.'?'.$new_query; // Finally url is ready
}
}