Commit 4de17b1a by Julien Jorry

[IMPORTANT] Fix bug with multiple flux form submit (fix front + fix csrf token)

parent fab29c95
...@@ -141,6 +141,7 @@ function showConfirmTransactionModal(div, form, montant, destinataire = null) { ...@@ -141,6 +141,7 @@ function showConfirmTransactionModal(div, form, montant, destinataire = null) {
// Bind modal validation button with form submition // Bind modal validation button with form submition
$('#confirmTransactionModal #confirmTransactionButton').off() $('#confirmTransactionModal #confirmTransactionButton').off()
$('#confirmTransactionModal #confirmTransactionButton').on('click', function(e){ $('#confirmTransactionModal #confirmTransactionButton').on('click', function(e){
$(this).attr('disabled', true)
form.submit() form.submit()
}); });
} }
...@@ -208,6 +209,7 @@ jQuery(document).ready(function() { ...@@ -208,6 +209,7 @@ jQuery(document).ready(function() {
$('.transactionSubmit').on('click', function(e){ $('.transactionSubmit').on('click', function(e){
// Stop form submition // Stop form submition
e.preventDefault(); e.preventDefault();
$(this).attr('disabled', true);
var form = this.closest('form') var form = this.closest('form')
if (form.checkValidity()) { if (form.checkValidity()) {
...@@ -234,9 +236,19 @@ jQuery(document).ready(function() { ...@@ -234,9 +236,19 @@ jQuery(document).ready(function() {
} }
}); });
$('.fluxSubmit').on('click', function(e){
// Stop form submition
e.preventDefault();
$(this).attr('disabled', true);
var form = this.closest('form')
form.submit()
});
$('.cotisationMLCSubmit').on('click', function(e){ $('.cotisationMLCSubmit').on('click', function(e){
// Stop form submition // Stop form submition
e.preventDefault(); e.preventDefault();
$(this).attr('disabled', true);
var form = this.closest('form') var form = this.closest('form')
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
"app": { "app": {
"js": [ "js": [
"/build/runtime.6ad5c9da.js", "/build/runtime.6ad5c9da.js",
"/build/app.498d6ed6.js" "/build/app.61c44411.js"
], ],
"css": [ "css": [
"/build/app.1fb37df4.css" "/build/app.1fb37df4.css"
......
{ {
"build/app.css": "/build/app.1fb37df4.css", "build/app.css": "/build/app.1fb37df4.css",
"build/app.js": "/build/app.498d6ed6.js", "build/app.js": "/build/app.61c44411.js",
"build/admin.css": "/build/admin.87a6bc21.css", "build/admin.css": "/build/admin.87a6bc21.css",
"build/admin.js": "/build/admin.15535d30.js", "build/admin.js": "/build/admin.15535d30.js",
"build/runtime.js": "/build/runtime.6ad5c9da.js", "build/runtime.js": "/build/runtime.6ad5c9da.js",
......
...@@ -41,6 +41,7 @@ use Symfony\Component\HttpFoundation\Session\SessionInterface; ...@@ -41,6 +41,7 @@ use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Translation\TranslatorInterface; use Symfony\Component\Translation\TranslatorInterface;
...@@ -100,7 +101,8 @@ class FluxController extends AbstractController ...@@ -100,7 +101,8 @@ class FluxController extends AbstractController
Environment $templating, Environment $templating,
OperationUtils $operationUtils, OperationUtils $operationUtils,
TokenGeneratorInterface $tokenGenerator, TokenGeneratorInterface $tokenGenerator,
ValidatorInterface $validator ValidatorInterface $validator,
CsrfTokenManagerInterface $tokenManager
) { ) {
$this->security = $security; $this->security = $security;
$this->em = $em; $this->em = $em;
...@@ -115,6 +117,7 @@ class FluxController extends AbstractController ...@@ -115,6 +117,7 @@ class FluxController extends AbstractController
$this->operationUtils = $operationUtils; $this->operationUtils = $operationUtils;
$this->tokenGenerator = $tokenGenerator; $this->tokenGenerator = $tokenGenerator;
$this->validator = $validator; $this->validator = $validator;
$this->tokenManager = $tokenManager;
} }
protected function manageFluxForm(Request $request, Form $form, $template = '@kohinos/flux/transaction.html.twig', $params = []) protected function manageFluxForm(Request $request, Form $form, $template = '@kohinos/flux/transaction.html.twig', $params = [])
...@@ -128,7 +131,13 @@ class FluxController extends AbstractController ...@@ -128,7 +131,13 @@ class FluxController extends AbstractController
// return new Response('', Response::HTTP_BAD_REQUEST); // return new Response('', Response::HTTP_BAD_REQUEST);
// } // }
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && !$this->tokenManager->isTokenValid($this->tokenManager->getToken("flux_form"))) {
$referer = $request->headers->get('referer');
return $this->redirect($referer);
}
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$this->tokenManager->refreshToken("flux_form");
$flux = $form->getData(); $flux = $form->getData();
// try { // try {
if ($this->operationUtils->executeOperations($flux)) { if ($this->operationUtils->executeOperations($flux)) {
......
...@@ -91,6 +91,9 @@ class FluxFormType extends AbstractType ...@@ -91,6 +91,9 @@ class FluxFormType extends AbstractType
]) ])
->add('save', SubmitType::class, [ ->add('save', SubmitType::class, [
'label' => 'Valider', 'label' => 'Valider',
'attr' => [
'class' => 'btn-primary btn fluxSubmit',
],
]) ])
->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) { ->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
$flux = $event->getData(); $flux = $event->getData();
...@@ -109,8 +112,12 @@ class FluxFormType extends AbstractType ...@@ -109,8 +112,12 @@ class FluxFormType extends AbstractType
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
{ {
$resolver->setDefaults([ $resolver->setDefaults([
'attr' => ['class' => 'flux_form'],
'data_class' => Flux::class, 'data_class' => Flux::class,
'cascade_validation' => true, 'cascade_validation' => true,
'csrf_protection' => true,
'csrf_field_name' => '_token_kohinos',
'csrf_token_id' => 'flux_form',
]); ]);
} }
......
...@@ -23,9 +23,13 @@ ...@@ -23,9 +23,13 @@
{% for operation in operations %} {% for operation in operations %}
<tr> <tr>
<td><span data-toggle="tooltip" data-placement="bottom" title="{{ operation.createdAt|date('d/m/Y H:i') }}">{{ operation.createdAt|date('d/m/Y') }}</span></td> <td><span data-toggle="tooltip" data-placement="bottom" title="{{ operation.createdAt|date('d/m/Y H:i') }}">{{ operation.createdAt|date('d/m/Y') }}</span></td>
<td>{{ ((isCurrentAccountable(app.user, operation.flux.expediteur) ? 'exp' : 'des')~'_'~operation.flux.parenttype)|trans({}, 'flux') }}</td> <td>{{ ((isCurrentAccountable(app.user, operation.flux.expediteur) ? 'exp' : 'des')~'_'~operation.flux.parenttype)|trans({}, 'flux') }}
<div id='operationInfo{{loop.index}}' class='collapse operationInfo{{loop.index}}'>
Référence : {{ operation.flux.reference }}
</div>
</td>
<td> <td>
<span style='cursor:pointer;' data-toggle="collapse" data-target="#operationInfo{{loop.index}}"> <span style='cursor:pointer;' data-toggle="collapse" data-target=".operationInfo{{loop.index}}">
{% if not isCurrentAccountable(app.user, operation.flux.expediteur) %} {% if not isCurrentAccountable(app.user, operation.flux.expediteur) %}
{{ operation.flux.expediteur }} {{ operation.flux.expediteur }}
{% elseif not isCurrentAccountable(app.user, operation.flux.destinataire) %} {% elseif not isCurrentAccountable(app.user, operation.flux.destinataire) %}
...@@ -33,8 +37,7 @@ ...@@ -33,8 +37,7 @@
{% endif %} {% endif %}
<i class="fa fa-caret-down ml-2" aria-hidden="true"></i> <i class="fa fa-caret-down ml-2" aria-hidden="true"></i>
</span> </span>
<div id='operationInfo{{loop.index}}' class='collapse'> <div class='collapse operationInfo{{loop.index}}'>
Référence : {{ operation.flux.reference }}<br/>
Moyen : {{ operation.flux.moyen|trans }} Moyen : {{ operation.flux.moyen|trans }}
</div> </div>
</td> </td>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment