<?php
namespace App\Controller\Website\Auth;
use App\Controller\Website\ThemeRenderController;
use App\Entity\Generic\Customer\Customer;
use App\Form\Website\NewPasswordType;
use App\Form\Website\ResetPasswordSmsRequestFormType;
use App\Form\Website\VerifySmsCodeType;
use App\Security\Authenticator\CustomerAuthenticator;
use App\Service\SmsHandler;
use App\Service\WebsiteManager;
use App\Service\Util\Sms;
use Doctrine\ORM\EntityManagerInterface;
use LogicException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Http\Authentication\UserAuthenticatorInterface;
class SecurityController extends ThemeRenderController
{
#[Route(path: '/website-panel/login', name: 'customer_panel_login')]
public function login(AuthenticationUtils $authenticationUtils, WebsiteManager $shopManager): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('customer_panel_user_handler');
}
$error = $authenticationUtils->getLastAuthenticationError();
$lastUsername = $authenticationUtils->getLastUsername();
return $this->renderUserTemplate('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}
#[Route(path: '/website-panel/user-handler', name: 'customer_panel_user_handler')]
public function userHandler(Security $security): RedirectResponse
{
$user = $security->getUser();
if ($user->hasRole('ROLE_ADMIN')) {
return $this->redirectToRoute('shop_customer_panel_admin_dashboard');
}
return $this->redirectToRoute('shop_customer_panel_dashboard');
}
#[Route(path: '/website-panel/logout', name: 'shop_owner_logout')]
public function logout(): void
{
throw new LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
}
#[Route('/forgot-password/sms', name: 'app_forgot_password_sms')]
public function requestSmsReset(
Request $request,
EntityManagerInterface $em,
SmsHandler $smsSender,
TokenGeneratorInterface $tokenGenerator,
): Response
{
$form = $this->createForm(ResetPasswordSmsRequestFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$phone = $form->get('phoneNumber')->getData();
$user = $em->getRepository(Customer::class)->findOneBy(['mobile' => $phone]);
if ($user) {
$code = random_int(100000, 999999);
$user->setVerifyCode($code);
$user->setPasswordResetAt(new \DateTime());
$em->flush();
$smsSender->sendCode($phone, $code);
}
$this->addFlash('success', 'در صورت ثبت شماره صحیح، کدی برای شما ارسال خواهد شد');
return $this->redirectToRoute('app_verify_sms_code');
}
return $this->renderUserTemplate('security/request_sms_reset.html.twig', [
'form' => $form->createView(),
]);
}
#[Route('/forgot-password/sms/verify', name: 'app_verify_sms_code')]
public function verifyCode(
Request $request,
EntityManagerInterface $em,
UrlGeneratorInterface $urlGenerator,
SessionInterface $session
): Response
{
$form = $this->createForm(VerifySmsCodeType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$phone = $form->get('phoneNumber')->getData();
$code = $form->get('code')->getData();
$user = $em->getRepository(Customer::class)->findOneBy(['mobile' => $phone, 'verifyCode' => $code]);
if ($user && $user->getPasswordResetAt() > (new \DateTime('-10 minutes'))) {
// ذخیره موقتی کاربر برای مرحله بعدی
$session->set('reset_user_id', $user->getId());
return $this->redirectToRoute('app_reset_password_form');
}
$this->addFlash('danger', 'کد وارد شده صحیح نیست یا منقضی شده');
}
return $this->renderUserTemplate('security/verify_sms_code.html.twig', [
'form' => $form->createView(),
]);
}
#[Route('/forgot-password/sms/reset', name: 'app_reset_password_form')]
public function resetPassword(
Request $request,
EntityManagerInterface $em,
UserPasswordHasherInterface $hasher,
SessionInterface $session
): Response
{
$userId = $session->get('reset_user_id');
if (!$userId) {
return $this->redirectToRoute('app_forgot_password_sms');
}
$user = $em->getRepository(Customer::class)->find($userId);
if (!$user) {
return $this->redirectToRoute('app_forgot_password_sms');
}
$form = $this->createForm(NewPasswordType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$password = $form->get('newPassword')->getData();
$user->setPassword($hasher->hashPassword($user, $password));
$user->setVerifyCode(null);
$user->setPasswordResetAt(null);
$em->flush();
$session->remove('reset_user_id');
$this->addFlash('success', 'رمز عبور با موفقیت تغییر کرد');
return $this->redirectToRoute('customer_panel_login');
}
return $this->renderUserTemplate('security/reset_password.html.twig', [
'form' => $form->createView(),
]);
}
#[Route('/streight-login/{id}', name: 'app_website_streight_login')]
public function app_website_streight_login(
Customer $customer = null,
Request $request,
UserAuthenticatorInterface $userAuthenticator,
CustomerAuthenticator $customerAuthenticator, // همون authenticator خودت
)
{
if ($customer){
return $userAuthenticator->authenticateUser(
$customer,
$customerAuthenticator, // Authenticator مربوط به فایروال customer_firewall
$request
);
}else{
return $this->redirectToRoute('app_shop_site_index');
}
}
}