<?php
namespace JF\JuridicusBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use JF\JuridicusBundle\Entity\Email;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use JF\JuridicusBundle\Entity\User;
use JF\JuridicusBundle\Entity\MailTemplate;
use Swift_Mailer;
use Swift_Message;
use Psr\Log\LoggerInterface;
use JF\JuridicusBundle\Services\Sms;
/**
* Controller managing the resetting of the password
*
* @Route("/reset_password")
*/
class ResettingController extends AbstractController
{
private int $tokenTtl = 86400;
public function __construct(
private EntityManagerInterface $em,
private UserPasswordHasherInterface $passwordHasher,
private Swift_Mailer $mailer,
private Sms $smsService,
private LoggerInterface $logger ) {
}
/**
* Request reset user password: show form
*
* @Route("/request", name="reset_password_request")
* @Template("@JFJuridicusBundle/Resetting/request.html.twig")
*/
public function requestAction()
{
return array();
}
/**
* Request reset user password: submit form and send email
*
* @Route("/send_email", name="reset_password_send_email")
* @Method({"POST"})
* @Template("@JFJuridicusBundle/Resetting/request.html.twig")
*/
public function sendEmailAction(Request $request)
{
$username = $request->request->get('username');
$user = $this->em->getRepository(User::class)->findOneBy(['username' => $username]);
if (null === $user) {
// Back To Form
return array('invalid_username' => $username);
}
$kunde = $user->getKunde();
if (null === $kunde) {
// Back To Form
return array('invalid_username' => $username);
}
if ($user->isPasswordRequestNonExpired($this->tokenTtl)) {
return $this->render('@JFJuridicusBundle/Resetting/password_already_requested.html.twig');
}
$token = $user->getConfirmationToken();
if (null === $token) {
$token = uniqid(md5(rand()));
$user->setConfirmationToken($token);
}
$user->setPasswordRequestedAt(new \DateTimeImmutable());
$this->em->persist($user);
$this->em->flush();
$link = $this->generateUrl('reset_password_activate', array('token' => $token), UrlGeneratorInterface::ABSOLUTE_URL); //changedFrom true
// finde neuestes Template -> TODO
$template = $this->em->getRepository(MailTemplate::class)->findCurrentByTyp(Email::RESETTING);
$replacements = array(
'vorname' => $kunde->getVorname(),
'nachname' => $kunde->getNachname(),
'email' => $kunde->getEmail(),
'handynummer' => $kunde->getHandynummer(),
'link' => $link
);
$this->logger->error(sprintf('Linka: %s ', $link));
$mailerBcc = $this->getParameter('mailer_bcc');
$mailUser = $this->getParameter('mailer_user');
$message = (new Swift_Message($template->getBetreff()))
->setFrom(array($mailUser => 'Juridicus'))
->setReplyTo('info@juridicus.de')
->setTo($kunde->getEmail())
->setBody($template->replace($replacements), 'text/html')
;
if (isset($mailerBcc)) {
$message->setBcc(array($mailerBcc));
}
$failedRecipients = [];
$result = $this->mailer->send($message, $failedRecipients);
$this->logger->error('Mail debug', [
'to' => $kunde->getEmail(),
'from' => $mailUser,
'subject' => $template->getBetreff(),
'result' => $result,
'failedRecipients' => $failedRecipients,
]);
if ( $result) {
// Versand speichern
$email = new Email();
$email
->setTyp(Email::RESETTING)
->setKunde($kunde)
;
$this->em->persist($email);
$this->container->get('session')->set('reset_password_email_success', $kunde->getEmail());
return $this->redirect($this->generateUrl('reset_password_email_success'));
} else {
$this->container->get('session')->set('reset_password_email_success', $kunde->getEmail());
return $this->redirect($this->generateUrl('reset_password_email_error'));
}
}
/**
* Reset user password and send sms
*
* @Route("/activate/{token}", name="reset_password_activate")
* @param string $token
* @return \Symfony\Component\HttpFoundation\Response
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
public function resetAction($token)
{
/* @var $session Symfony\Component\HttpFoundation\Session */
$session = $this->container->get('session');
$user = $this->em->getRepository(User::class)->findOneBy(['confirmationToken' => $token]);
if (null === $user) {
throw $this->createNotFoundException('Der Resetcode existiert nicht.');
}
$kunde = $user->getKunde();
if (null === $kunde) {
throw $this->createNotFoundException('Der Benutzer zum Resetcode existiert nicht.');
}
if (!$user->isPasswordRequestNonExpired($this->tokenTtl)) {
return $this->redirect($this->generateUrl('password_reset_request'));
}
$password_plain = substr(uniqid(md5(rand())), 8, 8);
$hashedPassword = $this->passwordHasher->hashPassword(
$user,
$password_plain
);
$this->logger->error(sprintf('Password: %s ', $password_plain));
$user->setConfirmationToken(null);
$user->setPlainPassword($password_plain);
$user->setPassword($hashedPassword);
$user->setPasswordRequestedAt(null);
$user->setEnabled(true);
$this->em->persist($user);
$this->em->flush();
// Senden des Passwords per SMS
$template = $this->em->getRepository(MailTemplate::class)->findCurrentByTyp(Email::SMS_RESETTING);
$replacements = array(
'vorname' => $kunde->getVorname(),
'nachname' => $kunde->getNachname(),
'email' => $kunde->getEmail(),
'handynummer' => $kunde->getHandynummer(),
'password' => $password_plain
);
if ($this->smsService->send(
html_entity_decode(strip_tags($template->replace($replacements))), $kunde->getHandynummer())
)
{
$kunde->setSmsSendAt(new \DateTime());
$this->em->persist($kunde);
$this->em->flush();
$session->set('reset_password_sms_success', $kunde->getEmail());
return $this->redirect($this->generateUrl('reset_password_sms_success'));
} else {
$session->set('reset_password_sms_error', $kunde->getEmail());
return $this->redirect($this->generateUrl('reset_password_sms_error'));
}
}
/**
* Tell the user to check his email provider
*
* @Route("/email/success", name="reset_password_email_success")
* @Template("@JFJuridicusBundle/Resetting/email_success.html.twig")
*/
public function emailSuccessAction()
{
$session = $this->container->get('session');
$email = $session->get('reset_password_email_success');
$session->remove('reset_password_email_success');
if (empty($email)) {
// the user does not come from the sendEmail action
return $this->redirect($this->generateUrl('reset_password_request'));
}
return array(
'kunde' => $this->em->getRepository(User::class)->findOneBy(['email' => $email])->getKunde()
);
}
/**
* Tell the user that email sending failed
*
* @Route("/email/error", name="reset_password_email_error")
* @Template("@JFJuridicusBundle/Resetting/email_error.html.twig")
*/
public function emailErrorAction()
{
$session = $this->container->get('session');
$email = $session->get('reset_password_email_error');
$session->remove('reset_password_email_error');
if (empty($email)) {
// the user does not come from the sendEmail action
return $this->redirect($this->generateUrl('reset_password_request'));
}
return array(
'kunde' => $this->em->getRepository(User::class)->findOneBy(['email' => $email])->getKunde()
);
}
/**
* Tell the user to check his sms
*
* @Route("/sms/success", name="reset_password_sms_success")
* @Template("@JFJuridicusBundle/Resetting/sms_success.html.twig")
*/
public function smsSuccessAction()
{
$session = $this->container->get('session');
$email = $session->get('reset_password_sms_success');
$session->remove('reset_password_sms_success');
if (empty($email)) {
// the user does not come from the sendEmail action
return $this->redirect($this->generateUrl('reset_password_request'));
}
return array(
'kunde' => $this->em->getRepository(User::class)->findOneBy(['email' => $email])->getKunde()
);
}
/**
* Tell the user that sms sending failed
*
* @Route("/sms/error", name="reset_password_sms_error")
* @Template("@JFJuridicusBundle/Resetting/sms_error.html.twig")
*/
public function smsErrorAction()
{
$session = $this->container->get('session');
$email = $session->get('reset_password_sms_error');
$session->remove('reset_password_sms_error');
if (empty($email)) {
// the user does not come from the sendSms action
return $this->redirect($this->generateUrl('reset_password_request'));
}
return array(
'kunde' => $this->em->getRepository(User::class)->findOneBy(['email' => $email])->getKunde()
);
}
}