From f1ba948a3a5b5c000c0193b29578f33e0e9d1da2 Mon Sep 17 00:00:00 2001 From: Dave Mc Nicoll Date: Tue, 27 Oct 2026 18:23:43 +0000 Subject: [PATCH] - Removed CSRF form validation from FormHandler / added to FormContext formExecute method. - CRSF tokens are now consumed if a form return execute value is (bool) true, preventing double form send --- src/Method/FormContext.php | 22 ++++++++++++++++++++++ src/Method/FormHandler.php | 4 ++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Method/FormContext.php b/src/Method/FormContext.php index 647e3f7..5d6c773 100644 --- a/src/Method/FormContext.php +++ b/src/Method/FormContext.php @@ -76,6 +76,17 @@ class FormContext implements FormContextInterface return true; } + public function formExecute($returnValue) : void + { + $this->formExecutionStatus = $returnValue; + $this->formExecuted = true; + + if ($returnValue) { + $this->consumeCsrfToken(); + } + } + + public function executed() : bool { return $this->formExecutionStatus === false ? false : $this->formExecuted; @@ -109,6 +120,17 @@ class FormContext implements FormContextInterface return $this->formExecutionStatus; } + public function consumeCsrfToken() { + if (! $this->formSkipCsrf) { + $token = $this->get('picea-ui-form')[$this->formName] ?? false; + + if ( $token ) { + # token is consumed + $_SESSION["picea-ui.form:{$this->formName}"] = array_diff($_SESSION["picea-ui.form:{$this->formName}"], [ $token ]); + } + } + } + public function getRequest() : ServerRequestInterface { return $this->formContextRequest; diff --git a/src/Method/FormHandler.php b/src/Method/FormHandler.php index 6f9d8ed..d8edb28 100644 --- a/src/Method/FormHandler.php +++ b/src/Method/FormHandler.php @@ -50,8 +50,8 @@ class FormHandler { if ( $this->sent && $this->context->formSent() ) { if ( $this->validationStatus = $this->form->validate($this->context) ) { - $this->context->formExecutionStatus = $this->executionStatus = $this->form->execute($this->context); - $this->context->formExecuted = true; + $this->executionStatus = $this->form->execute($this->context); + $this->context->formExecute($this->executionStatus); } } }