Remove "Resend Verification Email" page and related functionality

This commit is contained in:
Tomasz Kaliński 2026-06-22 13:54:52 +02:00
parent b7c7ca1bc1
commit 0d20d6372c
25 changed files with 48 additions and 190 deletions

View file

@ -43,7 +43,6 @@ Feature: Resending a verification email
Then I should be notified that my account has not been verified Then I should be notified that my account has not been verified
And I should see the resend verification email link And I should see the resend verification email link
And I should not be logged in And I should not be logged in
When I follow the resend verification email link When I resend the verification email from the login page
And I resend the verification email to "shop@example.com" on the resend page
Then I should be notified that the verification email has been sent to the provided address Then I should be notified that the verification email has been sent to the provided address
And a verification email should have been sent to "shop@example.com" And a verification email should have been sent to "shop@example.com"

View file

@ -13,8 +13,8 @@ declare(strict_types=1);
namespace Sylius\Behat\Context\Ui\Shop; namespace Sylius\Behat\Context\Ui\Shop;
use Behat\Step\Then;
use Behat\Behat\Context\Context; use Behat\Behat\Context\Context;
use Behat\Step\Then;
use Behat\Step\When; use Behat\Step\When;
use Sylius\Behat\Element\Shop\Account\RegisterElementInterface; use Sylius\Behat\Element\Shop\Account\RegisterElementInterface;
use Sylius\Behat\NotificationType; use Sylius\Behat\NotificationType;
@ -23,7 +23,6 @@ use Sylius\Behat\Page\Shop\Account\LoginPageInterface;
use Sylius\Behat\Page\Shop\Account\ProfileUpdatePageInterface; use Sylius\Behat\Page\Shop\Account\ProfileUpdatePageInterface;
use Sylius\Behat\Page\Shop\Account\RegisterPageInterface; use Sylius\Behat\Page\Shop\Account\RegisterPageInterface;
use Sylius\Behat\Page\Shop\Account\RegisterThankYouPageInterface; use Sylius\Behat\Page\Shop\Account\RegisterThankYouPageInterface;
use Sylius\Behat\Page\Shop\Account\ResendVerificationEmailPageInterface;
use Sylius\Behat\Page\Shop\Account\VerificationPageInterface; use Sylius\Behat\Page\Shop\Account\VerificationPageInterface;
use Sylius\Behat\Page\Shop\HomePageInterface; use Sylius\Behat\Page\Shop\HomePageInterface;
use Sylius\Behat\Service\NotificationCheckerInterface; use Sylius\Behat\Service\NotificationCheckerInterface;
@ -42,7 +41,6 @@ class RegistrationContext implements Context
private LoginPageInterface $loginPage, private LoginPageInterface $loginPage,
private RegisterPageInterface $registerPage, private RegisterPageInterface $registerPage,
private RegisterThankYouPageInterface $registerThankYouPage, private RegisterThankYouPageInterface $registerThankYouPage,
private ResendVerificationEmailPageInterface $resendVerificationEmailPage,
private VerificationPageInterface $verificationPage, private VerificationPageInterface $verificationPage,
private ProfileUpdatePageInterface $profileUpdatePage, private ProfileUpdatePageInterface $profileUpdatePage,
private RegisterElementInterface $registerElement, private RegisterElementInterface $registerElement,
@ -209,17 +207,10 @@ class RegistrationContext implements Context
Assert::true($this->loginPage->hasResendVerificationEmailLink()); Assert::true($this->loginPage->hasResendVerificationEmailLink());
} }
#[When('I follow the resend verification email link')] #[When('I resend the verification email from the login page')]
public function iFollowTheResendVerificationEmailLink(): void public function iResendTheVerificationEmailFromTheLoginPage(): void
{ {
$this->resendVerificationEmailPage->open(); $this->loginPage->resendVerificationEmail();
}
#[When('I resend the verification email to :email on the resend page')]
public function iResendTheVerificationEmailToOnTheResendPage(string $email): void
{
$this->resendVerificationEmailPage->specifyEmail($email);
$this->resendVerificationEmailPage->resend();
} }
#[When('I register with email :email and password :password')] #[When('I register with email :email and password :password')]

View file

@ -50,6 +50,13 @@ class LoginPage extends SyliusPage implements LoginPageInterface
return $this->hasElement('resend_verification_email_link'); return $this->hasElement('resend_verification_email_link');
} }
public function resendVerificationEmail(): void
{
$this->getElement('resend_verification_email_link')->press();
DriverHelper::waitForPageToLoad($this->getSession());
}
public function logIn(): void public function logIn(): void
{ {
$this->getElement('login_button')->click(); $this->getElement('login_button')->click();

View file

@ -21,6 +21,8 @@ interface LoginPageInterface extends SyliusPageInterface
public function hasResendVerificationEmailLink(): bool; public function hasResendVerificationEmailLink(): bool;
public function resendVerificationEmail(): void;
public function logIn(): void; public function logIn(): void;
public function specifyPassword(string $password): void; public function specifyPassword(string $password): void;

View file

@ -1,42 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Sylius\Behat\Page\Shop\Account;
use Sylius\Behat\Page\SyliusPage;
final class ResendVerificationEmailPage extends SyliusPage implements ResendVerificationEmailPageInterface
{
public function getRouteName(): string
{
return 'sylius_shop_resend_verification_email';
}
public function resend(): void
{
$this->getElement('resend_button')->click();
}
public function specifyEmail(?string $email): void
{
$this->getElement('email')->setValue($email);
}
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
'email' => '[data-test-resend-verification-email]',
'resend_button' => '[data-test-resend-verification-email-button]',
]);
}
}

View file

@ -1,23 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Sylius\Behat\Page\Shop\Account;
use Sylius\Behat\Page\SyliusPageInterface;
interface ResendVerificationEmailPageInterface extends SyliusPageInterface
{
public function resend(): void;
public function specifyEmail(?string $email): void;
}

View file

@ -281,7 +281,6 @@ return static function (ContainerConfigurator $container) {
service('sylius.behat.page.shop.account.login'), service('sylius.behat.page.shop.account.login'),
service('sylius.behat.page.shop.account.register'), service('sylius.behat.page.shop.account.register'),
service('sylius.behat.page.shop.account.register.thank_you'), service('sylius.behat.page.shop.account.register.thank_you'),
service('sylius.behat.page.shop.account.resend_verification_email'),
service('sylius.behat.page.shop.account.verify'), service('sylius.behat.page.shop.account.verify'),
service('sylius.behat.page.shop.account.profile_update'), service('sylius.behat.page.shop.account.profile_update'),
service('sylius.behat.element.shop.account.register'), service('sylius.behat.element.shop.account.register'),

View file

@ -23,7 +23,6 @@ use Sylius\Behat\Page\Shop\Account\ProfileUpdatePage;
use Sylius\Behat\Page\Shop\Account\RegisterPage; use Sylius\Behat\Page\Shop\Account\RegisterPage;
use Sylius\Behat\Page\Shop\Account\RegisterThankYouPage; use Sylius\Behat\Page\Shop\Account\RegisterThankYouPage;
use Sylius\Behat\Page\Shop\Account\RequestPasswordResetPage; use Sylius\Behat\Page\Shop\Account\RequestPasswordResetPage;
use Sylius\Behat\Page\Shop\Account\ResendVerificationEmailPage;
use Sylius\Behat\Page\Shop\Account\ResetPasswordPage; use Sylius\Behat\Page\Shop\Account\ResetPasswordPage;
use Sylius\Behat\Page\Shop\Account\VerificationPage; use Sylius\Behat\Page\Shop\Account\VerificationPage;
use Sylius\Behat\Page\Shop\Account\WellKnownPasswordChangePage; use Sylius\Behat\Page\Shop\Account\WellKnownPasswordChangePage;
@ -46,7 +45,6 @@ return static function (ContainerConfigurator $container) {
$parameters->set('sylius.behat.page.shop.account.register.class', RegisterPage::class); $parameters->set('sylius.behat.page.shop.account.register.class', RegisterPage::class);
$parameters->set('sylius.behat.page.shop.account.register.thank_you.class', RegisterThankYouPage::class); $parameters->set('sylius.behat.page.shop.account.register.thank_you.class', RegisterThankYouPage::class);
$parameters->set('sylius.behat.page.shop.account.request_password_reset.class', RequestPasswordResetPage::class); $parameters->set('sylius.behat.page.shop.account.request_password_reset.class', RequestPasswordResetPage::class);
$parameters->set('sylius.behat.page.shop.account.resend_verification_email.class', ResendVerificationEmailPage::class);
$parameters->set('sylius.behat.page.shop.account.reset_password.class', ResetPasswordPage::class); $parameters->set('sylius.behat.page.shop.account.reset_password.class', ResetPasswordPage::class);
$parameters->set('sylius.behat.page.shop.account.verify.class', VerificationPage::class); $parameters->set('sylius.behat.page.shop.account.verify.class', VerificationPage::class);
$parameters->set('sylius.behat.page.shop.account.well_known_password_change.class', WellKnownPasswordChangePage::class); $parameters->set('sylius.behat.page.shop.account.well_known_password_change.class', WellKnownPasswordChangePage::class);
@ -118,11 +116,6 @@ return static function (ContainerConfigurator $container) {
->parent('sylius.behat.symfony_page') ->parent('sylius.behat.symfony_page')
; ;
$services
->set('sylius.behat.page.shop.account.resend_verification_email', '%sylius.behat.page.shop.account.resend_verification_email.class%')
->parent('sylius.behat.symfony_page')
;
$services $services
->set('sylius.behat.page.shop.account.reset_password', '%sylius.behat.page.shop.account.reset_password.class%') ->set('sylius.behat.page.shop.account.reset_password', '%sylius.behat.page.shop.account.reset_password.class%')
->parent('sylius.behat.symfony_page') ->parent('sylius.behat.symfony_page')

View file

@ -17,6 +17,6 @@ use Sylius\Bundle\ApiBundle\Attribute\OrderTokenValueAware;
use Sylius\Bundle\CoreBundle\Command\ResendOrderConfirmationEmail as BaseResendOrderConfirmationEmail; use Sylius\Bundle\CoreBundle\Command\ResendOrderConfirmationEmail as BaseResendOrderConfirmationEmail;
#[OrderTokenValueAware] #[OrderTokenValueAware]
readonly class ResendOrderConfirmationEmail extends BaseResendOrderConfirmationEmail class ResendOrderConfirmationEmail extends BaseResendOrderConfirmationEmail
{ {
} }

View file

@ -17,6 +17,6 @@ use Sylius\Bundle\ApiBundle\Attribute\ShipmentIdAware;
use Sylius\Bundle\CoreBundle\Command\ResendShipmentConfirmationEmail as BaseResendShipmentConfirmationEmail; use Sylius\Bundle\CoreBundle\Command\ResendShipmentConfirmationEmail as BaseResendShipmentConfirmationEmail;
#[ShipmentIdAware] #[ShipmentIdAware]
readonly class ResendShipmentConfirmationEmail extends BaseResendShipmentConfirmationEmail class ResendShipmentConfirmationEmail extends BaseResendShipmentConfirmationEmail
{ {
} }

View file

@ -13,10 +13,10 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Command; namespace Sylius\Bundle\CoreBundle\Command;
readonly class ResendOrderConfirmationEmail class ResendOrderConfirmationEmail
{ {
public function __construct( public function __construct(
public string $orderTokenValue, public readonly string $orderTokenValue,
) { ) {
} }
} }

View file

@ -13,10 +13,9 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Command; namespace Sylius\Bundle\CoreBundle\Command;
readonly class ResendShipmentConfirmationEmail class ResendShipmentConfirmationEmail
{ {
public function __construct( public function __construct(public readonly mixed $shipmentId)
public mixed $shipmentId, {
) {
} }
} }

View file

@ -14,33 +14,32 @@ declare(strict_types=1);
namespace Sylius\Bundle\ShopBundle\Controller; namespace Sylius\Bundle\ShopBundle\Controller;
use Sylius\Bundle\CoreBundle\Command\Account\ResendVerificationEmail; use Sylius\Bundle\CoreBundle\Command\Account\ResendVerificationEmail;
use Sylius\Bundle\UserBundle\Form\Model\PasswordResetRequest;
use Sylius\Bundle\UserBundle\Form\Type\UserRequestPasswordResetType;
use Sylius\Component\Channel\Context\ChannelContextInterface; use Sylius\Component\Channel\Context\ChannelContextInterface;
use Sylius\Component\Core\Model\ChannelInterface; use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Locale\Context\LocaleContextInterface; use Sylius\Component\Locale\Context\LocaleContextInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface; use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Routing\RouterInterface; use Symfony\Component\Routing\RouterInterface;
use Twig\Environment; use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
final class ResendVerificationEmailController final class ResendVerificationEmailController
{ {
public function __construct( public function __construct(
private readonly RouterInterface $router, private readonly RouterInterface $router,
private readonly FormFactoryInterface $formFactory,
private readonly Environment $twig,
private readonly ChannelContextInterface $channelContext, private readonly ChannelContextInterface $channelContext,
private readonly LocaleContextInterface $localeContext, private readonly LocaleContextInterface $localeContext,
private readonly MessageBusInterface $commandBus, private readonly MessageBusInterface $commandBus,
private readonly AuthenticationUtils $authenticationUtils,
private readonly CsrfTokenManagerInterface $csrfTokenManager,
) { ) {
} }
public function requestAction(Request $request): Response public function resendAction(Request $request): Response
{ {
/** @var ChannelInterface $channel */ /** @var ChannelInterface $channel */
$channel = $this->channelContext->getChannel(); $channel = $this->channelContext->getChannel();
@ -49,29 +48,27 @@ final class ResendVerificationEmailController
return new RedirectResponse($this->router->generate('sylius_shop_login')); return new RedirectResponse($this->router->generate('sylius_shop_login'));
} }
$form = $this->formFactory->create(UserRequestPasswordResetType::class); $token = new CsrfToken('resend_verification_email', (string) $request->request->get('_csrf_token'));
if ($request->isMethod('POST') && $form->handleRequest($request)->isSubmitted() && $form->isValid()) { if (!$this->csrfTokenManager->isTokenValid($token)) {
/** @var PasswordResetRequest $data */ return new RedirectResponse($this->router->generate('sylius_shop_login'));
$data = $form->getData(); }
$email = $this->authenticationUtils->getLastUsername();
if ('' !== $email) {
$this->commandBus->dispatch(new ResendVerificationEmail( $this->commandBus->dispatch(new ResendVerificationEmail(
channelCode: $channel->getCode(), channelCode: $channel->getCode(),
localeCode: $this->localeContext->getLocaleCode(), localeCode: $this->localeContext->getLocaleCode(),
email: (string) $data->getEmail(), email: $email,
sendVerificationLink: true, sendVerificationLink: true,
)); ));
/** @var FlashBagInterface $flashBag */
$flashBag = $request->getSession()->getBag('flashes');
$flashBag->add('success', 'sylius.user.verification_email_sent');
return new RedirectResponse($this->router->generate('sylius_shop_resend_verification_email'));
} }
return new Response($this->twig->render( /** @var FlashBagInterface $flashBag */
'@SyliusShop/account/resend_verification_email.html.twig', $flashBag = $request->getSession()->getBag('flashes');
['form' => $form->createView()], $flashBag->add('success', 'sylius.user.verification_email_sent');
));
return new RedirectResponse($this->router->generate('sylius_shop_login'));
} }
} }

View file

@ -1,30 +0,0 @@
sylius_twig_hooks:
hooks:
'sylius_shop.account.resend_verification_email':
content:
template: '@SyliusShop/account/resend_verification_email/content.html.twig'
priority: 0
'sylius_shop.account.resend_verification_email.content':
form_container:
template: '@SyliusShop/account/resend_verification_email/content/form_container.html.twig'
priority: 0
'sylius_shop.account.resend_verification_email.content.form_container':
header:
template: '@SyliusShop/account/resend_verification_email/content/form_container/header.html.twig'
priority: 200
description:
template: '@SyliusShop/account/resend_verification_email/content/form_container/description.html.twig'
priority: 100
form:
template: '@SyliusShop/account/resend_verification_email/content/form_container/form.html.twig'
priority: 0
'sylius_shop.account.resend_verification_email.content.form_container.form':
email:
template: '@SyliusShop/account/resend_verification_email/content/form_container/form/email.html.twig'
priority: 100
submit:
template: '@SyliusShop/account/resend_verification_email/content/form_container/form/submit.html.twig'
priority: 0

View file

@ -64,9 +64,9 @@ sylius_shop_register_thank_you:
sylius_shop_resend_verification_email: sylius_shop_resend_verification_email:
path: /resend-verification-email path: /resend-verification-email
methods: [GET, POST] methods: [POST]
defaults: defaults:
_controller: sylius_shop.controller.resend_verification_email::requestAction _controller: sylius_shop.controller.resend_verification_email::resendAction
sylius_shop_request_password_reset_token: sylius_shop_request_password_reset_token:
path: /forgotten-password path: /forgotten-password

View file

@ -58,11 +58,11 @@ return static function (ContainerConfigurator $container) {
->set('sylius_shop.controller.resend_verification_email', ResendVerificationEmailController::class) ->set('sylius_shop.controller.resend_verification_email', ResendVerificationEmailController::class)
->args([ ->args([
service('router'), service('router'),
service('form.factory'),
service('twig'),
service('sylius.context.channel'), service('sylius.context.channel'),
service('sylius.context.locale'), service('sylius.context.locale'),
service('sylius.command_bus'), service('sylius.command_bus'),
service('security.authentication_utils'),
service('security.csrf.token_manager'),
]) ])
; ;

View file

@ -3,6 +3,9 @@
{% if last_error is not empty and last_error.messageKey == 'sylius.user.email_not_verified' and sylius.channel.accountVerificationRequired %} {% if last_error is not empty and last_error.messageKey == 'sylius.user.email_not_verified' and sylius.channel.accountVerificationRequired %}
<div class="mt-2 text-center"> <div class="mt-2 text-center">
{{ 'sylius.ui.verification_email_not_received'|trans }}<br /> {{ 'sylius.ui.verification_email_not_received'|trans }}<br />
<a href="{{ path('sylius_shop_resend_verification_email') }}" {{ sylius_test_html_attribute('resend-verification-email-link') }}>{{ 'sylius.ui.resend_verification_email'|trans }}</a> <form method="post" action="{{ path('sylius_shop_resend_verification_email') }}">
<input type="hidden" name="_csrf_token" value="{{ csrf_token('resend_verification_email') }}" />
<button type="submit" class="btn btn-link p-0 border-0 align-baseline" {{ sylius_test_html_attribute('resend-verification-email-link') }}>{{ 'sylius.ui.resend_verification_email'|trans }}</button>
</form>
</div> </div>
{% endif %} {% endif %}

View file

@ -1,7 +0,0 @@
{% extends '@SyliusShop/shared/layout/base.html.twig' %}
{% block title %}{{ 'sylius.ui.resend_verification_email'|trans }} | {{ parent() }}{% endblock %}
{% block content %}
{% hook 'sylius_shop.account.resend_verification_email' with { form } %}
{% endblock %}

View file

@ -1,5 +0,0 @@
<div class="container my-auto">
<div class="row justify-content-center my-4">
{% hook 'content' %}
</div>
</div>

View file

@ -1,7 +0,0 @@
<div class="col-12 col-sm-10 col-md-8 col-lg-6 col-xl-4 order-lg-1">
<div class="d-flex justify-content-center align-items-center h-100 px-3">
<div class="w-100 py-lg-5 mb-5 my-lg-5">
{% hook 'form_container' %}
</div>
</div>
</div>

View file

@ -1 +0,0 @@
<div class="mb-4">{{ 'sylius.ui.resend_verification_email_info'|trans }}</div>

View file

@ -1,10 +0,0 @@
{% set form = hookable_metadata.context.form %}
{% form_theme form '@SyliusShop/form/theme.html.twig' %}
<div>
{{ form_start(form, {'action': path('sylius_shop_resend_verification_email'), 'attr': {'novalidate': 'novalidate'}}) }}
{% hook 'form' %}
{{ form_row(form._token) }}
{{ form_end(form, {'render_rest': false}) }}
</div>

View file

@ -1 +0,0 @@
{{ form_row(hookable_metadata.context.form.email, sylius_test_form_attribute('resend-verification-email')) }}

View file

@ -1,5 +0,0 @@
<div class="d-grid">
<button class="btn btn-primary" type="submit" {{ sylius_test_html_attribute('resend-verification-email-button') }}>
{{ 'sylius.ui.resend_verification_email'|trans }}
</button>
</div>

View file

@ -1 +0,0 @@
<h1 class="h2">{{ 'sylius.ui.resend_verification_email'|trans }}</h1>