<?php declare(strict_types=1);
namespace App\StartPlatz\Bundle\UserBundle\Controller;
use App\StartPlatz\Bundle\MemberBundle\Entity\Member;
use App\StartPlatz\Bundle\StartupBundle\Entity\Application;
use App\StartPlatz\Bundle\StartupBundle\Entity\Batch;
use App\StartPlatz\Bundle\UserBundle\Form\SetPasswordFormType;
use App\StartPlatz\Bundle\WebsiteBundle\Utility\Utility;
use Doctrine\DBAL\Driver\Connection;
use Exception;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use App\StartPlatz\Bundle\FeedbackBundle\CallbackService;
use App\StartPlatz\Bundle\UserBundle\Entity\User;
use App\StartPlatz\Bundle\UserBundle\Entity\UserRepository;
use App\StartPlatz\Bundle\UserBundle\Form\LoginFormType;
use App\StartPlatz\Bundle\UserBundle\Form\LostPasswordFormType;
use App\StartPlatz\Bundle\UserBundle\Form\RegistrationFormType;
use App\StartPlatz\Bundle\UserBundle\Security\LoginLink\Token;
use Startplatz\Bundle\WordpressIntegrationBundle\Annotation\WordpressResponse;
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\Routing\RouterInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Security as SymfonySecurity;
class AuthenticationController extends AbstractController
{
public function __construct(private readonly SessionInterface $session, private readonly RouterInterface $router, private readonly UserPasswordEncoderInterface $encoder, private readonly MailerInterface $mailer, private readonly CallbackService $callbackService, private readonly Connection $connection)
{
}
/**
* @Route("/usfb/{md5}", name="unsubscribe_user_bulkmail")
* @param $md5
* @return RedirectResponse|Response
*/
public function unsubscribeUserBulkmailAction($md5)
{
$em = $this->getDoctrine()->getManager();
if (!$user = $em->getRepository(User::class)->findOneBy(['salt' => $md5])) {
return new Response('sorry, not found ');
}
if (!$user->getisOnBlacklist()) {
$member = $em->getRepository(Member::class)->find($user->getMemberId());
$em->getRepository(Member::class)->addTag('blacklist', $member, $user->getEmail(), $logText = 'User has unsubscribed');
}
$redirect = '/x/feed';
$hash = Token::createHash($user->getEmail(), $redirect);
$this->session->getFlashBag()->add('notice', 'SUCCESS you have been unsubscribed ');
return $this->redirect($this->generateUrl('login_email_check', [
'email' => $user->getEmail(),
'hash' => $hash,
'redirect' => $redirect,
]));
}
/**
* @Route("/authentication/magic-link", name="login_magic_link")
*/
public function magicLinkAction(Request $request)
{
// Prüfe die Anfragemethode
if (!$request->isMethod('POST')) {
return new Response('Invalid request.', 405);
}
$em = $this->getDoctrine()->getManager();
$email = strtolower((string) $request->get('email'));
/** @var Member $member */
if (!$member = $em->getRepository(Member::class)->findOneBy(['email' => $email])) {
return new Response('', 400);
}
/*
if (!$user = $this->getUser()){
$toEmail = 'lorenz.graef@startplatz.de';
$mailText = "Member mit E-Mail {$member->getEmail()} und firstName {$member->getFirstName()} und lastName {$member->getLastName()} versucht sich einzuloggen" ;
$mailSubject = 'Login Versuch';
$fromEmail = "lorenz.graef@startplatz.de";
$fromName = "System per Allmeda - SOS";
$bodyType = 'html';
$sendResult = Utility::sendAlertMailPerN8N( $toEmail, $mailText, $mailSubject, $fromEmail, $fromName, $bodyType);
return new Response('please try later', 400);
}
*/
if ($redirect = $request->request->get('targetPath')) {
if ($redirect[0] != "/") {
$redirect = "/" . $redirect;
}
} elseif ($redirect = $request->get('targetPath')) {
## do nothing
} else {
$redirect = "/x/home";
}
if (!$action = $request->get('action')) {
$action = 'setPassword';
}
$hash = Token::createHash($email, $redirect);
$data = ['email' => $email, 'redirect' => $redirect];
$loginLink = $this->generateUrl('login_email_check', ['email' => $data['email'], 'hash' => $hash, 'redirect' => $data['redirect'], 'action' => $action]);
$loginLink = $request->getSchemeAndHttpHost() . $loginLink;
$payload = json_encode([
'memberFirstName' => $member->getFirstName(),
'memberName' => $member->getName(),
'memberEmail' => $member->getEmail(),
'magicLink' => $loginLink,
]);
$callbackUrl = "https://hooks.zapier.com/hooks/catch/1872803/2qid0ji/";
$this->callbackService->curl_callback($callbackUrl, $payload);
return new Response('SUCCESS Magic Link sent to ' . $email);
}
/**
* @Route("/authentication/magic-link-defense", name="login_magic_defense_link")
* @Security("is_granted('ROLE_USER')")
*/
public function magicLinkDefenseAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$email = strtolower((string) $request->get('email'));
/** @var Member $member */
if (!$member = $em->getRepository(Member::class)->findOneBy(['email' => $email])) {
return new Response('', 400);
}
if ($redirect = $request->request->get('targetPath')) {
if ($redirect[0] != "/") {
$redirect = "/" . $redirect;
}
} elseif ($redirect = $request->get('targetPath')) {
## do nothing
} else {
$redirect = "/x/home";
}
if (!$action = $request->get('action')) {
$action = 'setPassword';
}
$hash = Token::createHash($email, $redirect);
$data = ['email' => $email, 'redirect' => $redirect];
$loginLink = $this->generateUrl('login_email_check', ['email' => $data['email'], 'hash' => $hash, 'redirect' => $data['redirect'], 'action' => $action]);
$loginLink = $request->getSchemeAndHttpHost() . $loginLink;
$payload = json_encode([
'memberFirstName' => $member->getFirstName(),
'memberName' => $member->getName(),
'memberEmail' => $member->getEmail(),
'magicLink' => $loginLink,
]);
$callbackUrl = "https://hooks.zapier.com/hooks/catch/1872803/2qid0ji/";
$this->callbackService->curl_callback($callbackUrl, $payload);
return new Response('SUCCESS Magic Link sent to ' . $email);
}
/* Gerrit stash membership 11.4.23
/**
* @Route("/x/membership/finalize/{account}/{productNumber}/{customerHash}", name="x_membership_booked")
*
public function newMembershipLogin(Request $request, $customerHash, $account, $productNumber = 0)
{
if (!$redirect = json_decode(base64_decode($request->get('redirect')))) {
$redirect = json_decode(json_encode(array('path' => 'x_membership_first-steps', 'parameters' => array('productNumber' => $productNumber, 'account' => $account))));
}
$redirectUrl = $this->generateUrl($redirect->path, (array)$redirect->parameters);
//logged in
if ($user = $this->getUser()) {
if (!ctype_digit($user->getPassword())) $this->redirect($redirectUrl);
$form = $this->createSetPasswordForm($redirectUrl);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$user = $this->getUser();
$data = $form->getData();
$password = $data['new_password'];
$newPasswordEncoded = $this->getUserPasswordEncoder()->encodePassword($user, $password);
$user->setPassword($newPasswordEncoded);
$em->getRepository(User::class)->add($user);
return $this->redirect($redirectUrl);
}
//logged in, set password
return $this->render('@StartPlatzAlphaBundle/Default/new.membership.login.html.twig', array(
'setPasswordForm' => $form->createView(),
'setPassword' => true,
'redirect' => base64_encode(json_encode($redirect)),
));
}
//Not logged in, ask for email to send link.
return $this->render('@StartPlatzAlphaBundle/Default/new.membership.login.html.twig', array(
'setPassword' => false,
'targetPath' => $this->generateUrl($redirect->path, (array)$redirect->parameters),
));
}
*/
/**
* @Route("/login/", name="login")
*/
public function loginAction(Request $request)
{
if ($targetPath = $request->query->get('targetPath')) {
$parts = parse_url((string) $targetPath);
$redirect = $parts['path'];
} elseif ($targetPath = $request->getSession()->get('_security.secured_area.target_path')) {
$parts = parse_url((string) $targetPath);
$redirect = $parts['path'];
} else {
$redirect = $this->generateUrl('x_home');
}
return $this->showLogin($redirect, $request);
}
protected function showLogin($redirect, $request, $registrationFormData = [], $forms = [])
{
$redirectRouteName = null;
$session = $request->getSession();
try {
$routingParameter = $this->router->match($redirect);
$redirectRouteName = $routingParameter['_route'];
} catch (Exception) {
}
if ($this->getUser()) {
return $this->redirect($redirect ?: $this->generateUrl('x_home'));
}
if ($request->attributes->has(SymfonySecurity::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(SymfonySecurity::AUTHENTICATION_ERROR);
} else {
$error = $session->get(SymfonySecurity::AUTHENTICATION_ERROR);
$session->remove(SymfonySecurity::AUTHENTICATION_ERROR);
}
if ($error) {
$session->getFlashBag()->add('notice', $this->renderView('@StartPlatzUserBundle/Authentication/loginErrorFlash.html.twig'));
}
if (!array_key_exists('registrationForm', $forms)) {
$forms['registrationForm'] = $this->createRegistrationForm($redirect, $registrationFormData);
}
if (!array_key_exists('pwlostForm', $forms)) {
$forms['pwlostForm'] = $this->createPwlostForm($redirect, $registrationFormData);
}
$template = "@StartPlatzUserBundle/Authentication/login.html.twig";
return $this->render($template, ['redirectRouteName' => $redirectRouteName, 'redirect' => $redirect, 'loginForm' => $this->createLoginForm($redirect)->createView(), 'registrationForm' => $forms['registrationForm']->createView(), 'pwlostForm' => $forms['pwlostForm']->createView()]);
}
protected function createRegistrationForm($redirect = null, $data = [])
{
if ($redirect) {
$data['redirect'] = $redirect;
}
return $this->createForm(
RegistrationFormType::class,
$data
);
}
protected function createPwlostForm($redirect = null, $data = [])
{
if ($redirect) {
$data['redirect'] = $redirect;
}
return $this->createForm(
LostPasswordFormType::class,
$data
);
}
protected function createLoginForm($redirect)
{
return $this->createForm(
LoginFormType::class,
['target_path' => $redirect]
);
}
protected function createSetPasswordForm($redirect)
{
return $this->createForm(
SetPasswordFormType::class,
['target_path' => $redirect]
);
}
/**
* @Route("/login/facebook", name="login_facebook")
*/
public function loginFacebookAction(): void
{
}
/**
* @Route("/login/facebook/check", name="login_facebook_check")
*/
public function loginFacebookCheckAction(): void
{
}
/**
* @Route("/login/google", name="login_google")
*/
public function loginGoogleAction(): void
{
}
/**
* @Route("/login/google/check", name="login_google_check")
*/
public function loginGoogleCheckAction(): void
{
}
/**
* @Route("/login/password/check", name="login_password_check")
*/
public function loginPasswordCheckAction(): void
{
}
/** @return UserRepository */
protected function getUserRepository()
{
return $this->getDoctrine()->getRepository(User::class);
}
/**
* @return UserPasswordEncoderInterface
*/
protected function getUserPasswordEncoder()
{
return $this->encoder;
}
protected function createEmailHash($salt, $email)
{
return Token::createHash($salt, $email);
}
/**
* @Route("/login/link/create/{redirect}", name="login_link_create")
* @Security("is_granted('ROLE_USER')")
*/
public function loginLinkCreateAction(Request $request, $redirect)
{
$url = $this->generateUrl($redirect);
$this->generateLoginLink($url);
$request->getSession()->getFlashBag()->add('notice', 'loginlink zu ' . $url . ' erstellt');
return $this->redirect($this->generateUrl('community_home'));
}
protected function generateLoginLink($redirect = '/x')
{
/** @var User $user */
$user = $this->getUser();
$message = new Email();
$message->to($user->getEmail());
$message->from(new Address('info@startplatz.de', 'Startplatz - Webseite'));
$message->subject('login-link for startplatz.de');
$message->text(
$this->renderView(
'@StartPlatzUserBundle/Mails/sendLoginLink.txt.twig',
['email' => $user->getEmail(), 'name' => $user->getName(), 'hash' => Token::createHash($user->getEmail(), $redirect), 'redirect' => $redirect]
)
);
$this->mailer->send($message);
return true;
}
/**
* @Route("/login/link/lg/create/{redirect}", name="login_link_create_lg")
*/
public function createLoginLinkLg(Request $request, $redirect)
{
$url = $this->generateUrl($redirect);
$this->generateLoginLinkLg($url);
$request->getSession()->getFlashBag()->add('notice', 'loginlink zu ' . $url . ' erstellt');
return $this->redirect($this->generateUrl('community_home'));
}
protected function generateLoginLinkLg($redirect = '/crm/contacts')
{
$email = 'lorenz.graef@startplatz.de';
$message = new Email();
$message->to($email);
$message->from(new Address('info@startplatz.de', 'Startplatz - Webseite'));
$message->subject('login-link for startplatz.de');
$message->text(
$this->renderView(
'@StartPlatzUserBundle/Mails/sendLoginLink.txt.twig',
['email' => $email, 'name' => 'lorenz', 'hash' => Token::createHash($email, $redirect), 'redirect' => $redirect]
)
);
$this->mailer->send($message);
return true;
}
/**
* @Route("/lost-pw/", name="lost_pw", methods={"POST"})
* @Template("@StartPlatzUserBundle/Authentication/login.html.twig")
*/
public function lostPwAction(Request $request)
{
$form = $this->createPwlostForm();
$form->handleRequest($request);
$data = $form->getData();
if ($form->isSubmitted() && $form->isValid()) {
$reset = $this->resetPassword($data);
if ($reset) {
$request->getSession()->getFlashBag()->add('notice', $this->renderView('@StartPlatzUserBundle/Authentication/passwordEmailFlash.html.twig', $data));
return $this->redirect($this->generateUrl('login'));
} else {
$request->getSession()->getFlashBag()->add('notice', $this->renderView('@StartPlatzUserBundle/Authentication/passwordEmailErrorFlash.html.twig', $data));
return $this->showLogin($data['redirect'], $request, $data, ['pwlostForm' => $form]);
}
} else {
return $this->showLogin($data['redirect'], $request, $data, ['pwlostForm' => $form]);
}
}
protected function resetPassword($data)
{
$password = substr(base_convert(sha1(uniqid((string)random_int(0, mt_getrandmax()), true)), 16, 36), 0, 8);
/** @var User $user */
if (!($user = $this->getUserRepository()->loadUser($data))) {
return false;
}
$user->setPassword($this->getUserPasswordEncoder()->encodePassword($user, $password));
$this->getUserRepository()->add($user);
//$password= $user->getPassword();
$message = new Email();
$message->to($data['email']);
$message->from(new Address('info@startplatz.de', 'Startplatz - Webseite'));
$message->subject('Dein Passwort für startplatz.de!');
$message->text(
$this->renderView(
'@StartPlatzUserBundle/Mails/login-password.txt.twig',
['email' => $user->getEmail(), 'name' => $user->getName(), 'hash' => Token::createHash($data['email'], $data['redirect']), 'redirect' => $data['redirect'], 'password' => $password]
)
);
$this->mailer->send($message);
return true;
}
/**
* @Route("/profile/send-new-password/", name="user_profile_send_new_password")
* @Security("is_granted('ROLE_USER')")
*/
public function sendNewPasswordAction(Request $request)
{
$user = $this->getUser();
$data['email'] = $user->getEmail();
$data['redirect'] = '/profile/set-password/';
$reset = $this->resetPassword($data);
if ($reset) {
$request->getSession()->getFlashBag()->add('notice', $this->renderView('@StartPlatzUserBundle/Authentication/passwordEmailFlash.html.twig', $data));
} else {
$request->getSession()->getFlashBag()->add('notice', $this->renderView('@StartPlatzUserBundle/Authentication/passwordEmailErrorFlash.html.twig', $data));
}
return $this->redirect($this->generateUrl('user_profil_change_password'));
}
/**
* @Route("/login/link/check/{email}/{hash}/to{redirect}", name="login_email_check", requirements={"redirect"=".+"})
*/
public function loginLinkCheckAction(Request $request, $redirect = '/', $hash = "")
{
if ($user = $this->getUser()) {
$em = $this->getDoctrine()->getManager();
$em->getRepository(User::class)->writeActivity($user);
if ($batches = $em->getRepository(Batch::class)->findByExtended(['settings' => 'validateEmail'])) {
foreach ($batches as $batch) {
$batchId = $batch->getId();
if ($application = $em->getRepository(Application::class)->findOneBy(['batchId' => $batchId, 'memberId'=>$user->getMemberId()])) {
$application->setHasEmailValidated(true);
$em->persist($application);
$em->flush();
}
}
}
if ($request->get('action') == 'setPassword') {
return $this->redirect($this->generateUrl('x_home', ['hash' => $hash]));
}
return $this->redirect($redirect);
} else {
$this->session->getFlashBag()->add('notice', 'ERROR: no user found');
return $this->redirect($this->generateUrl('x_home'));
}
}
/**
* @Route("/login/confirm/{email}/{hash}/to{redirect}", name="login_confirm_email", requirements={"redirect"=".+"})
*/
public function confirmLinkCheckAction(Request $request, $email, $hash, $redirect = '/login')
{
$em = $this->getDoctrine()->getManager();
$action = $request->get('action');
if (!$user = $this->getUserRepository()->findUserByConfirm($hash)) {
if ($this->getUserRepository()->findOneBy(['email' => $email])) {
$this->session->getFlashBag()->add('notice', 'ERROR email already confirmed. Please login.');
} else {
$this->session->getFlashBag()->add('notice', 'ERROR not matching any user');
}
return $this->redirect('/logout');
}
if (!$user->getIsEmailConfirmed()) {
$user->setIsEmailConfirmed(true);
$user->setEmail($user->getToConfirmEmail());
$user->setConfirmEmail(null);
$user->setToConfirmEmail(null);
$this->getUserRepository()->add($user);
if ($memberId = $user->getMemberId()) {
$em->getRepository(Member::class)->changeEmailByMemberId($memberId, $user->getEmail(), $user->getEmail());
}
}
return $this->redirect($this->getLoginLink($user->getEmail(), $redirect, $action));
}
private function getLoginLink($email, $redirect = '/x', $action = null)
{
$hash = Token::createHash($email, $redirect);
if ($action) {
$loginLink = $this->generateUrl('login_email_check', ['email' => $email, 'hash' => $hash, 'redirect' => $redirect, 'action' => $action]);
} else {
$loginLink = $this->generateUrl('login_email_check', ['email' => $email, 'hash' => $hash, 'redirect' => $redirect]);
}
return $loginLink;
}
/**
* @Route("/logout/", name="logout")
*/
public function logoutAction(): void
{
}
/**
* @Template
*/
public function loginStatusAction()
{
return [];
}
}