<?php
namespace App\Controller;
use App\Entity\User;
use App\Form\RegistrationFormType;
use App\Form\RequestResetPasswordType;
use App\Form\ResetPasswordType;
use App\Form\Model\RequestResetPasswordData;
use App\Form\Model\ResetPasswordData;
use App\Security\AppCustomAuthenticator;
use App\Security\EmailVerifier;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Mime\Address;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\UserAuthenticatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use SymfonyCasts\Bundle\VerifyEmail\Exception\VerifyEmailExceptionInterface;
use GuzzleHttp\Client;
use App\Repository\UserRepository;
use App\Model\Common;
class RegistrationController extends AbstractController
{
private EmailVerifier $emailVerifier;
public function __construct(EmailVerifier $emailVerifier, UserRepository $userRepository)
{
$this->userRepository = $userRepository;
$this->emailVerifier = $emailVerifier;
}
#[Route('/register', name: 'app_register')]
public function register(Request $request, UserPasswordHasherInterface $userPasswordHasher, UserAuthenticatorInterface $userAuthenticator, AppCustomAuthenticator $authenticator, EntityManagerInterface $entityManager): Response
{
$user = new User();
$common = new Common();
$form = $this->createForm(RegistrationFormType::class, $user);
$form->handleRequest($request);
$recaptcha_site_key = $this->getParameter("recaptcha_site_key");
$recaptcha_secret_key = $this->getParameter("recaptcha_secret_key");
$site_url = $this->getParameter("site_url");
if ($form->isSubmitted() && $form->isValid()) {
// encode the plain password
$recaptchaResponse = $request->request->get('g-recaptcha-response');
$client = new Client();
$response = $client->post('https://www.google.com/recaptcha/api/siteverify', [
'form_params' => [
'secret' => $recaptcha_secret_key,
'response' => $recaptchaResponse
]
]);
$responseData = json_decode($response->getBody(), true);
if ($responseData['success']) {
// ... continue with user registration
$token = bin2hex(random_bytes(16));
$user->setToken($token);
$user->setPassword(
$userPasswordHasher->hashPassword(
$user,
$form->get('plainPassword')->getData()
)
);
$user->setNumberOfEmailSent(1);
$entityManager->persist($user);
$entityManager->flush();
$common->sendEmail($user->getEmail(),"Confirm email", $this->render('admin/registration/confirmation_email.html.twig', [ 'signedUrl' => $site_url . "login/" . $token]));
$messageCode = "ok";
} else {
$messageCode = "error_recpacha";
// ... handle invalid reCAPTCHA response
}
return $this->render('admin/registration/verification.html.twig', [
'user' => $user,
'message_code' => $messageCode
]);
/*
return $userAuthenticator->authenticateUser(
$user,
$authenticator,
$request
);
*/
}
return $this->render('admin/registration/register.html.twig', [
'registrationForm' => $form->createView(),
'recaptcha_site_key' => $recaptcha_site_key
]);
}
#[Route('/verify/email', name: 'app_verify_email')]
public function verifyUserEmail(Request $request, TranslatorInterface $translator): Response
{
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
// validate email confirmation link, sets User::isVerified=true and persists
try {
$this->emailVerifier->handleEmailConfirmation($request, $this->getUser());
} catch (VerifyEmailExceptionInterface $exception) {
$this->addFlash('verify_email_error', $translator->trans($exception->getReason(), [], 'VerifyEmailBundle'));
return $this->redirectToRoute('app_register');
}
// @TODO Change the redirect on success and handle or remove the flash message in your templates
$this->addFlash('success', 'Your email address has been verified.');
return $this->redirectToRoute('app_register');
}
#[Route('/reset-password', name: 'app_request_reset_password')]
public function requestResetPassword(Request $request, UserPasswordHasherInterface $userPasswordHasher, UserAuthenticatorInterface $userAuthenticator, AppCustomAuthenticator $authenticator, EntityManagerInterface $entityManager): Response
{
$success = null;
$customError = null;
$user = new User();
$resetPasswordData = new RequestResetPasswordData();
$common = new Common();
$form = $this->createForm(RequestResetPasswordType::class, $resetPasswordData);
$form->handleRequest($request);
$recaptcha_site_key = $this->getParameter("recaptcha_site_key");
$recaptcha_secret_key = $this->getParameter("recaptcha_secret_key");
$site_url = $this->getParameter("site_url");
if ($form->isSubmitted() && $form->isValid()) {
// encode the plain password
$recaptchaResponse = $request->request->get('g-recaptcha-response');
$client = new Client();
$response = $client->post('https://www.google.com/recaptcha/api/siteverify', [
'form_params' => [
'secret' => $recaptcha_secret_key,
'response' => $recaptchaResponse
]
]);
$responseData = json_decode($response->getBody(), true);
if ($responseData['success']) {
// ... continue with user registration
$email = $resetPasswordData->email;
$user = $this->userRepository->findOneByEmail($email);
if ($user) {
$token = bin2hex(random_bytes(16));
$user->setToken($token);
$entityManager->persist($user);
$entityManager->flush();
$common->sendEmail($user->getEmail(),"Reset password", $this->render('admin/registration/password_email.html.twig', [ 'signedUrl' => $site_url . "reset-password/" . $token]));
$success = "Check your mailbox to complete.";
} else {
$customError = "Email doesn't exists. Please register.";
}
} else {
$customError = "Google says You are a robot.";
}
}
return $this->render('admin/registration/request-reset-password.html.twig', [
'requestResetPasswordForm' => $form->createView(),
'recaptcha_site_key' => $recaptcha_site_key,
'success' => $success,
'custom_error' => $customError
]);
}
#[Route('/reset-password/{token}', name: 'app_reset_password')]
public function resetPassword(string $token, Request $request, UserPasswordHasherInterface $userPasswordHasher, UserAuthenticatorInterface $userAuthenticator, AppCustomAuthenticator $authenticator, EntityManagerInterface $entityManager): Response
{
$success = null;
$customError = null;
$user = $this->userRepository->findOneByToken($token);
if ($user) {
$resetPasswordData = new ResetPasswordData();
$common = new Common();
$form = $this->createForm(ResetPasswordType::class, $resetPasswordData);
$form->handleRequest($request);
$recaptcha_site_key = $this->getParameter("recaptcha_site_key");
$recaptcha_secret_key = $this->getParameter("recaptcha_secret_key");
$site_url = $this->getParameter("site_url");
if ($form->isSubmitted() && $form->isValid()) {
// encode the plain password
$recaptchaResponse = $request->request->get('g-recaptcha-response');
$client = new Client();
$response = $client->post('https://www.google.com/recaptcha/api/siteverify', [
'form_params' => [
'secret' => $recaptcha_secret_key,
'response' => $recaptchaResponse
]
]);
$responseData = json_decode($response->getBody(), true);
if ($responseData['success']) {
// ... continue with user registration
$password = $form->getData()->getPassword();
$confirmPassword = $form->getData()->getConfirmPassword();
if($password == $confirmPassword) {
$user->setPassword(
$userPasswordHasher->hashPassword(
$user,
$password
)
);
$user->setToken("");
$entityManager->persist($user);
$entityManager->flush();
$success = "Password changed";
} else {
$customError = "Passwords does not match.";
}
} else {
$customError = "Google says You are a robot.";
}
}
return $this->render('admin/registration/reset-password.html.twig', [
'resetPasswordForm' => $form->createView(),
'recaptcha_site_key' => $recaptcha_site_key,
'success' => $success,
'custom_error' => $customError
]);
} else { // Nie ma usera z tokenem
throw $this->createNotFoundException('The requested page was not found.');
}
}
}