<?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 App\Controller\Frontend;
use App\Entity\Gos\LeadFormResponse;
use App\Entity\Gos\NewsletterTemplate;
use App\Entity\Gos\PasswordFromImport;
use App\Entity\Gos\PortalSettings;
use App\Entity\Gos\User;
use App\Utils\Email\SendMail;
use App\Utils\Encryption;
use App\Utils\SalesManago\SalesManagoEvent;
use App\Utils\SalesManago\v2\Action\Contact\Upsert\Events\SalesManagoUpsertEventsV2;
use App\Utils\SalesManago\v2\Action\SalesManagoEventDispatcher;
use App\Utils\UserServices;
use Doctrine\ORM\EntityManagerInterface;
use FOS\UserBundle\CompatibilityUtil;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\GetResponseNullableUserEvent;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\Form\Factory\FactoryInterface;
use FOS\UserBundle\Form\Type\ResettingFormType;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Mailer\MailerInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use FOS\UserBundle\Util\TokenGeneratorInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use FOS\UserBundle\Controller\ResettingController as FOSBaseController;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Environment;
use Twig\TemplateWrapper;
class FmResettingController extends FOSBaseController
{
private EventDispatcherInterface $eventDispatcher;
private FactoryInterface $formFactory;
private UserManagerInterface $userManager;
private TokenGeneratorInterface $tokenGenerator;
private MailerInterface $mailer;
private $retryTtl;
private ?Request $request;
private TranslatorInterface $translator;
private EntityManagerInterface $em;
private SalesManagoEvent $salesManagoEvent;
private UserServices $userServices;
private SendMail $sendMail;
private Environment $twig;
private Encryption $encryption;
private SalesManagoEventDispatcher $salesManagoEventDispatcher;
public function __construct(
EventDispatcherInterface $eventDispatcher,
FactoryInterface $formFactory,
UserManagerInterface $userManager,
TokenGeneratorInterface $tokenGenerator,
MailerInterface $mailer,
$retryTtl,
RequestStack $requestStack,
TranslatorInterface $translator,
EntityManagerInterface $em,
SalesManagoEvent $salesManagoEvent,
UserServices $userServices,
SendMail $sendMail,
Environment $twig,
Encryption $encryption,
SalesManagoEventDispatcher $salesManagoEventDispatcher
) {
$this->eventDispatcher = CompatibilityUtil::upgradeEventDispatcher($eventDispatcher);
$this->formFactory = $formFactory;
$this->userManager = $userManager;
$this->tokenGenerator = $tokenGenerator;
$this->mailer = $mailer;
$this->retryTtl = $retryTtl;
$this->request = $requestStack->getCurrentRequest();
$this->translator = $translator;
$this->em = $em;
$this->salesManagoEvent = $salesManagoEvent;
$this->userServices = $userServices;
$this->sendMail = $sendMail;
$this->twig = $twig;
$this->encryption = $encryption;
$this->salesManagoEventDispatcher = $salesManagoEventDispatcher;
parent::__construct($eventDispatcher, $formFactory, $userManager, $tokenGenerator, $mailer, $retryTtl);
}
/**
* Request reset user password: show form.
*/
public function requestAction(): Response
{
if ($this->request->attributes->get('_route') == 'eforum_reset')
{
return $this->render(sprintf('frontend-eforum/security/request.html.twig'));
}
if ($this->request->attributes->get('_route') == 'uniqskills_reset')
{
return $this->render(sprintf('uniqskills/security/request.html.twig'));
}
return $this->render('@FOSUser/Resetting/request.html.twig');
}
public function sendEmailAction(Request $request): Response
{
$username = $request->request->get('username');
$user = $this->userManager->findUserByUsernameOrEmail($username);
$event = new GetResponseNullableUserEvent($user, $request);
$this->eventDispatcher->dispatch($event,FOSUserEvents::RESETTING_SEND_EMAIL_INITIALIZE);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
if (null !== $user && !$user->isPasswordRequestNonExpired(30)) {
$event = new GetResponseUserEvent($user, $request);
$this->eventDispatcher->dispatch($event, FOSUserEvents::RESETTING_RESET_REQUEST);
if (null !== $event->getResponse())
{
if ($request->request->get('from_app'))
{
return $this->json([
'status' => false,
'message' => 'Email z kodem umożliwiającym zresetowanie hasła został już wysłany'
]);
}
elseif ($request->request->get('json_reset'))
{
return $this->json(['success' => true]);
}
return $event->getResponse();
}
if ($request->request->get('from_app'))
{
$user->setResettingCode(self::generateActivationCodeForApp());
}
elseif (null === $user->getConfirmationToken())
{
$user->setConfirmationToken($this->tokenGenerator->generateToken());
}
$event = new GetResponseUserEvent($user, $request);
$this->eventDispatcher->dispatch($event, FOSUserEvents::RESETTING_SEND_EMAIL_CONFIRM);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$this->mailer->sendResettingEmailMessage($user);
$user->setPasswordRequestedAt(new \DateTime());
$this->userManager->updateUser($user);
$event = new GetResponseUserEvent($user, $request);
$this->eventDispatcher->dispatch($event, FOSUserEvents::RESETTING_SEND_EMAIL_COMPLETED);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
}
if ($request->request->get('from_app'))
{
return $this->json([
'status' => true,
'message' => 'Wiadomość z kodem umożliwiającym zresetowanie hasła wysłana na podany adres email'
]);
}
if ($request->request->get('json_reset'))
{
return $this->json(['success' => true]);
}
if ($request->get('_route') == 'eforum_reset_sendmail')
{
return $this->redirectToRoute('eforum_reset_check', ['username' => $username]);
}
if ($request->get('_route') == 'uniqskills_reset_sendmail')
{
return $this->redirectToRoute('uniqskills_reset_check', ['username' => $username]);
}
if ($request->get('_route') === 'order_ajax_form_reset_sendmail')
{
return $this->json(['success' => true]);
}
return $this->redirectToRoute('fos_user_resetting_check_email', ['username' => $username]);
}
/**
* Tell the user to check his email provider.
*
* @param Request $request
*
* @return Response
*/
public function checkEmailAction(Request $request): Response
{
$origin = $request->getSession()->get('origin', 'default');
$username = $request->query->get('username');
$locale = $request->getSession()->get('userLocale', $request->getLocale());
if (empty($username))
{
// the user does not come from the sendEmail action
if ($origin == 'eforum')
{
return $this->redirectToRoute('eforum_reset');
}
elseif ($origin == 'uniqskills')
{
return $this->redirectToRoute('uniqskills_reset', ['_locale' => $locale]);
}
else
{
return $this->redirectToRoute('fos_user_resetting_request');
}
}
if ($origin == 'eforum')
{
$this->addFlash('success', 'resetting.reset.check_email');
return $this->redirectToRoute('eforum_reset');
}
elseif ($origin == 'uniqskills')
{
$message = $this->translator->trans(
'uniqskills.resetting.request.emailSent',
[],
'messages',
$locale
);
$this->addFlash('success', $message);
return $this->redirectToRoute('uniqskills_reset', ['_locale' => $locale]);
}
else
{
return $this->render('@FOSUser/Resetting/check_email.html.twig', [
'tokenLifetime' => 0
]);
}
}
/**
* Reset user password.
*
* @param Request $request
* @param string $token
*
* @return Response
*/
public function resetAction(Request $request, $token): Response
{
$origin = $request->attributes->get('_route');
$customMessage = '';
$hash = $request->getSession()->get('portalSettingsHash');
$portalSettings = $this->em->getRepository(PortalSettings::class)->findOneByHash($hash);
$isAjax = $request->request->get('isAjax');
$user = $this->userManager->findUserByConfirmationToken($token);
if (null === $user)
{
$this->addFlash(
'danger',
$this->translator->trans(
'errors.account.linkExpired',
[],
'messages',
$request->getSession()->get('userLocale', 'pl'))
);
if ($origin == 'eforum_reset_password')
{
return $this->redirectToRoute('eforum_reset');
}
elseif ($origin == 'uniqskills_reset_password')
{
return $this->redirectToRoute('uniqskills_reset');
}
return $this->redirectToRoute('fos_user_resetting_request');
}
$event = new GetResponseUserEvent($user, $request);
$this->eventDispatcher->dispatch($event, FOSUserEvents::RESETTING_RESET_INITIALIZE);
if (!$user->isEnabled())
{
$request->getSession()->set('firstActivation', 1);
$request->getSession()->set('registerBool', true);
$user->setEnabled(true);
$user->setActivationDate(new \DateTime());
$this->addFlash('success',
$this->translator->trans(
'messages.account.accountActivated',
[],
'messages',
$request->getSession()->get('userLocale', 'pl')
)
);
$gosUser = $this->em->getRepository(User::class)->find($user->getId());
$this->userServices->activateVouchersForUser($gosUser);
$gosUser->setAllowedAdvertising(true);
$this->em->persist($gosUser);
$this->salesManagoEvent->sendAllowedAdvertising($gosUser);
$this->salesManagoEventDispatcher->dispatchContactUpsert($gosUser, SalesManagoUpsertEventsV2::ON_ACTIVATION);
$this->userServices->sendUserLeadToDB($gosUser, $portalSettings, $user->getReginfo(), __METHOD__);
$this->em->flush();
}
if ($request->query->has('pdfArticleUrl')) {
return $this->render('frontend/article_pdf/after_register_content.html.twig', [
'pdfUrl' => $this->pdfResponseUrl($request->query->get('pdfArticleUrl'))
]);
}
if (null !== $event->getResponse())
{
return $event->getResponse();
}
$form = $this->createForm(ResettingFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid())
{
// user change password in gos - deactivate passwordFromImport
$register = false;
$passwordsFromImport = $this->em->getRepository(PasswordFromImport::class)
->findActivePasswordByUserEmail($user->getEmail());
foreach ($passwordsFromImport as $passwordFromImport)
{
$passwordFromImport->setIsActive(false);
$this->em->persist($passwordFromImport);
}
$firstActivation = 0;
$otpNetflix = false;
if ($request->getSession()->has('firstActivation'))
{
$firstActivation = 1;
}
if ($request->getSession()->has('registerBool'))
{
$register = true;
}
if ($request->getSession()->has('otpNetflix'))
{
$otpNetflix = true;
}
$this->em->flush();
$event = new FormEvent($form, $request);
$this->eventDispatcher->dispatch($event, FOSUserEvents::RESETTING_RESET_SUCCESS);
$this->userManager->updateUser($user);
$request->getSession()->remove('otpRoute');
if ($otpNetflix)
{
return $this->redirectToRoute('fmOneTimePasswordRegisterConfirmation');
}
if ($origin == 'eforum_reset_password')
{
$this->addFlash('success',
$this->translator->trans(
'messages.account.passwordChanged',
[],
'messages',
$request->getSession()->get('userLocale', 'pl')
)
);
if ($register)
{
return $this->redirectToRoute('eforum_login', [
'gaEvent' => 'accountCreate',
'fa' => $firstActivation
]);
}
return $this->redirectToRoute('eforum_login');
}
elseif ($origin == 'uniqskills_reset_password')
{
$this->addFlash('success', 'messages.account.passwordChanged');
if ($register)
{
return $this->redirectToRoute('uniqskills_login', [
'gaEvent' => 'accountCreate',
'fa' => $firstActivation
]);
}
return $this->redirectToRoute('uniqskills_login');
}
if ($request->query->get('gos'))
{
return $this->redirectToRoute('backend_login');
}
if ($register)
{
return $this->redirectToRoute('fos_user_security_login', [
'gaEvent' => 'accountCreate',
'fa' => $firstActivation
]);
}
if ($user->getCart() && count($user->getCart()->getProductCart()) > 0)
{
$event->setResponse($this->redirectToRoute('fmOrderUserBase'));
}
if (null === $response = $event->getResponse())
{
$response = new RedirectResponse($this->redirectToRoute('fos_user_profile_show'));
}
return $response;
}
if ($origin == 'eforum_reset_password')
{
$template = '/frontend-eforum/security/reset.html.twig';
}
elseif ($origin == 'uniqskills_reset_password')
{
$template = '/uniqskills/security/reset.html.twig';
}
elseif ($request->getSession()->get('otpRoute') !== null || $request->query->get('otpRoute') !== null)
{
if ($request->getSession()->get('otpRoute') === null)
{
$request->getSession()->set('otpRoute', $request->query->get('otpRoute'));
}
$otpRoute = $request->getSession()->get('otpRoute');
$leadIndex = strpos($otpRoute, 'leadTemplate');
$newsletterIndex = strpos($otpRoute, 'newsletterTemplate');
if ($leadIndex !== false)
{
$id = intval(substr($otpRoute, $leadIndex + strlen('leadTemplate')));
$leadTemplate = $this->em->getRepository(LeadFormResponse::class)->find($id);
if ($leadTemplate instanceof LeadFormResponse)
{
$customMessage = $leadTemplate->getNewAccountBodyResponse();
if ($leadTemplate->isEnglish()) {
$translator->setLocale('en');
}
}
$template = 'frontend/one_time_password/new_password.html.twig';
}
elseif ($newsletterIndex !== false)
{
$id = intval(substr($otpRoute, $newsletterIndex + strlen('newsletterTemplate')));
$newsletterTemplate = $this->em->getRepository(NewsletterTemplate::class)->find($id);
if ($newsletterTemplate instanceof NewsletterTemplate)
{
$customMessage = $newsletterTemplate->getMessageConfirmedNewUser();
if($newsletterTemplate->getIsFileNewsletter() && $newsletterTemplate->getGratisFilename())
{
$gratisLink = $_ENV['GOS_URL_HTTPS'].$this->generateUrl('fmNewsletterGratis',
['gratisFilename' => $newsletterTemplate->getGratisFilename()]);
$customMessage = str_replace('GRATIS_URL', $gratisLink, $customMessage);
}
}
$template = 'frontend/one_time_password/new_password.html.twig';
}
else
{
$template = '@FOSUser/Resetting/reset.html.twig';
}
}
else
{
$template = '@FOSUser/Resetting/reset.html.twig';
}
if ($isAjax)
{
/** @var TemplateWrapper $template */
$template = $this->twig->load($template);
$content = $template->renderBlock('content', [
'token' => $token,
'form' => $form->createView(),
'active' => $user->isEnabled(),
'isGOS' => $request->query->get('gos') ? 1 : 0,
'customMessage' => $customMessage,
'portalSettings'=> $portalSettings,
]);
if ($template->hasBlock('customjs'))
{
$content .= $template->renderBlock('customjs');
}
$response = new Response();
$response->setContent($content);
return $response;
}
return $this->render($template, array(
'token' => $token,
'form' => $form->createView(),
'active' => $user->isEnabled(),
'isGOS' => $request->query->get('gos') ? 1 : 0,
'customMessage' => $customMessage,
'portalSettings'=> $portalSettings,
));
}
/**
* @param string $url
* @return string
*/
private function pdfResponseUrl(string $url): string
{
$url = parse_url($url);
$path = $url['path'] . '/pdf';
$scheme = str_replace('http', 'https', $url['scheme']);
$host = $url['host'];
$query = isset($url['query']) ? '?' . $url['query'] : '';
return $scheme . '://' . $host . $path . $query;
}
/**
* @Route("/reset-activation-code", name="fmUserResetActivationCode")
*/
public function sendAgainConfirmationCodeAction(Request $request): JsonResponse
{
$data = $request->query->get('data');
$token = $request->query->get('publicToken');
$userToken = $this->encryption->decrypt($data, $token);
$locale = $request->getSession()->get('userLocale', 'pl');
$portalSetting = $this->em->getRepository(PortalSettings::class)
->findOneByHash('44e1391ae50ee1dbb0ba3f6349b837');
/** @var User $user */
$user = $this->em->getRepository(User::class)->findOneBy(['token' => $userToken]);
if ($user)
{
if (!$user->isEnabled())
{
$user->setActivationCode(self::generateActivationCodeForApp());
$this->em->flush();
$status = $this->sendMail->sendMail(
'account_reset_activation_code',
$user->getEmail(),
['user' => $user],
$portalSetting->getHash(),
false,
$locale
);
if ($status)
{
return $this->json([
'status' => true,
'message' => 'Email z nowym kodem aktywacyjnym został wysłany'
]);
}
else
{
return $this->json([
'status' => false,
'message' => 'Nie udało się wysłać maila'
]);
}
}
else
{
return $this->json([
'status' => false,
'enabled' => false,
'message' => 'Użytkownik był już aktywny'
]);
}
}
return $this->json([
'status' => false,
'message' => 'Nie udało się wysłać maila'
]);
}
private static function generateActivationCodeForApp($digits = 6): string
{
return str_pad(rand(0, pow(10, $digits)-1), $digits, '0', STR_PAD_LEFT);
}
}