coopTilleuls / CoopTilleulsForgotPasswordBundle

Provides a "forgot password" complete feature for your API through a Symfony bundle
MIT License
79 stars 25 forks source link

Cannot autowire service "App\EventSubscriber\ForgotPasswordEventSubscriber": argument "$userManager" #85

Closed clem9999 closed 3 years ago

clem9999 commented 3 years ago

Describe the bug Hi all!

I'm trying to implement your bundle, but when I follow your instruction... the part where I get the mail is ok, but not the part to reset the password. I don't understand the problem the UserManager type is not found.

To Reproduce My controller : (ForgotPasswordEventSubscriber.php)

namespace App\EventSubscriber;

use CoopTilleuls\ForgotPasswordBundle\Event\CreateTokenEvent; use CoopTilleuls\ForgotPasswordBundle\Event\UpdatePasswordEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Mime\Email; use Twig\Environment; use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;

use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;

final class ForgotPasswordEventSubscriber implements EventSubscriberInterface { private $mailer; private $twig; /* @var UserPasswordHasherInterface / private $passwordHasher;

private $userManager;

public function __construct(MailerInterface $mailer, Environment $twig, UserPasswordHasherInterface $passwordHasher, UserManager $userManager)
{
    $this->mailer = $mailer;
    $this->twig = $twig;
    $this->passwordHasher = $passwordHasher;
    $this->userManager = $userManager;

}

public static function getSubscribedEvents()
{
    return [
        // Symfony 4.3 and inferior, use 'coop_tilleuls_forgot_password.create_token' event name
        CreateTokenEvent::class => 'onCreateToken',
        UpdatePasswordEvent::class => 'onUpdatePassword',

    ];
}

public function onCreateToken(CreateTokenEvent $event)
{
    $passwordToken = $event->getPasswordToken();
    $user = $passwordToken->getUser();

    $message = (new Email())
        ->from('no-reply@example.com')
        ->to($user->getEmail())
        ->subject('Reset your password')
        ->html($this->twig->render(
            'resetpassword/reset_password_email.html.twig',
            [
                'signedUrl' => sprintf('http://localhost:3000/forgot-password/%s', $passwordToken->getToken()),
            ]
        ));
    if (0 === $this->mailer->send($message)) {
        throw new \RuntimeException('Unable to send email');
    }
}

public function onUpdatePassword(UpdatePasswordEvent $event)
{
    $passwordToken = $event->getPasswordToken();
    $user = $passwordToken->getUser();
    $password = $event->getPassword();
    $hashedPassword = $this->passwordHasher->hashPassword($user, $password);
    $user->setPassword($hashedPassword);
    $this->userManager->persist($user);
    $this->userManager->flush();
}

}

`` image Additional context Add any other context about the problem here.

clem9999 commented 3 years ago

Hey !

I fix my problem. I just missed to add an import use Doctrine\ORM\EntityManagerInterface; and change the type by EntityManagerInterface.

My Controller :

namespace App\EventSubscriber; use CoopTilleuls\ForgotPasswordBundle\Event\UpdatePasswordEvent; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use CoopTilleuls\ForgotPasswordBundle\Event\CreateTokenEvent; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Mime\Email; use Twig\Environment; use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;

use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;

final class ForgotPasswordEventSubscriber implements EventSubscriberInterface { private $mailer; private $twig; /* @var UserPasswordHasherInterface / private $passwordHasher;

private $userManager;

public function __construct(MailerInterface $mailer, Environment $twig, UserPasswordHasherInterface $passwordHasher, EntityManagerInterface $userManager)
{
    $this->mailer = $mailer;
    $this->twig = $twig;
    $this->passwordHasher = $passwordHasher;
    $this->userManager = $userManager;

}

public static function getSubscribedEvents()
{
    return [
        // Symfony 4.3 and inferior, use 'coop_tilleuls_forgot_password.create_token' event name
        CreateTokenEvent::class => 'onCreateToken',
        UpdatePasswordEvent::class => 'onUpdatePassword',

    ];
}

public function onCreateToken(CreateTokenEvent $event)
{
    $passwordToken = $event->getPasswordToken();
    $user = $passwordToken->getUser();

    $message = (new Email())
        ->from('no-reply@example.com')
        ->to($user->getEmail())
        ->subject('Reset your password')
        ->html($this->twig->render(
            'resetpassword/reset_password_email.html.twig',
            [
                'signedUrl' => sprintf('http://localhost:3000/forgot-password/%s', $passwordToken->getToken()),
            ]
        ));
    if (0 === $this->mailer->send($message)) {
        throw new \RuntimeException('Unable to send email');
    }
}

public function onUpdatePassword(UpdatePasswordEvent $event)
{
    $passwordToken = $event->getPasswordToken();
    $user = $passwordToken->getUser();
    $password = $event->getPassword();
    $hashedPassword = $this->passwordHasher->hashPassword($user, $password);
    $user->setPassword($hashedPassword);
    $this->userManager->persist($user);
    $this->userManager->flush();
}

}

chalasr commented 3 years ago

Cool, cool. Closing as solved then. Thanks for sharing your solution and for using this bundle.