From b9aed93c9d08ed3a539f9e9795a61c810b45b22e Mon Sep 17 00:00:00 2001 From: Julien Rosset Date: Tue, 14 May 2024 18:43:29 +0200 Subject: [PATCH] Fix sign up and sign in forms --- .env | 2 +- .gitignore | 2 + assets/styles/_bootstrap.scss | 8 +-- assets/styles/_layout.scss | 2 +- composer.json | 77 ++++++++++++++-------------- config/packages/twig.yaml | 1 + config/services.yaml | 4 +- migrations/Version20240514155807.php | 27 ++++++++++ src/Controller/UserController.php | 11 ++-- src/Entity/User.php | 14 ++--- src/Form/SignUpFormType.php | 36 ++++++++----- src/Security/UserChecker.php | 3 ++ templates/base.html.twig | 6 +-- templates/core/main.html.twig | 2 +- templates/symfony.html.twig | 2 +- templates/user/signIn.html.twig | 38 ++++++++------ templates/user/signUp.html.twig | 9 ++-- 17 files changed, 140 insertions(+), 104 deletions(-) create mode 100644 migrations/Version20240514155807.php diff --git a/.env b/.env index fe088ac..1d45309 100644 --- a/.env +++ b/.env @@ -37,7 +37,7 @@ MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0 ###< symfony/messenger ### ###> symfony/mailer ### -# MAILER_DSN=null://null +MAILER_DSN=smtp://localhost:1025 # MailHog MAILER_EMAIL=jul.rosset@gmail.com MAILER_NAME="WebEDM Mail Bot" ###< symfony/mailer ### diff --git a/.gitignore b/.gitignore index e93e543..2de41b0 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ /public/assets/ /assets/vendor/ ###< symfony/asset-mapper ### + +.symfony.local.yaml \ No newline at end of file diff --git a/assets/styles/_bootstrap.scss b/assets/styles/_bootstrap.scss index 84f2379..ed1e834 100644 --- a/assets/styles/_bootstrap.scss +++ b/assets/styles/_bootstrap.scss @@ -5,16 +5,12 @@ //$primary : rgb(0, 0, 0); //$secondary : rgb(102, 102, 102); +//endregion +//region Autres variables Bootstrap $alert-padding-y : 0.25rem; $alert-padding-x : 0.25rem; $alert-margin-bottom : 0.5rem; //endregion -//region Autres variables Bootstrap -$enable-rounded : false; -$nav-link-padding-y : 0; - -$box-shadow : 0px 3px 15px 0 rgba(0, 0, 0, .8); -//endregion //region Les autres variables de Boostrap @import '../../vendor/twbs/bootstrap/scss/variables'; @import '../../vendor/twbs/bootstrap/scss/variables-dark'; diff --git a/assets/styles/_layout.scss b/assets/styles/_layout.scss index 6398144..7300cec 100644 --- a/assets/styles/_layout.scss +++ b/assets/styles/_layout.scss @@ -15,4 +15,4 @@ header { } footer { bottom : 0; -} +} \ No newline at end of file diff --git a/composer.json b/composer.json index 3df75e6..2375ccf 100644 --- a/composer.json +++ b/composer.json @@ -4,49 +4,50 @@ "minimum-stability": "stable", "prefer-stable": true, "require": { - "php": ">=8.1", - "ext-ctype": "*", - "ext-iconv": "*", - "doctrine/annotations": "^2.0", - "doctrine/doctrine-bundle": "^2.9", + "php": ">=8.1", + "ext-ctype": "*", + "ext-iconv": "*", + "doctrine/annotations": "^2.0", + "doctrine/dbal": "^3", + "doctrine/doctrine-bundle": "^2.9", "doctrine/doctrine-migrations-bundle": "^3.2", - "doctrine/orm": "^2.15", + "doctrine/orm": "^2.15", "phpdocumentor/reflection-docblock": "^5.3", - "phpstan/phpdoc-parser": "^1.20", + "phpstan/phpdoc-parser": "^1.20", "stof/doctrine-extensions-bundle": "^1.7", - "symfony/asset": "6.4.*", - "symfony/asset-mapper": "6.4.*", - "symfony/console": "6.4.*", - "symfony/doctrine-messenger": "6.4.*", - "symfony/dotenv": "6.4.*", + "symfony/asset": "6.4.*", + "symfony/asset-mapper": "6.4.*", + "symfony/console": "6.4.*", + "symfony/doctrine-messenger": "6.4.*", + "symfony/dotenv": "6.4.*", "symfony/expression-language": "6.4.*", - "symfony/flex": "^2", - "symfony/form": "6.4.*", - "symfony/framework-bundle": "6.4.*", - "symfony/http-client": "6.4.*", - "symfony/intl": "6.4.*", - "symfony/mailer": "6.4.*", - "symfony/mime": "6.4.*", - "symfony/monolog-bundle": "^3.0", - "symfony/notifier": "6.4.*", - "symfony/process": "6.4.*", - "symfony/property-access": "6.4.*", - "symfony/property-info": "6.4.*", - "symfony/rate-limiter": "6.4.*", - "symfony/runtime": "6.4.*", - "symfony/security-bundle": "6.4.*", - "symfony/serializer": "6.4.*", - "symfony/string": "6.4.*", - "symfony/translation": "6.4.*", - "symfony/twig-bundle": "6.4.*", - "symfony/validator": "6.4.*", - "symfony/web-link": "6.4.*", - "symfony/yaml": "6.4.*", - "symfonycasts/sass-bundle": "^0.6.0", + "symfony/flex": "^2", + "symfony/form": "6.4.*", + "symfony/framework-bundle": "6.4.*", + "symfony/http-client": "6.4.*", + "symfony/intl": "6.4.*", + "symfony/mailer": "6.4.*", + "symfony/mime": "6.4.*", + "symfony/monolog-bundle": "^3.0", + "symfony/notifier": "6.4.*", + "symfony/process": "6.4.*", + "symfony/property-access": "6.4.*", + "symfony/property-info": "6.4.*", + "symfony/rate-limiter": "6.4.*", + "symfony/runtime": "6.4.*", + "symfony/security-bundle": "6.4.*", + "symfony/serializer": "6.4.*", + "symfony/string": "6.4.*", + "symfony/translation": "6.4.*", + "symfony/twig-bundle": "6.4.*", + "symfony/validator": "6.4.*", + "symfony/web-link": "6.4.*", + "symfony/yaml": "6.4.*", + "symfonycasts/sass-bundle": "^0.6.0", "symfonycasts/verify-email-bundle": "^1.17", - "twbs/bootstrap": "^5.3", - "twig/extra-bundle": "^3.0", - "twig/twig": "^3.0" + "twbs/bootstrap": "^5.3", + "twig/extra-bundle": "^3.0", + "twig/twig": "^3.0" }, "config": { "allow-plugins": { diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml index f9f4cc5..ea00709 100644 --- a/config/packages/twig.yaml +++ b/config/packages/twig.yaml @@ -1,5 +1,6 @@ twig: default_path: '%kernel.project_dir%/templates' + form_themes: [ 'bootstrap_5_horizontal_layout.html.twig' ] when@test: twig: diff --git a/config/services.yaml b/config/services.yaml index 137744b..5a4bced 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -4,8 +4,8 @@ # Put parameters here that don't need to change on each machine where the app is deployed # https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration parameters: - mailer.email: '%env(MAILER_EMAIL)%)' - mailer.name: '%env(MAILER_NAME)%)' + mailer.email: '%env(MAILER_EMAIL)%' + mailer.name: '%env(MAILER_NAME)%' services: # default configuration for services in *this* file diff --git a/migrations/Version20240514155807.php b/migrations/Version20240514155807.php new file mode 100644 index 0000000..b9649b6 --- /dev/null +++ b/migrations/Version20240514155807.php @@ -0,0 +1,27 @@ +addSql('ALTER TABLE user ADD is_verified tinyint(1) NOT NULL'); + } + + public function down (Schema $schema): void { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE user DROP is_verified'); + } +} diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index 6154471..844caf8 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -58,7 +58,7 @@ class UserController extends AbstractController { $user->setPassword( $userPasswordHasher->hashPassword( $user, - $form->get('plainPassword')->getData() + $form->get('newPassword')->getData() ) ); @@ -70,10 +70,11 @@ class UserController extends AbstractController { 'user_mailVerify', $user, (new TemplatedEmail()) - ->from(new Address( - $this->getParameter('mailer.email'), - $this->getParameter('mailer.name') - ) + ->from( + new Address( + $this->getParameter('mailer.email'), + $this->getParameter('mailer.name') + ) ) ->to($user->getEmail()) ->subject('Please Confirm your Email') diff --git a/src/Entity/User.php b/src/Entity/User.php index 0055752..9464d48 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -32,7 +32,6 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface { * @var string The hashed password */ #[ORM\Column(length: 255)] - #[Assert\NotBlank] private string $password; /** @@ -50,7 +49,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface { /** * @var Collection The {@see Tag tags} of the user */ - #[ORM\OneToMany(mappedBy: 'user', targetEntity: Tag::class, orphanRemoval: true)] + #[ORM\OneToMany(mappedBy: 'owner', targetEntity: Tag::class, orphanRemoval: true)] #[Assert\Valid] private Collection $tags; @@ -150,7 +149,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface { * @see UserInterface */ public function getUserIdentifier (): string { - return (string)$this->email; + return $this->email; } /** @@ -183,7 +182,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface { * * @see UserInterface */ - public function eraseCredentials () { + public function eraseCredentials (): void { } /** @@ -221,12 +220,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface { * @return $this */ public function removeTag (Tag $tag): static { - if ($this->tags->removeElement($tag)) { - if ($tag->getOwner() === $this) { - $tag->setOwner(null); - } - } - + $this->tags->removeElement($tag); return $this; } diff --git a/src/Form/SignUpFormType.php b/src/Form/SignUpFormType.php index a216dc7..8767452 100644 --- a/src/Form/SignUpFormType.php +++ b/src/Form/SignUpFormType.php @@ -6,6 +6,7 @@ use App\Entity\User; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\PasswordType; +use Symfony\Component\Form\Extension\Core\Type\RepeatedType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Validator\Constraints\IsTrue; @@ -33,22 +34,13 @@ class SignUpFormType extends AbstractType { public function buildForm (FormBuilderInterface $builder, array $options): void { $builder ->add('email') - ->add('agreeTerms', CheckboxType::class, [ - 'mapped' => false, - 'constraints' => [ - new IsTrue( - [ - 'message' => 'You should agree to our terms.', - ] - ), - ], - ]) - ->add('plainPassword', PasswordType::class, [ + ->add('newPassword', RepeatedType::class, [ // instead of being set onto the object directly, // this is read and encoded in the controller - 'mapped' => false, - 'attr' => ['autocomplete' => 'new-password'], - 'constraints' => [ + 'type' => PasswordType::class, + 'mapped' => false, + 'attr' => ['autocomplete' => 'new-password'], + 'constraints' => [ new NotBlank( [ 'message' => 'Please enter a password', @@ -63,6 +55,22 @@ class SignUpFormType extends AbstractType { ] ), ], + 'first_options' => [ + 'label' => 'Password', + ], + 'second_options' => [ + 'label' => 'Password confirmation', + ], + ]) + ->add('agreeTerms', CheckboxType::class, [ + 'mapped' => false, + 'constraints' => [ + new IsTrue( + [ + 'message' => 'You should agree to our terms.', + ] + ), + ], ]); } } diff --git a/src/Security/UserChecker.php b/src/Security/UserChecker.php index 5563556..6d96073 100644 --- a/src/Security/UserChecker.php +++ b/src/Security/UserChecker.php @@ -19,6 +19,9 @@ class UserChecker implements UserCheckerInterface { return; } + if (!$user->isVerified()) { + throw new CustomUserMessageAccountStatusException('Your account mail has not been validated.'); + } if ($user->getValidationAdministrator() === null || $user->getValidationDate() === null) { throw new CustomUserMessageAccountStatusException('Your account has not been validated by an administrator yet.'); } diff --git a/templates/base.html.twig b/templates/base.html.twig index 6043255..7bbfdd1 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -7,14 +7,14 @@