Fix sign up and sign in forms

master
Julien Rosset 1 year ago
parent 34fc4a466c
commit b9aed93c9d

@ -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 ###

2
.gitignore vendored

@ -24,3 +24,5 @@
/public/assets/
/assets/vendor/
###< symfony/asset-mapper ###
.symfony.local.yaml

@ -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';

@ -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": {

@ -1,5 +1,6 @@
twig:
default_path: '%kernel.project_dir%/templates'
form_themes: [ 'bootstrap_5_horizontal_layout.html.twig' ]
when@test:
twig:

@ -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

@ -0,0 +1,27 @@
<?php
declare(strict_types = 1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240514155807 extends AbstractMigration {
public function getDescription (): string {
return '';
}
public function up (Schema $schema): void {
// this up() migration is auto-generated, please modify it to your needs
$this->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');
}
}

@ -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')

@ -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<int, Tag> 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;
}

@ -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.',
]
),
],
]);
}
}

@ -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.');
}

@ -7,14 +7,14 @@
<nav class="navbar-light d-flex flex-column justify-content-start fixed-top">
<div class="d-flex justify-content-between w-100 px-2">
<!--region Website name-->
<a class="navbar-brand" href="/">
<a class="navbar-brand" href="{{ path('core_main') }}">
Web EDM
</a>
<!--endregion-->
<!--region menu-->
<div class="d-flex align-items-center">
<a href="#" class="me-3">Sign In</a>
<a href="#" class="me-3">Sign Up</a>
<a href="{{ path('user_signIn') }}" class="me-3">Sign In</a>
<a href="{{ path('user_signUp') }}" class="me-3">Sign Up</a>
</div>
<!--endregion-->
</div>

@ -5,5 +5,5 @@
{% block mainContent %}
<h1>Web EDM</h1>
<p>Welcome on Web EDM, the Web Electronic Document Manager.</p>
<p>Please <a href="#">Sign In</a> or <a href="#">Sign out</a> to start.</p>
<p>Please <a href="{{ path('user_signIn') }}">Sign In</a> or <a href="{{ path('user_signUp') }}">Sign Up</a> to start.</p>
{% endblock %}

@ -14,7 +14,7 @@
{% endblock %}
{% block bodyTag %}
<body id="page-{{ app.current_route }}">
<body id="page-{{ app.current_route }}" class="m-2">
{% endblock %}
{% block bodyContent %}
{% block headerTag %}

@ -6,26 +6,32 @@
<h1>Sign in</h1>
<form method="post">
{% if error %}
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
<div class="mb-3 alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
<label for="username">Email</label>
<input type="email" value="{{ last_username }}" name="_username" id="username" class="form-control" autocomplete="email" required autofocus>
<label for="password">Password</label>
<input type="password" name="_password" id="password" class="form-control" autocomplete="current-password" required>
<input type="hidden" name="_csrf_token"
value="{{ csrf_token('authenticate') }}"
>
<div class="checkbox mb-3">
<label>
<input type="checkbox" name="_remember_me" id="remember_me">
<label for="remember_me">Remember me</label>
</label>
<div class="mb-3 row">
<label for="username" class="col-form-label col-sm-2">Email</label>
<div class="col-sm-10">
<input type="email" value="{{ last_username }}" name="_username" id="username" class="form-control" autocomplete="email" required autofocus>
</div>
</div>
<div class="mb-3 row">
<label for="password" class="col-form-label col-sm-2">Password</label>
<div class="col-sm-10">
<input type="password" name="_password" id="password" class="form-control" autocomplete="current-password" required>
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-2"></div>
<div class="col-sm-10">
<div class="form-check">
<input type="checkbox" name="_remember_me" id="remember_me" class="form-check-input">
<label for="remember_me" class="form-check-label">Remember me</label>
</div>
</div>
</div>
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
<button class="btn btn-lg btn-primary" type="submit">Sign in</button>
</form>
{% endblock %}

@ -4,9 +4,8 @@
{% block mainContent %}
<h1>Sign up</h1>
<p>
NOTE : after confirming your account email, it must be also validated by an administrator
<strong>NOTE :</strong> after confirming your account email, it must be also validated by an administrator
<br>You'll receive an email when your account would be accepted
</p>
@ -14,11 +13,9 @@
{{ form_start(registrationForm) }}
{{ form_row(registrationForm.email) }}
{{ form_row(registrationForm.plainPassword, {
label: 'Password'
}) }}
{{ form_row(registrationForm.newPassword) }}
{{ form_row(registrationForm.agreeTerms) }}
<button type="submit" class="btn">Request account</button>
<button type="submit" class="btn btn-primary">Request account</button>
{{ form_end(registrationForm) }}
{% endblock %}

Loading…
Cancel
Save