feat/cnx_api #11

Merged
maurine merged 15 commits from feat/cnx_api into main 2026-03-30 12:08:52 +02:00
3 changed files with 147 additions and 0 deletions
Showing only changes of commit 3dcba06f20 - Show all commits

View File

@@ -0,0 +1,50 @@
<?php
namespace App\Form;
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\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
class ChangePasswordType extends AbstractType
{
# Mise en place du formulaire de changement de mot de passe
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('oldPassword', PasswordType::class, [
'label' => 'Ancien mot de passe',
'mapped' => false,
])
->add('newPassword', RepeatedType::class, [
'type' => PasswordType::class,
'mapped' => false,
'first_options' => ['label' => 'Nouveau mot de passe'],
'second_options' => ['label' => 'Confirmer mot de passe'],
# Mise en place de contraintes dans la saisie du mot de passe
'constraints' => [
new NotBlank([
'message' => 'Veuillez saisir un mot de passe',
]),
new Length([
'min' => 8,
'minMessage' => 'Votre mot de passe doit faire au moins {{ limit }} caractères',
'max' => 4096,
]),
],
])
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
// Configure your form options here
]);
}
}

View File

@@ -0,0 +1,60 @@
<?php
namespace App\Security;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\SecurityRequestAttributes;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
class AppCustomAuthenticator extends AbstractLoginFormAuthenticator
{
use TargetPathTrait;
public const LOGIN_ROUTE = 'app_login';
public function __construct(private UrlGeneratorInterface $urlGenerator)
{
}
public function authenticate(Request $request): Passport
{
$email = $request->getPayload()->getString('email');
$request->getSession()->set(SecurityRequestAttributes::LAST_USERNAME, $email);
return new Passport(
new UserBadge($email),
new PasswordCredentials($request->getPayload()->getString('password')),
[
new CsrfTokenBadge('authenticate', $request->getPayload()->getString('_csrf_token')),
new RememberMeBadge(),
]
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
return new RedirectResponse($targetPath);
}
// For example:
// return new RedirectResponse($this->urlGenerator->generate('some_route'));
throw new \Exception('TODO: provide a valid redirect inside '.__FILE__);
}
protected function getLoginUrl(Request $request): string
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
}

View File

@@ -0,0 +1,37 @@
{# templates/user/edit_password.html.twig #}
{% extends 'base.html.twig' %}
{% block title %}Modifier mon mot de passe | {{ parent() }}{% endblock %}
{% block body %}
<div class="min-h-screen bg-bg-primary flex items-center justify-center p-4">
<div class="max-w-md w-full bg-white rounded-2xl shadow-xl p-8 border-t-4 border-brand-teal">
<h1 class="font-title text-4xl text-brand-dark mb-6 text-center">
Sécurité du compte
</h1>
{{ form_start(form) }}
<div class="space-y-4">
{# Champ Ancien Mot de Passe #}
<div>
{{ form_label(form.oldPassword, null, {'label_attr': {'class': 'block text-sm font-medium text-gray-700 mb-1'}}) }}
{{ form_widget(form.oldPassword, {'attr': {'class': 'w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-brand-teal focus:border-transparent outline-none transition-all'}}) }}
{{ form_errors(form.oldPassword) }}
</div>
{# Champs Nouveau Mot de Passe (RepeatedType) #}
<div class="space-y-4">
{{ form_row(form.newPassword.first, {'attr': {'class': 'w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-brand-teal outline-none'}}) }}
{{ form_row(form.newPassword.second, {'attr': {'class': 'w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-brand-teal outline-none'}}) }}
</div>
<button type="submit" class="w-full bg-brand-teal text-brand-dark font-bold py-3 rounded-lg hover:bg-opacity-90 transition-colors shadow-md mt-6">
Mettre à jour mon mot de passe
</button>
</div>
{{ form_end(form) }}
</div>
</div>
{% endblock %}