diff --git a/webapp/src/Form/User/ChangePasswordFormType.php b/webapp/src/Form/User/ChangePasswordFormType.php new file mode 100644 index 0000000000000000000000000000000000000000..630166fbe3477f651c449956d7388126c402c8c2 --- /dev/null +++ b/webapp/src/Form/User/ChangePasswordFormType.php @@ -0,0 +1,112 @@ +<?php + +/* + * This file is part of the Comptoir-du-Libre software. + * <https://gitlab.adullact.net/Comptoir/comptoir-du-libre> + * + * Copyright (c) ADULLACT <https://adullact.org> + * Association des Développeurs et Utilisateurs de Logiciels Libres + * pour les Administrations et les Collectivités Territoriales + * + * Comptoir-du-Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You should have received a copy of the GNU Affero General Public License + * along with this software. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>. + */ + +declare(strict_types=1); + +namespace App\Form\User; + +use Symfony\Component\Form\AbstractType; +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\Translation\TranslatableMessage; +use Symfony\Component\Validator\Constraints\Length; +use Symfony\Component\Validator\Constraints\NotBlank; + +class ChangePasswordFormType extends AbstractType +{ + public function buildForm(FormBuilderInterface $builder, array $options): void + { + $builder + ->add('currentPlainPassword', PasswordType::class, [ + // instead of being set onto the object directly, + // this is read and encoded in the controller + 'mapped' => false, + 'attr' => ['autocomplete' => 'new-password'], + 'label' => 'user.change_password.form.label.current-password', + 'help' => 'user.change_password.form.label.current-password.help', + 'constraints' => [ + new NotBlank([ + 'message' => 'common.validator.help.field.error.required', + ]), + new Length([ + // max length allowed by Symfony for security reasons + 'max' => 4096, + ]), + ], + ]) + ->add('newPlainPassword', RepeatedType::class, [ + 'type' => PasswordType::class, + 'options' => [ + 'attr' => [ + 'autocomplete' => 'new-password', + 'minlength' => $options['min_password_length'], + 'maxlength' => 4096, // max length allowed by Symfony for security reasons + ], + ], + 'first_options' => [ + 'constraints' => [ + new NotBlank([ + 'message' => 'common.validator.help.field.error.required', + ]), + new Length([ + 'min' => $options['min_password_length'], +// 'minMessage' => 'Password should be at least {{ limit }} characters', + 'minMessage' => new TranslatableMessage( + message: 'common.validator.help.password.error.too-short', + ), + 'max' => 4096, // max length allowed by Symfony for security reasons + ]), + ], + 'label' => 'user.change_password.form.label.new-password', + 'help_html' => true, + 'help' => new TranslatableMessage( + message: 'user.change_password.form.label.new-password.help', + parameters: ['%min_password_length%' => $options['min_password_length']], + domain: 'messages' + ), + ], + 'second_options' => [ + 'label' => 'user.change_password.form.label.new-password-repeat', + 'help' => 'user.change_password.form.label.new-password-repeat.help', + ], + 'invalid_message' => 'common.validator.help.password.error.new-password-must-match', + // Instead of being set onto the object directly, + // this is read and encoded in the controller + 'mapped' => false, + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'min_password_length' => 16, + // enable/disable CSRF protection for this form + 'csrf_protection' => true, + // the name of the hidden HTML field that stores the token + 'csrf_field_name' => 'csrf_token_ChangePassword', + // an arbitrary string used to generate the value of the token + // using a different string for each form improves its security + 'csrf_token_id' => 'task_ChangePasswordFormType', + ]); + $resolver->setAllowedTypes('min_password_length', 'int'); + } +} diff --git a/webapp/src/Form/User/ResetPasswordFormType.php b/webapp/src/Form/User/ResetPasswordFormType.php new file mode 100644 index 0000000000000000000000000000000000000000..aea5b5e16265272cbb56e0a316a2312a5dcaeb21 --- /dev/null +++ b/webapp/src/Form/User/ResetPasswordFormType.php @@ -0,0 +1,98 @@ +<?php + +/* + * This file is part of the Comptoir-du-Libre software. + * <https://gitlab.adullact.net/Comptoir/comptoir-du-libre> + * + * Copyright (c) ADULLACT <https://adullact.org> + * Association des Développeurs et Utilisateurs de Logiciels Libres + * pour les Administrations et les Collectivités Territoriales + * + * Comptoir-du-Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You should have received a copy of the GNU Affero General Public License + * along with this software. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>. + */ + +declare(strict_types=1); + +namespace App\Form\User; + +use App\Entity\User; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\EmailType; +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\Translation\TranslatableMessage; +use Symfony\Component\Validator\Constraints\Length; +use Symfony\Component\Validator\Constraints\NotBlank; +use Symfony\Component\Validator\Constraints\Email; + +class ResetPasswordFormType extends AbstractType +{ + public function buildForm(FormBuilderInterface $builder, array $options): void + { + $builder + ->add('newPlainPassword', RepeatedType::class, [ + 'type' => PasswordType::class, + 'options' => [ + 'attr' => [ + 'autocomplete' => 'new-password', + 'minlength' => $options['min_password_length'], + 'maxlength' => 4096, // max length allowed by Symfony for security reasons + ], + ], + 'first_options' => [ + 'constraints' => [ + new NotBlank([ + 'message' => 'common.validator.help.field.error.required', + ]), + new Length([ + 'min' => $options['min_password_length'], +// 'minMessage' => 'Password should be at least {{ limit }} characters', + 'minMessage' => new TranslatableMessage( + message: 'common.validator.help.password.error.too-short', + ), + 'max' => 4096, // max length allowed by Symfony for security reasons + ]), + ], + 'label' => 'forgot_password.form.label.new-password', + 'help_html' => true, + 'help' => new TranslatableMessage( + message: 'forgot_password.form.label.new-password.help', + parameters: ['%min_password_length%' => $options['min_password_length']], + domain: 'messages' + ), + ], + 'second_options' => [ + 'label' => 'forgot_password.form.label.new-password-repeat', + 'help' => 'forgot_password.form.label.new-password-repeat.help', + ], + 'invalid_message' => 'common.validator.help.password.error.new-password-must-match', + // Instead of being set onto the object directly, + // this is read and encoded in the controller + 'mapped' => false, + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'min_password_length' => 16, + // enable/disable CSRF protection for this form + 'csrf_protection' => true, + // the name of the hidden HTML field that stores the token + 'csrf_field_name' => 'csrf_token_ResetPassword', + // an arbitrary string used to generate the value of the token + // using a different string for each form improves its security + 'csrf_token_id' => 'task_ResetPasswordFormType', + ]); + $resolver->setAllowedTypes('min_password_length', 'int'); + } +} diff --git a/webapp/src/Form/User/ResetPasswordRequestFormType.php b/webapp/src/Form/User/ResetPasswordRequestFormType.php new file mode 100644 index 0000000000000000000000000000000000000000..7332e69f5b9bf2168c26308f42d95fb3a9ec650f --- /dev/null +++ b/webapp/src/Form/User/ResetPasswordRequestFormType.php @@ -0,0 +1,65 @@ +<?php + +/* + * This file is part of the Comptoir-du-Libre software. + * <https://gitlab.adullact.net/Comptoir/comptoir-du-libre> + * + * Copyright (c) ADULLACT <https://adullact.org> + * Association des Développeurs et Utilisateurs de Logiciels Libres + * pour les Administrations et les Collectivités Territoriales + * + * Comptoir-du-Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You should have received a copy of the GNU Affero General Public License + * along with this software. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>. + */ + +declare(strict_types=1); + +namespace App\Form\User; + +use App\Entity\User; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\EmailType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Validator\Constraints\NotBlank; +use Symfony\Component\Validator\Constraints\Email; + +class ResetPasswordRequestFormType extends AbstractType +{ + public function buildForm(FormBuilderInterface $builder, array $options): void + { + $builder + ->add('email', EmailType::class, [ + 'label' => 'forgot_password.request.form.label.email', + 'help' => 'forgot_password.request.form.label.email.help', + 'constraints' => [ + new NotBlank([ + 'message' => 'common.validator.help.field.error.required', + ]), + new Email([ + 'mode' => 'html5', + 'message' => 'common.validator.help.email.error.not-valid', + ]), + ], + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + // enable/disable CSRF protection for this form + 'csrf_protection' => true, + // the name of the hidden HTML field that stores the token + 'csrf_field_name' => 'csrf_token_ResetPasswordRequest', + // an arbitrary string used to generate the value of the token + // using a different string for each form improves its security + 'csrf_token_id' => 'task_ResetPasswordRequestFormType', + ]); + } +}