From 3dc768ec27a7230600d5e9f816ac9bed5053a66c Mon Sep 17 00:00:00 2001 From: Ioannis Igoumenos Date: Fri, 25 Apr 2025 22:04:49 +0300 Subject: [PATCH] Fix redirects and state saves --- .../Controller/EmailVerifiersController.php | 29 ++++++++- .../element/emailVerifiers/verify.php | 25 +++----- app/src/Controller/AppController.php | 2 +- app/src/Lib/Traits/ApplicationStatesTrait.php | 61 +++++++------------ .../Model/Table/ApplicationStatesTable.php | 34 +++++++++++ app/templates/element/notify/blockUser.php | 3 +- 6 files changed, 95 insertions(+), 59 deletions(-) diff --git a/app/plugins/CoreEnroller/src/Controller/EmailVerifiersController.php b/app/plugins/CoreEnroller/src/Controller/EmailVerifiersController.php index 5e8e1e820..e05a16748 100644 --- a/app/plugins/CoreEnroller/src/Controller/EmailVerifiersController.php +++ b/app/plugins/CoreEnroller/src/Controller/EmailVerifiersController.php @@ -30,15 +30,18 @@ namespace CoreEnroller\Controller; use App\Controller\StandardEnrollerController; +use App\Lib\Enum\ApplicationStateEnum; use App\Lib\Enum\PetitionStatusEnum; +use App\Lib\Traits\ApplicationStatesTrait; use App\Lib\Util\StringUtilities; use Cake\Http\Exception\BadRequestException; -use Cake\I18n\FrozenTime; use Cake\ORM\TableRegistry; use CoreEnroller\Lib\Enum\VerificationModeEnum; use \App\Lib\Enum\HttpStatusCodesEnum; class EmailVerifiersController extends StandardEnrollerController { + use ApplicationStatesTrait; + public $paginate = [ 'order' => [ 'EmailVerifiers.id' => 'asc' @@ -125,6 +128,10 @@ public function resend($id) { */ public function dispatch(string $id) { + $request = $this->getRequest(); + $session = $request->getSession(); + $username = $session->read('Auth.external.user'); + $op = $this->requestParam('op'); if(!$op) { @@ -140,6 +147,7 @@ public function dispatch(string $id) { $candidateAddresses = $this->EmailVerifiers->assembleVerifiableAddresses($cfg, $petition); $this->set('vv_config', $cfg); + $this->set('controller', $this); $this->set('vv_email_addresses', $candidateAddresses); // To make things easier for the view, we'll create a separate view var with the @@ -241,7 +249,24 @@ public function dispatch(string $id) { catch(\Exception $e) { $this->llog('error', $e->getMessage()); $this->Flash->error($e->getMessage()); - } + + if ($e->getMessage() === __d('error', 'Verifications.code')) { + // Add a flag to the session to instruct the UI to handle blocking. + $this->request->getSession()->write('verification_error', 1); + // Get preferences if we have an Auth.User.co_person_id + if(!empty($username)) { + $ApplicationStates = $this->fetchTable('ApplicationStates'); + $columnStatement = $this->viewBuilder()->getVar('vv_person_id') === null ? 'person_id IS' : 'person_id'; + $data = [ + 'tag' => ApplicationStateEnum::VerifyEmailBlocked, + 'username' => $username, + 'co_id' => $this->getCOID(), + $columnStatement => $this->viewBuilder()->getVar('vv_person_id') ?? null + ]; + $ApplicationStates->createOrUpdate($data, 'lock'); + } + } + } } else { // Generate a Verification request, then render a form to collect it. // If there is already a pending request, overwrite it (generate a new code). diff --git a/app/plugins/CoreEnroller/templates/element/emailVerifiers/verify.php b/app/plugins/CoreEnroller/templates/element/emailVerifiers/verify.php index ae443a6bc..63d5ecd30 100644 --- a/app/plugins/CoreEnroller/templates/element/emailVerifiers/verify.php +++ b/app/plugins/CoreEnroller/templates/element/emailVerifiers/verify.php @@ -31,10 +31,17 @@ use App\Lib\Util\StringUtilities; use Cake\Routing\Router; -if (filter_var($vv_config->enable_blockonfailure, FILTER_VALIDATE_BOOLEAN)) { + +$session = $this->getRequest()->getSession(); +$hasVerificationError = $session->read('verification_error') ?? 0; // Replace 'keyName' with the actual session key you want to access +if ( + filter_var($vv_config->enable_blockonfailure, FILTER_VALIDATE_BOOLEAN) + && filter_var($hasVerificationError, FILTER_VALIDATE_BOOLEAN) +) { + $session->delete('verification_error'); $stateAttr = ApplicationStateEnum::VerifyEmailBlocked; - $appStateValue = $this->ApplicationState->getValue($stateAttr, 'lock'); - $appStateId = $this->ApplicationState->getId($stateAttr); + $appStateValue = $this->ApplicationState->getValue($stateAttr, 'lock', true); + $appStateId = $this->ApplicationState->getId($stateAttr, true); if ($vv_attempts_count > 0 && $appStateValue !== 'unlock') { $currentUrl = Router::url(null, true); @@ -46,18 +53,6 @@ )); return; } - - // Reset the locker - if ($appStateValue !== 'lock') { - $data = [ - 'tag' => $stateAttr, - 'value' => 'lock', - 'username' => $vv_user['username'] ?? '', - 'co_id' => $vv_cur_co->id, - 'person_id' => $vv_person_id ?? $vv_user_roles["person_id"] ?? null - ]; - $this->ApplicationState->updateState($data, (int)$appStateId); - } } $this->Field->enableFormEditMode(); diff --git a/app/src/Controller/AppController.php b/app/src/Controller/AppController.php index 393a0ab9f..2efcf0452 100644 --- a/app/src/Controller/AppController.php +++ b/app/src/Controller/AppController.php @@ -384,7 +384,7 @@ protected function primaryLinkLookup(): void * - postcondition: Application Preferences variable set * @since COmanage Registry v5.1.0 */ - protected function getAppPrefs() { + public function getAppPrefs() { $request = $this->getRequest(); $session = $request->getSession(); diff --git a/app/src/Lib/Traits/ApplicationStatesTrait.php b/app/src/Lib/Traits/ApplicationStatesTrait.php index ec9e468d7..c9e315458 100644 --- a/app/src/Lib/Traits/ApplicationStatesTrait.php +++ b/app/src/Lib/Traits/ApplicationStatesTrait.php @@ -30,7 +30,7 @@ namespace App\Lib\Traits; use Cake\Collection\Collection; -use Cake\ORM\Table; +use Cake\Controller\ControllerFactory; use Cake\ORM\TableRegistry; trait ApplicationStatesTrait @@ -50,16 +50,22 @@ public function constructComplexStateTag(array $nameParts): string } /** - * @param string $stateTag - * @param string|int $defaultValue - * + * @param string $stateTag + * @param string|int $defaultValue + * @param bool $invalidate * @return string * @since COmanage Registry v5.1.0 */ - public function getValue(string $stateTag, string|int $defaultValue): string + public function getValue(string $stateTag, string|int $defaultValue, $invalidate = false): string { $vv_app_prefs = []; - if(method_exists($this, 'getView')) { + + if ($invalidate) { + // View, refetch + $curController = $this->getView()->get('controller'); + $curController->getAppPrefs(); + $vv_app_prefs = $curController->viewBuilder()->getVar('vv_app_prefs'); + } elseif(method_exists($this, 'getView')) { // View $vv_app_prefs = $this->getView()?->get('vv_app_prefs'); } elseif(method_exists($this, 'viewBuilder')) { @@ -79,15 +85,21 @@ public function getValue(string $stateTag, string|int $defaultValue): string } /** - * @param string $stateTag - * + * @param string $stateTag + * @param bool $invalidate * @return string * @since COmanage Registry v5.1.0 */ - public function getId(string $stateTag): string + public function getId(string $stateTag, $invalidate = false): string { $vv_app_prefs = []; - if(method_exists($this, 'getView')) { + + if ($invalidate) { + // View, refetch + $curController = $this->getView()->get('controller'); + $curController->getAppPrefs(); + $vv_app_prefs = $curController->viewBuilder()->getVar('vv_app_prefs'); + } elseif(method_exists($this, 'getView')) { // View $vv_app_prefs = $this->getView()?->get('vv_app_prefs'); } elseif(method_exists($this, 'viewBuilder')) { @@ -105,33 +117,4 @@ public function getId(string $stateTag): string return (string)$appStateId; } - - - /** - * Update or create a state record in the ApplicationStates table. - * - * @param array $data The data to be saved. - * @param int|null $id The ID of the record to update, or null to create a new record. - * - * @return void - * @throws \Cake\ORM\Exception\PersistenceFailedException When the save operation fails. - * @since COmanage Registry v5.2.0 - */ - public function updateState(array $data, ?int $id): void - { - $appstate = TableRegistry::getTableLocator()->get('ApplicationStates'); - If ($id !== null) { - // Update existing record - $record = $appstate - ->find() - ->where(['id' => $id]) - ->first(); - $record->set($data); - $appstate->saveOrFail($record); - } else { - $newRecord = $appstate->newEntity($data); - // Create new entry - $appstate->saveOrFail($newRecord); - } - } } \ No newline at end of file diff --git a/app/src/Model/Table/ApplicationStatesTable.php b/app/src/Model/Table/ApplicationStatesTable.php index 77cf110ac..6843c2f3c 100644 --- a/app/src/Model/Table/ApplicationStatesTable.php +++ b/app/src/Model/Table/ApplicationStatesTable.php @@ -29,6 +29,7 @@ namespace App\Model\Table; +use App\Lib\Enum\ApplicationStateEnum; use Cake\Database\Expression\QueryExpression; use Cake\ORM\Query; use Cake\ORM\Table; @@ -141,4 +142,37 @@ public function retrieveAll(string $username, ?int $coid, ?int $personid): array return $tags ?? []; } + + + /** + * Create or update an application state. + * + * This method either updates an existing application state record or creates + * a new one based on the provided data and value. + * + * @param array $data Associative array containing fields and their values. + * @param string $value Value to set for the application state. + * @return void + * @throws \Cake\ORM\Exception\PersistenceFailedException When a save operation fails. + * @since COmanage Registry v5.2.0 + */ + public function createOrUpdate(array $data, string $value): void + { + $appId = $this->find() + ->cache(false) + ->where($data)->first(); + + // Enter the new value + $data['value'] = $value; + + If ($appId->id !== null) { + // Update existing record + $appId->set($data); + $this->saveOrFail($appId); + } else { + $newRecord = $this->newEntity($data); + // Create new entry + $this->saveOrFail($newRecord); + } + } } \ No newline at end of file diff --git a/app/templates/element/notify/blockUser.php b/app/templates/element/notify/blockUser.php index 71fc8024e..70966ca9d 100644 --- a/app/templates/element/notify/blockUser.php +++ b/app/templates/element/notify/blockUser.php @@ -14,6 +14,7 @@ #main { align-content: center; } + #flash-messages, .page-title-container { display: none; } @@ -99,8 +100,6 @@ $('#count-down-container'), true ); - // Reload the page - // window.location.replace(reloadUrl); } }, 1000);