Initially proposed for Monofony, but it makes sense for Sylius as well. Maybe even more for Sylius.
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, submit, 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 Sylius by default.
@mikemix how would you implement it in a different way, from the technical point of view?
besides the technical implementation, don't you find (business) value in the improvement I have proposed?
I cannot find a good (business) justification for the current behavior where the user is asked to do lots of unnecessary steps that can be automated for the sake of UX.
@CoderMaggie any input on this?
This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in a week if no further activity occurs. Thank you for your contributions.
can we have some input from the Sylius Team? cc @pamil
I'm also in favor of such behavior. That's not very a fluid process currently and it needs way too much steps.
@pamil
