<?php
namespace App\Profile\Controller;
use App\Profile\Entity\ForgotPassword;
use App\Profile\Entity\Login;
use App\Profile\Entity\Register;
use App\Profile\Entity\ResetPassword;
use App\Profile\Form\Type\Auth\ForgotPasswordType;
use App\Profile\Form\Type\Auth\LoginType;
use App\Profile\Form\Type\Auth\RegisterType;
use App\Profile\Form\Type\Auth\ResetPasswordType;
use App\Profile\Model\Profile;
use App\Profile\Model\ProfileRoles;
use App\Profile\Service\ProfileAuthService;
use Codeception\Exception\ConfigurationException;
use Exception;
use Pimcore\Config\Config;
use Pimcore\Controller\FrontendController;
use Pimcore\Model\WebsiteSetting;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Contracts\Translation\TranslatorInterface;
class ProfileAuthController extends FrontendController
{
protected ProfileAuthService $authService;
protected TranslatorInterface $translator;
public function __construct(ProfileAuthService $authService, TranslatorInterface $translator)
{
$this->authService = $authService;
$this->translator = $translator;
}
#[Route([
'name' => 'auth_register',
'localizedPaths' => [
'en' => '/{_locale}/signup',
'de' => '/{_locale}/signup',
'fr' => '/{_locale}/signup',
],
])]
#[IsGranted('IS_ANONYMOUS')]
public function register(Request $request, Config $websiteConfig): Response
{
$data = new Register();
$data->setProfileType($request->get('register') ? $request->get('register')['profileType'] : null);
$registerForm = $this->createForm(RegisterType::class, $data);
$registerForm->handleRequest($request);
if ($registerForm->isSubmitted() && $registerForm->isValid()) {
$data = $registerForm->getData();
try {
$mailDocument = WebsiteSetting::getByName('authActivationMailDocument', null, $request->getLocale(), 'en') ?? null;
if (!$mailDocument) {
throw new ConfigurationException('Website Config "authActivationMailDocument" is not configured properly.');
}
$mailDocument = $mailDocument->getData();
$activationToken = $this->authService->registerUser($data);
$mail = new \Pimcore\Mail();
$mail->setDocument($mailDocument);
$mail->setParams([
'activationToken' => $activationToken,
'activationLink' => $this->generateUrl('auth_activate', [
'activationToken' => $activationToken,
'_locale' => $request->getLocale(),
], UrlGeneratorInterface::ABSOLUTE_URL),
]);
$mail->to($data->getEmail());
$mail->send();
return $this->redirectToRoute('auth_register_success', ['_locale' => $request->getLocale()]);
} catch (Exception $e) {
$isDuplicate = strtok($e->getMessage(), ' ') == 'Duplicate';
if ($isDuplicate) {
$passwortForgotUrl = $this->generateUrl('auth_forgotpassword', ['email' => $registerForm->get('email')->getData()]);
$link = ' <a href="'.$passwortForgotUrl.'">'.$this->translator->trans('auth.form.register.forgotLinkText').'</a>';
$this->addFlash('error', $this->translator->trans('auth.form.register.alreadyRegisteredError').$link);
} else {
$this->addFlash('error', $this->translator->trans('auth.form.register.unknownError'));
}
}
}
return $this->renderTemplate('auth/register.html.twig', [
'registerForm' => $registerForm->createView(),
]);
}
#[Route([
'name' => 'auth_register_success',
'localizedPaths' => [
'en' => '/{_locale}/signup/success',
'de' => '/{_locale}/signup/success',
'fr' => '/{_locale}/signup/success',
],
])]
#[IsGranted('IS_ANONYMOUS')]
public function registerSuccess(): Response
{
return $this->renderTemplate('auth/register_success.html.twig');
}
#[Route([
'name' => 'auth_activate',
'localizedPaths' => [
'en' => '/{_locale}/signup/activate/{activationToken}',
'de' => '/{_locale}/signup/activate/{activationToken}',
'fr' => '/{_locale}/signup/activate/{activationToken}',
],
])]
#[IsGranted('IS_ANONYMOUS')]
public function activate(Request $request, string $activationToken, Session $session): Response
{
if ($this->authService->activateUser($activationToken)) {
$session->getFlashBag()->add('success', $this->translator->trans('auth.form.login.activateSuccess'));
return $this->redirectToRoute('auth_login', ['_locale' => $request->getLocale()]);
} else {
$response = $this->renderTemplate('auth/activation_failed.html.twig');
}
return $response;
}
#[Route([
'name' => 'auth_login',
'localizedPaths' => [
'en' => '/{_locale}/signin',
'de' => '/{_locale}/signin',
'fr' => '/{_locale}/signin',
],
])]
#[IsGranted('IS_ANONYMOUS')]
public function login(Request $request, AuthenticationUtils $authenticationUtils, Session $session): Response
{
$error = $authenticationUtils->getLastAuthenticationError();
if ($error) {
$this->addFlash('error', $this->translator->trans('auth.form.login.error'));
}
$lastUsername = $authenticationUtils->getLastUsername();
$data = new Login();
if ($lastUsername) {
$data->setEmail($lastUsername);
}
$loginForm = $this->createForm(LoginType::class, $data);
return $this->renderTemplate('auth/login.html.twig', [
'loginForm' => $loginForm->createView(),
'error' => $error,
'flashesSuccess' => $session->getFlashBag()->get('success'),
]);
}
#[Route([
'name' => 'auth_logout',
'localizedPaths' => [
'en' => '/{_locale}/signout',
'de' => '/{_locale}/signout',
'fr' => '/{_locale}/signout',
],
])]
#[IsGranted(ProfileRoles::ROLE_USER)]
public function logout()
{
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
}
#[Route([
'name' => 'auth_logout_success',
'localizedPaths' => [
'en' => '/{_locale}/signout/success',
'de' => '/{_locale}/signout/success',
'fr' => '/{_locale}/signout/success',
],
])]
#[IsGranted('IS_ANONYMOUS')]
public function logoutSuccess()
{
return $this->renderTemplate('auth/logout.html.twig', []);
}
#[Route([
'name' => 'auth_forgotpassword',
'localizedPaths' => [
'en' => '/{_locale}/password/request',
'de' => '/{_locale}/password/request',
'fr' => '/{_locale}/password/request',
],
])]
#[IsGranted('IS_ANONYMOUS')]
public function forgotPassword(Request $request, Config $websiteConfig): Response
{
$data = new ForgotPassword();
if ($request->get('email')) {
$data->setEmail($request->get('email'));
}
$forgotForm = $this->createForm(ForgotPasswordType::class, $data);
$forgotForm->handleRequest($request);
if ($forgotForm->isSubmitted() && $forgotForm->isValid()) {
$data = $forgotForm->getData();
try {
$mailDocument = WebsiteSetting::getByName('authResetMailDocument', null, $request->getLocale(), 'en') ?? null;
if (!$mailDocument) {
throw new ConfigurationException('Website Config "authResetMailDocument" is not configured properly.');
}
$mailDocument = $mailDocument->getData();
$resetToken = $this->authService->forgotPassword($data);
$mail = new \Pimcore\Mail();
$mail->setDocument($mailDocument);
$mail->setParams([
'resetToken' => $resetToken,
'resetLink' => $this->generateUrl('auth_resetpassword', [
'resetToken' => $resetToken,
'_locale' => $request->getLocale(),
], UrlGeneratorInterface::ABSOLUTE_URL),
]);
$mail->to($data->getEmail());
$mail->send();
return $this->redirectToRoute('auth_forgotpassword_success', ['_locale' => $request->getLocale()]);
} catch (Exception $e) {
$this->addFlash('error', $this->translator->trans('auth.form.forgot.error'));
}
}
return $this->renderTemplate('auth/password_forgot.html.twig', [
'forgotForm' => $forgotForm->createView(),
]);
}
#[Route([
'name' => 'auth_forgotpassword_success',
'localizedPaths' => [
'en' => '/{_locale}/password/request/success',
'de' => '/{_locale}/password/request/success',
'fr' => '/{_locale}/password/request/success',
],
])]
#[IsGranted('IS_ANONYMOUS')]
public function forgotPasswordSuccess(): Response
{
return $this->renderTemplate('auth/password_forgot_success.html.twig');
}
#[Route([
'name' => 'auth_resetpassword',
'localizedPaths' => [
'en' => '/{_locale}/password/reset/{resetToken}',
'de' => '/{_locale}/password/reset/{resetToken}',
'fr' => '/{_locale}/password/reset/{resetToken}',
],
])]
#[IsGranted('IS_ANONYMOUS')]
public function resetPassword(Request $request, string $resetToken, Config $websiteConfig): Response
{
$data = new ResetPassword();
$data->setResetToken($resetToken);
$profile = Profile::getByResetToken($data->getResetToken(), 1);
$data->setEmail($profile->getEmail());
$resetForm = $this->createForm(ResetPasswordType::class, $data);
$resetForm->handleRequest($request);
if ($resetForm->isSubmitted() && $resetForm->isValid()) {
$data = $resetForm->getData();
try {
$isReset = $this->authService->resetPassword($data);
if (!$isReset) {
throw new Exception();
}
$mailDocument = WebsiteSetting::getByName('authResetConfirmationMailDocument', null, $request->getLocale(), 'en') ?? null;
if (!$mailDocument) {
throw new ConfigurationException('Website Config "authResetConfirmationMailDocument" is not configured properly.');
}
$mailDocument = $mailDocument->getData();
$mail = new \Pimcore\Mail();
$mail->setDocument($mailDocument);
$mail->to($data->getEmail());
$mail->send();
$this->addFlash('success', $this->translator->trans('auth.form.login.resetSuccess'));
return $this->redirectToRoute('auth_login', ['_locale' => $request->getLocale()]);
} catch (Exception $e) {
$this->addFlash('error', $this->translator->trans('auth.form.reset.error'));
}
}
return $this->renderTemplate('auth/password_reset.html.twig', [
'resetForm' => $resetForm->createView(),
]);
}
}