<?php
namespace App\Controller;
use App\Entity\User;
use App\Form\{ForgotPasswordType, ResetPasswordType};
use App\Repository\UserRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\{Request, Response};
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
class SecurityController extends AbstractController
{
#[Route(path: '/login', name: 'app_login')]
public function login(AuthenticationUtils $helper): Response
{
$this->redirectLoggedInUsers();
return $this->render('security/login.html.twig', [
'last_username' => $helper->getLastUsername(),
'error' => $helper->getLastAuthenticationError()
]);
}
#[Route(path: '/logout', name: 'app_logout', methods: ['GET'])]
public function logout(): void
{
}
#[Route(path: '/forgot-password', name: 'app_forgot')]
public function forgotPassword(Request $request, UserRepository $userRepo, EntityManagerInterface $entityManager): Response
{
$this->redirectLoggedInUsers();
if ($request->isMethod('POST')) {
$token = $request->request->get('g-recaptcha-response');
$responses = $this->verifyGoogleRecaptcha($token);
if (!$responses['success']) {
throw new UserNotFoundException();
}
}
$form = $this->createForm(ForgotPasswordType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user = $userRepo->findOneByEmail($form->get('email')->getData());
if (!$user) {
$this->addFlash('success', 'An email with a link reset password is your email address!');
return $this->redirectToRoute('app_login');
}
$user->setToken(bin2hex(random_bytes(32)));
$entityManager->persist($user);
$entityManager->flush();
$link = $this->generateUrl('user_reset_password', ['token' => $user->getToken()], UrlGeneratorInterface::ABSOLUTE_URL);
$html = '';
$html .= "<html>";
$html .= "<body style='background-color:#ffffff;color:black;font-family:Arial, 'Helvetica Neue',Helvetica, sans-serif;font-size: 13px;'>";
$html .= "Click <a href='" . $link . "' target='_blank'>here</a> to reset your password. This link is valid for 5 minutes.</body>";
$html .= "</html>";
$arrParams = '{"personalizations":[{"to":[{"email":"' . $form->get('email')->getData() . '"}],"subject":"Hospital Management System - Reset Password"}],"content": [{"type": "text/html charset=utf-8", "value": "' . $html . '"}],"from":{"email":"' . $_ENV['EMAIL_NOREPLY'] . '",
"name":"' . $_ENV['EMAIL_FROM_NAME'] . '"}}';
$endpoint = $_ENV['CNMGTS_API_MAIL_URL'];
$APItoken = 'Bearer ' . $_ENV['CNMGTS_API_MAIL_PASSWORD'];
$ch = @curl_init();
@curl_setopt($ch, CURLOPT_POST, true);
@curl_setopt($ch, CURLOPT_POSTFIELDS, $arrParams);
@curl_setopt($ch, CURLOPT_URL, $endpoint);
@curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization:' . $APItoken,
'Content-Type: application/json',
));
@curl_setopt($ch, CURLOPT_TIMEOUT, 400);
@curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = @curl_exec($ch); //Log the response from HubSpot as needed.
@curl_close($ch);
if ($response) {
$this->addFlash('error', 'Please try again');
return $this->redirectToRoute('app_forgot');
} else {
$this->addFlash('success', 'An email with a link reset password is your email address!');
return $this->redirectToRoute('app_login');
}
}
return $this->renderForm('security/forgot.html.twig', [
'form' => $form
]);
}
#[Route(path: '/reset-password/{token}', name: 'user_reset_password')]
public function resetPassword(Request $request, User $user, string $token, UserPasswordHasherInterface $hasher, UserRepository $userRepo, EntityManagerInterface $entityManager): Response
{
$this->redirectLoggedInUsers();
$user = $userRepo->findOneBy(['token' => $token, 'isActive' => true]);
$form = $this->createForm(ResetPasswordType::class, $user);
$form->handleRequest($request);
if ($user) {
$getDate = $userRepo->ExpiryToken($token);
$newTime = date('Y-m-d H:i:s', strtotime('+5 minutes', strtotime($getDate)));
$time = time();
if ($time > strtotime($newTime)) {
$this->addFlash('danger', 'Link expired! Please try again.');
return $this->redirectToRoute('app_forgot');
} else {
if ($form->isSubmitted() && $form->isValid()) {
$first = $request->request->get('reset_password')['password']['first'];
$second = $request->request->get('reset_password')['password']['second'];
$formData = $form->getData();
$newPassword = $user->getPassword();
if (empty($first) && empty($second)) {
return $this->renderForm('security/reset.html.twig', [
'form' => $form,
'error' => 'Password is required'
]);
}
if (preg_match('/^(?=.*\d)(?=.*[@#\-_$%^&+=§!\?])(?=.*[a-z])(?=.*[A-Z])[0-9A-Za-z@#\-_$%^&+=§!\?]{8,20}$/', $user->getPassword())) {
if ($user->getPasswordMd5() != '' && $user->getPasswordMd5() == md5($newPassword)) {
return $this->renderForm('security/reset.html.twig', [
'form' => $form,
'error' => 'Password should not be older password. please try again'
]);
} elseif ($user->getPasswordOld1() != '' && ($user->getPasswordOld1() == md5($newPassword))) {
return $this->renderForm('security/reset.html.twig', [
'form' => $form,
'error' => 'Password should not be older password. please try again'
]);
} elseif ($user->getPasswordOld2() != '' && $user->getPasswordOld2() == md5($newPassword)) {
return $this->renderForm('security/reset.html.twig', [
'form' => $form,
'error' => 'Password should not be older password. please try again'
]);
} else {
$userRepo->UpdatePassword1($user->getPasswordMd5(), $user->getId());
$userRepo->UpdatePassword2($user->getPasswordOld1(), $user->getId());
$userRepo->UpdatePassword3($user->getPasswordOld2(), $user->getId());
$user->setPassword($hasher->hashPassword($user, $newPassword));;
$user->setPasswordMd5(md5($newPassword));
$user->setToken(null);
$entityManager->persist($user);
$entityManager->flush();
$this->addFlash('success', 'Password updated successfully!');
return $this->redirectToRoute('app_login');
}
} else {
return $this->renderForm('security/reset.html.twig', [
'form' => $form,
'error' => 'Password is not valid. please try again'
]);
}
} else {
return $this->renderForm('security/reset.html.twig', [
'form' => $form,
'error' => ''
]);
}
}
}
return $this->redirectToRoute('app_forgot');
}
private function redirectLoggedInUsers()
{
if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
return $this->redirectToRoute('dashboard');
}
}
public function verifyGoogleRecaptcha($token)
{
$ip2020 = "";
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip2020 = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip2020 = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip2020 = $_SERVER['REMOTE_ADDR'];
}
$endpoint = 'https://www.google.com/recaptcha/api/siteverify';
$secretKey = $_ENV['GOOGLE_RECAPTCHA_SECRET_KEY'];
$arrParams = "secret=$secretKey" . "&response=$token" . "&remoteip=$ip2020";
$ch = @curl_init();
@curl_setopt($ch, CURLOPT_POST, true);
@curl_setopt($ch, CURLOPT_POSTFIELDS, $arrParams);
@curl_setopt($ch, CURLOPT_URL, $endpoint);
@curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/x-www-form-urlencoded'
));
@curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = @curl_exec($ch); //Log the response from HubSpot as needed.
@curl_close($ch);
return json_decode($response, true);
}
}