✨ feat(security): Ajoute réinitialisation mot de passe, robots.txt, et traductions.
Ajoute la fonctionnalité de réinitialisation de mot de passe, met à jour le
robots.txt, et ajoute des traductions en français et en anglais.
```
101 lines
4.4 KiB
Twig
101 lines
4.4 KiB
Twig
{% extends 'base.twig' %}
|
|
|
|
{% block title %}{{ 'events.reset_password'|trans }}{% endblock %}
|
|
{% block meta_description %}{{ 'events.reset_password'|trans }}{% endblock %}
|
|
|
|
{% block canonical_url %}<link rel="canonical" href="{{ url('app_forgot_password_confirm', {id: id, token: token}) }}" />{% endblock %}
|
|
{% block breadcrumb_schema %}
|
|
<script type="application/ld+json">
|
|
{
|
|
"@context": "https://schema.org",
|
|
"@type": "BreadcrumbList",
|
|
"itemListElement": [
|
|
{
|
|
"@type": "ListItem",
|
|
"position": 1,
|
|
"name": "{{ 'breadcrumb.home'|trans }}",
|
|
"item": "{{ app.request.schemeAndHttpHost }}"
|
|
},
|
|
{
|
|
"@type": "ListItem",
|
|
"position": 2,
|
|
"name": "{{ 'breadcrumb.reset_password'|trans }}",
|
|
"item": "{{ app.request.schemeAndHttpHost }}{{ app.request.pathInfo }}"
|
|
}
|
|
]
|
|
}
|
|
</script>
|
|
{% endblock %}
|
|
|
|
{% block body %}
|
|
<div class="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
|
|
<div class="max-w-md w-full space-y-8 p-10 bg-white rounded-xl shadow-lg">
|
|
|
|
<h2 class="mt-6 text-center text-3xl font-extrabold text-gray-900">
|
|
{{ 'events.reset_password'|trans }}
|
|
</h2>
|
|
|
|
<p class="mt-2 text-center text-sm text-gray-600">
|
|
{{ 'text.enter_new_password'|trans }}
|
|
</p>
|
|
|
|
{# Affichage des messages flash (ex: token expiré ou invalide) #}
|
|
{% for flash_error in app.flashes('reset_password_error') %}
|
|
<div class="p-4 text-sm text-red-700 bg-red-100 rounded-lg" role="alert">
|
|
{{ flash_error }}
|
|
</div>
|
|
{% endfor %}
|
|
|
|
{# Le formulaire Symfony #}
|
|
{{ form_start(form, {'attr': {'class': 'mt-8 space-y-6'}}) }}
|
|
|
|
<div class="rounded-md shadow-sm -space-y-px">
|
|
{# Champ Nouveau Mot de Passe (first) #}
|
|
{# On suppose que form.plainPassword est un RepeatedType avec un champ 'first' et 'second' #}
|
|
|
|
<div>
|
|
{{ form_label(form.password.first, 'label.new_password'|trans, {'label_attr': {'class': 'sr-only'}}) }}
|
|
{{ form_widget(form.password.first, {
|
|
'attr': {
|
|
'class': 'appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm',
|
|
'placeholder': 'label.new_password'|trans,
|
|
'autocomplete': 'new-password',
|
|
'required': 'required'
|
|
}
|
|
}) }}
|
|
{{ form_errors(form.password.first) }}
|
|
</div>
|
|
|
|
{# Champ Confirmation Mot de Passe (second) #}
|
|
<div>
|
|
{{ form_label(form.password.second, 'label.confirm_password'|trans, {'label_attr': {'class': 'sr-only'}}) }}
|
|
{{ form_widget(form.password.second, {
|
|
'attr': {
|
|
'class': 'appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm',
|
|
'placeholder': 'label.confirm_password'|trans,
|
|
'autocomplete': 'new-password',
|
|
'required': 'required'
|
|
}
|
|
}) }}
|
|
{{ form_errors(form.password.second) }}
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{# Affichage des erreurs globales du formulaire #}
|
|
{{ form_errors(form) }}
|
|
|
|
{# Bouton Soumettre #}
|
|
<div>
|
|
<button type="submit"
|
|
class="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
|
{{ 'button.reset_password'|trans }}
|
|
</button>
|
|
</div>
|
|
|
|
{{ form_end(form) }}
|
|
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|