diff --git a/.trivyignore b/.trivyignore index ee6b711..24f1176 100644 --- a/.trivyignore +++ b/.trivyignore @@ -1 +1,6 @@ CVE-2025-30204 +GHSA-c2pc-g5qf-rfrf +CVE-2024-8176 +CVE-2024-55549 +CVE-2025-24855 +CVE-2025-59530 diff --git a/fixtures/test/user.yaml b/fixtures/test/user.yaml index ea3b449..0ea60d5 100644 --- a/fixtures/test/user.yaml +++ b/fixtures/test/user.yaml @@ -88,7 +88,6 @@ App\Entity\User: name: 'APES compte lieu' address: '@address_region_hauts_de_france' schedule: '9h30 - 17h30' - phoneNumber: null createdAt: # —— Users ————————————————————————————————————————————————————————————————— @@ -170,6 +169,7 @@ App\Entity\User: firstname: lastname: address: null + phoneNumber: '+33600000000' avatar: 'a9a9bf49-24e4-4b3e-bdbd-86808c32939e.jpg' # user with an address and a preferred category set diff --git a/src/Controller/Admin/AbstractUserCrudController.php b/src/Controller/Admin/AbstractUserCrudController.php index 4fa5f6e..26f7c2f 100755 --- a/src/Controller/Admin/AbstractUserCrudController.php +++ b/src/Controller/Admin/AbstractUserCrudController.php @@ -342,7 +342,7 @@ abstract class AbstractUserCrudController extends AbstractCrudController impleme ->setFormType(PhoneNumberType::class) ->setFormTypeOptions([ 'format' => PhoneNumberFormat::INTERNATIONAL, - 'required' => false, + 'required' => true, ]) ->setHelp($i18prefix.'.field.phone.help') ; diff --git a/src/Controller/Security/AccountCreateController.php b/src/Controller/Security/AccountCreateController.php index 966f362..91a85b8 100644 --- a/src/Controller/Security/AccountCreateController.php +++ b/src/Controller/Security/AccountCreateController.php @@ -8,6 +8,7 @@ use App\Controller\FlashTrait; use App\Controller\i18nTrait; use App\Controller\User\MyAccountAction; use App\Entity\User; +use App\Enum\User\UserType; use App\Exception\UserConfirmationTokenExpiredException; use App\Exception\UserNotFoundException; use App\Form\Type\Security\AccountCreateStep1FormType; @@ -20,12 +21,15 @@ use App\MessageBus\CommandBus; use App\MessageBus\QueryBus; use App\MessageHandler\Command\Security\AccountCreateStep1CommandHandler; use App\Repository\ConfigurationRepository; +use libphonenumber\PhoneNumber; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\SecurityBundle\Security; +use Symfony\Component\Form\FormError; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Messenger\Exception\HandlerFailedException; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Contracts\Translation\TranslatorInterface; /** * @see AccountCreateActionStep1Test @@ -43,6 +47,7 @@ final class AccountCreateController extends AbstractController private readonly CommandBus $commandBus, private readonly Security $security, private readonly ConfigurationRepository $configurationRepository, + private readonly TranslatorInterface $translator, ) { $this->i18nPrefix = $this->getI18nPrefix(); } @@ -102,39 +107,55 @@ final class AccountCreateController extends AbstractController $configuration = $this->configurationRepository->getInstanceConfigurationOrCreate(); // nominal case: user found and token not expired $form = $this->createForm(AccountCreateStep2FormType::class, $user->setStep2Defaults())->handleRequest($request); - if ($form->isSubmitted() && $form->isValid()) { - /** @var User $user */ - $user = $form->getData(); - $this->commandBus->dispatch(new AccountCreateStep2Command($user)); - $this->security->login($user); // auto-log the user + if ($form->isSubmitted()) { + $phone = $form->get('phone')->getData() ?? ''; - // If user has pending invitations then redirect them to the first group - // found without doing the confirmation stuff, it must be done on the - // page group. - $group = $user->getMyGroupsAsInvited()->first(); - if ($group !== false) { - // If platform needs payment, redirect to payment - if ($configuration->getPaidMembership()) { - $successMessage = $this->i18nPrefix.'.step2.with_invitation.global_paid_membership.flash.success'; + if (!$phone instanceof PhoneNumber || $phone->getNationalNumber() === '') { + $form->get('phone')->addError( + new FormError($this->translator->trans('account_create.phone.empty.error', [], 'validators')) + ); + } + + if ($phone instanceof PhoneNumber && \strlen($phone->getNationalNumber() ?? '') < 8) { + $form->get('phone')->addError( + new FormError($this->translator->trans('account_create.phone.short.error', [], 'validators')) + ); + } + if ($form->isValid()) { + /** @var User $user */ + $user = $form->getData(); + $user->setType(UserType::USER); + $this->commandBus->dispatch(new AccountCreateStep2Command($user)); + $this->security->login($user); // auto-log the user + + // If user has pending invitations then redirect them to the first group + // found without doing the confirmation stuff, it must be done on the + // page group. + $group = $user->getMyGroupsAsInvited()->first(); + if ($group !== false) { + // If platform needs payment, redirect to payment + if ($configuration->getPaidMembership()) { + $successMessage = $this->i18nPrefix.'.step2.with_invitation.global_paid_membership.flash.success'; + $this->addFlashSuccess($successMessage); + + return $this->redirectToRoute('redirect_to_payment'); + } + $successMessage = $this->i18nPrefix.'.step2.with_invitation.flash.success'; $this->addFlashSuccess($successMessage); - return $this->redirectToRoute('redirect_to_payment'); + return $this->redirectToRoute('app_group_show_logged', $group->getRoutingParameters()); } - $successMessage = $this->i18nPrefix.'.step2.with_invitation.flash.success'; + + if ($configuration->getPaidMembership()) { + $successMessage = $this->i18nPrefix.'.step2.global_paid_membership.flash.success'; + } else { + $successMessage = $this->i18nPrefix.'.step2.flash.success'; + } + // otherwise go to the address form $this->addFlashSuccess($successMessage); - return $this->redirectToRoute('app_group_show_logged', $group->getRoutingParameters()); + return $this->redirectToRoute(MyAccountAction::ROUTE); } - - if ($configuration->getPaidMembership()) { - $successMessage = $this->i18nPrefix.'.step2.global_paid_membership.flash.success'; - } else { - $successMessage = $this->i18nPrefix.'.step2.flash.success'; - } - // otherwise go to the address form - $this->addFlashSuccess($successMessage); - - return $this->redirectToRoute(MyAccountAction::ROUTE); } return $this->render('pages/register/step2.html.twig', compact('form', 'user')); diff --git a/src/Controller/User/Account/EditProfileAction.php b/src/Controller/User/Account/EditProfileAction.php index 9380580..8a0613a 100644 --- a/src/Controller/User/Account/EditProfileAction.php +++ b/src/Controller/User/Account/EditProfileAction.php @@ -13,7 +13,9 @@ use App\Form\Type\User\EditProfileFormType; use App\Repository\UserRepository; use App\Tests\Functional\Controller\User\Account\EditProfileActionTest; use Doctrine\ORM\EntityManagerInterface; +use libphonenumber\PhoneNumber; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\Form\FormError; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -21,6 +23,7 @@ use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter; use Symfony\Component\Security\Http\Attribute\CurrentUser; use Symfony\Component\Security\Http\Attribute\IsGranted; +use Symfony\Contracts\Translation\TranslatorInterface; /** * @see EditProfileActionTest @@ -34,6 +37,7 @@ final class EditProfileAction extends AbstractController private readonly UserRepository $userRepository, private readonly UserManager $userManager, private readonly EntityManagerInterface $entityManager, + private readonly TranslatorInterface $translator, ) { } @@ -45,14 +49,30 @@ final class EditProfileAction extends AbstractController public function __invoke(Request $request, #[CurrentUser] User $user): Response { $form = $this->createForm(EditProfileFormType::class, $user)->handleRequest($request); - if ($form->isSubmitted() && $form->isValid()) { - /** @var UploadedFile|null $avatar */ - $avatar = $form->get('avatar')->getData(); - $this->userManager->upload($avatar, $user); - $this->userRepository->save($user, true); - $this->addFlashSuccess($this->getI18nPrefix().'.flash.success'); + if ($form->isSubmitted()) { + $phone = $form->get('phone')->getData() ?? ''; - return $this->redirectToRoute(MyAccountAction::ROUTE); + if (!$phone instanceof PhoneNumber || $phone->getNationalNumber() === '') { + $form->get('phone')->addError( + new FormError($this->translator->trans('account_create.phone.empty.error', [], 'validators')) + ); + } + + if ($phone instanceof PhoneNumber && \strlen($phone->getNationalNumber() ?? '') < 8) { + $form->get('phone')->addError( + new FormError($this->translator->trans('account_create.phone.short.error', [], 'validators')) + ); + } + + if ($form->isValid()) { + /** @var UploadedFile|null $avatar */ + $avatar = $form->get('avatar')->getData(); + $this->userManager->upload($avatar, $user); + $this->userRepository->save($user, true); + $this->addFlashSuccess($this->getI18nPrefix().'.flash.success'); + + return $this->redirectToRoute(MyAccountAction::ROUTE); + } } // In case of error, we must reload the original firstname (to display it in navbar) diff --git a/src/Form/Type/Security/AccountCreateStep2FormType.php b/src/Form/Type/Security/AccountCreateStep2FormType.php index 94e677b..0ed465c 100755 --- a/src/Form/Type/Security/AccountCreateStep2FormType.php +++ b/src/Form/Type/Security/AccountCreateStep2FormType.php @@ -5,11 +5,10 @@ declare(strict_types=1); namespace App\Form\Type\Security; use App\Entity\User; -use App\Enum\User\UserType; +use libphonenumber\PhoneNumberFormat; +use Misd\PhoneNumberBundle\Form\Type\PhoneNumberType; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\CallbackTransformer; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\PasswordType; use Symfony\Component\Form\Extension\Core\Type\RepeatedType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; @@ -27,19 +26,6 @@ final class AccountCreateStep2FormType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options): void { $builder - ->add('type', ChoiceType::class, [ - 'label' => 'account_create_action.account_type', - 'label_attr' => ['class' => 'text-black fw-light'], - 'choices' => UserType::getForFront(), - 'choice_attr' => function () { - return [ - 'data-controller' => 'account', - 'data-action' => 'click->account#choosenType', - ]; - }, - 'expanded' => true, - ]) - ->add('firstname', TextType::class, [ 'label' => 'account_create_action.firsname', 'label_attr' => ['class' => 'text-black fw-light required'], @@ -60,14 +46,14 @@ final class AccountCreateStep2FormType extends AbstractType 'required' => false, ]) - ->add('name', TextType::class, [ - 'label' => 'account_create_action.name', - 'label_attr' => ['class' => 'text-black fw-light required'], - 'attr' => [ - 'class' => 'form-control-sm input-name', - 'placeholder' => 'account_create_action.name.placeholder', - ], - 'required' => false, + ->add('phone', PhoneNumberType::class, [ + 'label' => 'account_create_action.phone', + 'label_attr' => ['class' => 'text-black fs-6 fw-normal'], + 'widget' => PhoneNumberType::WIDGET_COUNTRY_CHOICE, + 'format' => PhoneNumberFormat::INTERNATIONAL, + 'country_display_emoji_flag' => true, + 'preferred_country_choices' => ['FR'], + 'required' => true, ]) ->add('plainPassword', RepeatedType::class, [ @@ -118,15 +104,6 @@ final class AccountCreateStep2FormType extends AbstractType 'attr' => ['class' => 'btn btn-primary btn-sm'], ]) ; - - $builder->get('type')->addModelTransformer(new CallbackTransformer( - function (?UserType $enumToString) { - return $enumToString === null ? '' : $enumToString->value; - }, - function (string $stringToEnum) { - return UserType::from($stringToEnum); - } - )); } public function configureOptions(OptionsResolver $resolver): void diff --git a/src/Form/Type/User/EditProfileFormType.php b/src/Form/Type/User/EditProfileFormType.php index 6e5ee39..8009ddf 100644 --- a/src/Form/Type/User/EditProfileFormType.php +++ b/src/Form/Type/User/EditProfileFormType.php @@ -50,8 +50,9 @@ final class EditProfileFormType extends AbstractType 'label_attr' => ['class' => 'text-black fs-6 fw-normal'], 'format' => PhoneNumberFormat::INTERNATIONAL, 'widget' => PhoneNumberType::WIDGET_COUNTRY_CHOICE, + 'country_display_emoji_flag' => true, 'preferred_country_choices' => ['FR'], - 'required' => false, + 'required' => true, ]) ->add('smsNotifications', CheckboxType::class, [ diff --git a/src/Message/Command/Security/AccountCreateStep2Command.php b/src/Message/Command/Security/AccountCreateStep2Command.php index e3fb6dd..f666698 100755 --- a/src/Message/Command/Security/AccountCreateStep2Command.php +++ b/src/Message/Command/Security/AccountCreateStep2Command.php @@ -7,6 +7,7 @@ namespace App\Message\Command\Security; use App\Entity\User; use App\Enum\User\UserType; use App\MessageHandler\Command\Security\AccountCreateStep2CommandHandler; +use libphonenumber\PhoneNumber; use Symfony\Component\Uid\Uuid; use Webmozart\Assert\Assert; @@ -22,6 +23,7 @@ final class AccountCreateStep2Command public ?string $firstname = null; public ?string $name = null; public string $plainPassword; + public PhoneNumber $phone; public function __construct(User $user) { @@ -33,5 +35,7 @@ final class AccountCreateStep2Command $this->name = $user->getName(); Assert::stringNotEmpty($user->getPlainPassword()); $this->plainPassword = $user->getPlainPassword(); + Assert::notNull($user->phone); + $this->phone = $user->phone; } } diff --git a/src/MessageHandler/Command/Security/AccountCreateStep2CommandHandler.php b/src/MessageHandler/Command/Security/AccountCreateStep2CommandHandler.php index 564df19..e3c199f 100644 --- a/src/MessageHandler/Command/Security/AccountCreateStep2CommandHandler.php +++ b/src/MessageHandler/Command/Security/AccountCreateStep2CommandHandler.php @@ -9,6 +9,8 @@ use App\Entity\User; use App\Enum\User\UserType; use App\Message\Command\Security\AccountCreateStep2Command; use App\Repository\UserRepository; +use libphonenumber\PhoneNumberFormat; +use libphonenumber\PhoneNumberUtil; use Symfony\Component\Messenger\Attribute\AsMessageHandler; use Webmozart\Assert\Assert; @@ -47,6 +49,11 @@ final class AccountCreateStep2CommandHandler throw new \UnexpectedValueException('This hanlder can only create users or places.'); } + $phoneObjectToString = PhoneNumberUtil::getInstance()->format( + $message->phone, + PhoneNumberFormat::E164 + ); + $user->setPhoneNumber($phoneObjectToString); $this->userManager->updatePassword($user->setPlainPassword($message->plainPassword)); $this->userManager->finalizeAccountCreateStep2($user); $this->userManager->save($user, true); diff --git a/templates/components/product/_calendar.html.twig b/templates/components/product/_calendar.html.twig index cd07aeb..30776e0 100644 --- a/templates/components/product/_calendar.html.twig +++ b/templates/components/product/_calendar.html.twig @@ -1,6 +1,7 @@ {% set is_product_owner = product.owner == app.user %} -
+
{{ title }}
@@ -71,22 +72,36 @@
{% endif %}
-
- {% if actionNeeded %} + {% if actionNeeded %}
{% if app.user is null or is_granted('borrow', product) %} - + {% if app.user and app.user.address is null %} + {% include 'components/product/_modal.html.twig' with { + menu_action: false, + page_type: 'article', + button: 'templates.components.product.calendar.service_request'|trans, + title: 'templates.pages.account.index.no-address-title'|trans, + message: 'templates.pages.account.index.no-address-message'|trans({ + '%product%': product.type.isObject ? 'objet' : 'service' + }), + action: 'templates.pages.account.product.list.no-address-add'|trans + } %} + {% else %} + + {% endif %} {% else %} {{ form_widget(form.submit) }} {% endif %} diff --git a/templates/components/product/_modal.html.twig b/templates/components/product/_modal.html.twig index 59cc0b5..af89057 100644 --- a/templates/components/product/_modal.html.twig +++ b/templates/components/product/_modal.html.twig @@ -1,7 +1,14 @@ {% if menu_action is defined and menu_action == true %} {{ button }} + data-bs-toggle="modal" + data-bs-target="#modalAddAddress">{{ button }} +{% elseif menu_action is defined and menu_action == false and page_type == 'article' %} + {% else %}
diff --git a/templates/pages/register/step2.html.twig b/templates/pages/register/step2.html.twig index 3f0e1db..f6851bf 100644 --- a/templates/pages/register/step2.html.twig +++ b/templates/pages/register/step2.html.twig @@ -31,7 +31,6 @@ {{ form_start(form, {attr: {novalidate: true}}) }} - {{ form_row(form.type) }}
{{ form_label(form.firstname) }} {{ form_widget(form.firstname) }} @@ -40,10 +39,10 @@ {{ form_widget(form.lastname) }} {{ form_errors(form.lastname) }}
-
- {{ form_label(form.name) }} - {{ form_widget(form.name) }} - {{ form_errors(form.name) }} +
+ {{ form_label(form.phone) }} + {{ form_widget(form.phone) }} + {{ form_errors(form.phone) }}
{% include 'components/form/_password_visibility.html.twig' with { diff --git a/tests/Functional/Controller/Security/AccountCreateActionStep2PlaceTest.php b/tests/Functional/Controller/Security/AccountCreateActionStep2PlaceTest.php deleted file mode 100644 index 1988ca5..0000000 --- a/tests/Functional/Controller/Security/AccountCreateActionStep2PlaceTest.php +++ /dev/null @@ -1,53 +0,0 @@ -request('GET', self::ROUTE.TestReference::USER_13_CONFIRMATION_TOKEN); - self::assertResponseRedirects(); - $client->followRedirect(); - self::assertResponseIsSuccessful(); - self::assertSelectorTextContains('body', 'app.controller.security.account_create_controller.step2.user_confirmation_token_expired.warning'); - } - - public function testFormSubmitPlaceSuccess(): void - { - $client = self::createClient(); - $crawler = $client->request('GET', self::ROUTE.TestReference::USER_12_CONFIRMATION_TOKEN); - $form = $crawler->selectButton('account_create_step2_form_submit')->form(); - - $password = ByteString::fromRandom(13); - $client->submit($form, [ - $form->getName().'[type]' => 'place', - $form->getName().'[name]' => 'My Association', - $form->getName().'[plainPassword][first]' => $password, - $form->getName().'[plainPassword][second]' => $password, - $form->getName().'[gdpr]' => 1, - ]); - self::assertResponseRedirects(); - $client->followRedirect(); - self::assertResponseIsSuccessful(); - } -} diff --git a/tests/Functional/Controller/Security/AccountCreateActionStep2UserInvitationTest.php b/tests/Functional/Controller/Security/AccountCreateActionStep2UserInvitationTest.php index 599b2b7..1b18bff 100644 --- a/tests/Functional/Controller/Security/AccountCreateActionStep2UserInvitationTest.php +++ b/tests/Functional/Controller/Security/AccountCreateActionStep2UserInvitationTest.php @@ -33,11 +33,12 @@ final class AccountCreateActionStep2UserInvitationTest extends WebTestCase $password = ByteString::fromRandom(13); $client->submit($form, [ - $form->getName().'[type]' => 'user', $form->getName().'[firstname]' => 'Foo', $form->getName().'[lastname]' => 'Bar', $form->getName().'[plainPassword][first]' => $password, $form->getName().'[plainPassword][second]' => $password, + $form->getName().'[phone][country]' => 'FR', + $form->getName().'[phone][number]' => '602030405', $form->getName().'[gdpr]' => 1, ]); self::assertResponseRedirects(); diff --git a/tests/Functional/Controller/Security/AccountCreateActionStep2UserTest.php b/tests/Functional/Controller/Security/AccountCreateActionStep2UserTest.php index f52c464..2683211 100644 --- a/tests/Functional/Controller/Security/AccountCreateActionStep2UserTest.php +++ b/tests/Functional/Controller/Security/AccountCreateActionStep2UserTest.php @@ -40,11 +40,12 @@ final class AccountCreateActionStep2UserTest extends WebTestCase $password = ByteString::fromRandom(13); $client->submit($form, [ - $form->getName().'[type]' => 'user', $form->getName().'[firstname]' => 'Foo', $form->getName().'[lastname]' => 'Bar', $form->getName().'[plainPassword][first]' => $password, $form->getName().'[plainPassword][second]' => $password, + $form->getName().'[phone][country]' => 'FR', + $form->getName().'[phone][number]' => '602030405', $form->getName().'[gdpr]' => 1, ]); self::assertResponseRedirects(); diff --git a/tests/Functional/Controller/User/Account/EditProfileActionTest.php b/tests/Functional/Controller/User/Account/EditProfileActionTest.php index fcae901..518a54a 100644 --- a/tests/Functional/Controller/User/Account/EditProfileActionTest.php +++ b/tests/Functional/Controller/User/Account/EditProfileActionTest.php @@ -44,7 +44,7 @@ final class EditProfileActionTest extends WebTestCase $form->getName().'[category]' => TestReference::CATEGORY_OBJECT_1, $form->getName().'[description]' => 'description test', $form->getName().'[phone][country]' => 'FR', - $form->getName().'[phone][number]' => '', + $form->getName().'[phone][number]' => '634563424', $form->getName().'[smsNotifications]' => false, ]); @@ -53,7 +53,7 @@ final class EditProfileActionTest extends WebTestCase /** @var User $editedUser */ $editedUser = $repo->find(TestReference::USER_16); - self::assertNull($editedUser->getPhoneNumber()); + self::assertNotNull($editedUser->getPhoneNumber()); self::assertResponseRedirects(); $client->followRedirect(); diff --git a/tests/Integration/Doctrine/UserManagerTest.php b/tests/Integration/Doctrine/UserManagerTest.php index 86cb1ee..2666b7e 100644 --- a/tests/Integration/Doctrine/UserManagerTest.php +++ b/tests/Integration/Doctrine/UserManagerTest.php @@ -26,6 +26,7 @@ final class UserManagerTest extends KernelTestCase $user = new User(); $user->setEmail(ByteString::fromRandom(6)->toString().'@example.com'); + $user->setPhoneNumber('+33600000000'); $user->setPassword('foo'); $userManager->save($user, true); diff --git a/tests/Integration/MessageHandler/Security/AccountCreateStep2CommandHandlerTest.php b/tests/Integration/MessageHandler/Security/AccountCreateStep2CommandHandlerTest.php index eca8563..f255cee 100644 --- a/tests/Integration/MessageHandler/Security/AccountCreateStep2CommandHandlerTest.php +++ b/tests/Integration/MessageHandler/Security/AccountCreateStep2CommandHandlerTest.php @@ -10,6 +10,7 @@ use App\Message\Command\Security\AccountCreateStep2Command; use App\MessageHandler\Command\Security\AccountCreateStep2CommandHandler; use App\Tests\TestReference; use Hautelook\AliceBundle\PhpUnit\RefreshDatabaseTrait; +use libphonenumber\PhoneNumberUtil; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Component\Uid\Uuid; @@ -25,11 +26,17 @@ final class AccountCreateStep2CommandHandlerTest extends KernelTestCase $this->expectException(\UnexpectedValueException::class); $this->expectExceptionMessage('This hanlder can only create users or places'); + $user = (new User()) ->setId(Uuid::fromString(TestReference::USER_17)) ->setType(UserType::ADMIN) ->setPlainPassword('foo') ; + + $phoneUtil = PhoneNumberUtil::getInstance(); + $phone = $phoneUtil->parse('+33602030405', 'FR'); + $user->phone = $phone; + $message = new AccountCreateStep2Command($user); $handler($message); } diff --git a/tests/Integration/Repository/UserRepositoryTest.php b/tests/Integration/Repository/UserRepositoryTest.php index 841e347..ecf5e43 100644 --- a/tests/Integration/Repository/UserRepositoryTest.php +++ b/tests/Integration/Repository/UserRepositoryTest.php @@ -30,6 +30,7 @@ final class UserRepositoryTest extends KernelTestCase $user = new User(); $user->setEmail(ByteString::fromRandom(6)->toString().'@example.com'); + $user->setPhoneNumber('+33600000000'); $user->setPassword('foo'); $repo->save($user, true); $count = $repo->count([]); diff --git a/translations/security/account_create/security.fr.xlf b/translations/security/account_create/security.fr.xlf index 39821d5..a5ed764 100644 --- a/translations/security/account_create/security.fr.xlf +++ b/translations/security/account_create/security.fr.xlf @@ -75,6 +75,11 @@ 8 caractères minimun + + account_create_action.phone + Numéro de téléphone + + account_create_action.gdpr J’ai lu et j’accepte les Conditions Générales d'Utilisation
]]> diff --git a/translations/security/account_create/validators.fr.xlf b/translations/security/account_create/validators.fr.xlf index 5229d73..1c12cf8 100644 --- a/translations/security/account_create/validators.fr.xlf +++ b/translations/security/account_create/validators.fr.xlf @@ -26,6 +26,16 @@ Le nom du lieu est obligatoire + + account_create.phone.empty.error + Le numéro de téléphone est obligatoire + + + + account_create.phone.short.error + Veuillez indiquer un numéro de téléphone valide + + diff --git a/translations/templates/pages/account/index/messages.fr.xlf b/translations/templates/pages/account/index/messages.fr.xlf index cafb149..da0aa22 100644 --- a/translations/templates/pages/account/index/messages.fr.xlf +++ b/translations/templates/pages/account/index/messages.fr.xlf @@ -74,7 +74,7 @@ templates.pages.account.index.no-address-message - Pour pouvoir créer un %product%, commencez par remplir votre adresse. + Pour pouvoir créer ou emprunter un %product%, commencez par remplir votre adresse.