Skip to content

Instantly share code, notes, and snippets.

@lchrusciel
Last active March 16, 2022 12:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lchrusciel/777b59b2af6a4e39ccb23ed7c6f49b59 to your computer and use it in GitHub Desktop.
Save lchrusciel/777b59b2af6a4e39ccb23ed7c6f49b59 to your computer and use it in GitHub Desktop.
Reset password token not set to null after reset password security bug fix
<?php
// src/CommandHandler/Account/ResetPasswordHandler.php
declare(strict_types=1);
namespace App\CommandHandler\Account;
use Sylius\Bundle\ApiBundle\Command\Account\ResetPassword;
use Sylius\Component\Core\Model\ShopUserInterface;
use Sylius\Component\Resource\Metadata\MetadataInterface;
use Sylius\Component\User\Repository\UserRepositoryInterface;
use Sylius\Component\User\Security\PasswordUpdaterInterface;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
use Webmozart\Assert\Assert;
final class ResetPasswordHandler implements MessageHandlerInterface
{
private UserRepositoryInterface $userRepository;
private MetadataInterface $metadata;
private PasswordUpdaterInterface $passwordUpdater;
public function __construct(
UserRepositoryInterface $userRepository,
MetadataInterface $metadata,
PasswordUpdaterInterface $passwordUpdater
) {
$this->userRepository = $userRepository;
$this->metadata = $metadata;
$this->passwordUpdater = $passwordUpdater;
}
public function __invoke(ResetPassword $command): void
{
/** @var ShopUserInterface|null $user */
$user = $this->userRepository->findOneBy(['passwordResetToken' => $command->resetPasswordToken]);
Assert::notNull($user, 'No user found with reset token: ' . $command->resetPasswordToken);
$resetting = $this->metadata->getParameter('resetting');
$lifetime = new \DateInterval($resetting['token']['ttl']);
if (!$user->isPasswordRequestNonExpired($lifetime)) {
throw new \InvalidArgumentException('Password reset token has expired');
}
if ($command->resetPasswordToken !== $user->getPasswordResetToken()) {
throw new \InvalidArgumentException('Password reset token does not match.');
}
$user->setPlainPassword($command->newPassword);
$this->passwordUpdater->updatePassword($user);
$user->setPasswordResetToken(null);
}
}
# config/services.yaml
services:
# ...
# For Sylius v1.11
Sylius\Bundle\ApiBundle\CommandHandler\Account\ResetPasswordHandler:
alias: App\CommandHandler\Account\ResetPasswordHandler
# For Sylius v1.10
Sylius\Bundle\ApiBundle\CommandHandler\ResetPasswordHandler:
alias: App\CommandHandler\Account\ResetPasswordHandler
App\CommandHandler\Account\ResetPasswordHandler:
arguments:
- '@sylius.repository.shop_user'
- !service
class: Sylius\Component\Resource\Metadata\MetadataInterface
factory: [ '@sylius.resource_registry', 'get' ]
arguments:
- 'sylius.shop_user'
- '@sylius.security.password_updater'
tags:
- { name: messenger.message_handler, bus: sylius.command_bus }
- { name: messenger.message_handler, bus: sylius_default.bus }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment