Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto login after user confirmation and password reset #141

Open
gabiudrescu opened this issue May 7, 2020 · 1 comment
Open

Auto login after user confirmation and password reset #141

gabiudrescu opened this issue May 7, 2020 · 1 comment

Comments

@gabiudrescu
Copy link

Describe the proposed solution
You create yourself an account. You fill in a big form. Now you get redirected to your email to confirm it. You close the app, go to your email, find the mail, open it, click the link, and you are redirected to a login form with a flash message that you can now safely login.

But you have to input again the username, the password. Cognitive load++.

Same for reset password: you go to the website, it asks you to login. You input your email and a password you remember, it's wrong. Try a couple of variants, end up with the same error - wrong password.

You decide to reset it. Then you go to reset password. Enter your email, sends you back to login with a flash message to check your email. Again: You close the app, go to your email, find the mail, open it, click the link, and you are redirected to a form where you can set the new password. You write it, twice and hit submit.

Back to login, with a flash message. Now you have to insert the username, again, and then the new password. Again. Cognitive load++. Rage++.

Solution

<?php

namespace App\EventSubscriber;


use Sylius\Bundle\UserBundle\Security\UserLoginInterface;
use Sylius\Bundle\UserBundle\UserEvents;
use Sylius\Component\User\Repository\UserRepositoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
use Webmozart\Assert\Assert;

class AutologinSubscriber implements EventSubscriberInterface
{
    /**
     * @var \App\Repository\UserRepository
     */
    private $userRepository;
    /**
     * @var \Sylius\Bundle\UserBundle\Security\UserLoginInterface
     */
    private $userLogin;
    /**
     * @var string
     */
    private $firewallContextName;

    public function __construct(
        UserRepositoryInterface $userRepository,
        UserLoginInterface $userLogin,
        string $firewallContextName
    ) {
        $this->userRepository = $userRepository;
        $this->userLogin = $userLogin;
        $this->firewallContextName = $firewallContextName;
    }

    /**
     * @return array|string[]
     */
    public static function getSubscribedEvents(): array
    {
        return [
            UserEvents::POST_PASSWORD_RESET => 'autoLogin',
        ];
    }

    public function autoLogin(GenericEvent $event)
    {
        $user = $event->getSubject();
        Assert::notNull($user);

        $user->setEnabled(true);
        $this->userRepository->add($user);

        $this->userLogin->login($user, $this->firewallContextName);
    }
}
    Sylius\Component\User\Repository\UserRepositoryInterface: '@sylius.repository.app_user'

    App\EventSubscriber\AutologinSubscriber:
        class: App\EventSubscriber\AutologinSubscriber
        arguments:
            $firewallContextName: '%firewall.app.context%'
--- a/config/packages/security.yaml
+++ b/config/packages/security.yaml
@@ -5,6 +5,9 @@ imports:
 
 parameters:
     secret: '%env(resolve:APP_SECRET)%'
+    firewall.app.context: 'app'
+    firewall.admin.context: 'admin'
+    firewall.api.context: 'api'
 
 security:
 
@@ -22,7 +25,7 @@ security:
 
     firewalls:
         admin:
-            context: admin
+            context: '%firewall.admin.context%'
             pattern: /admin(?:/.*)?$
             provider: sylius_admin_user_provider
             form_login:
@@ -54,10 +57,11 @@ security:
             fos_oauth: true
             stateless: true
             anonymous: true
+            context: '%firewall.api.context%'
 
         app:
             switch_user: true
-            context: app
+            context: '%firewall.app.context%'
             pattern: /.*
             provider: sylius_app_user_provider
             form_login:
diff --git a/config/routes/frontend/security.yaml b/config/routes/frontend/security.yaml
index 3465090..7f89171 100644
--- a/config/routes/frontend/security.yaml
+++ b/config/routes/frontend/security.yaml
@@ -49,7 +49,7 @@ app_frontend_password_reset:
         _controller: sylius.controller.app_user:resetPasswordAction
         _sylius:
             template: frontend/account/resetPassword.html.twig
-            redirect: app_frontend_login
+            redirect: app_frontend_homepage

The solution above is a PoC I implemented for my needs. It works for me. If you are interested, I can submit it in a PR to be included in Monofony by default and, maybe, why not, in Sylius as well.

@gabiudrescu
Copy link
Author

@loic425 any input on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant