diff --git a/administrator/components/com_fields/src/Model/FieldModel.php b/administrator/components/com_fields/src/Model/FieldModel.php index 18e2d8b5aefb3..376abe272296c 100644 --- a/administrator/components/com_fields/src/Model/FieldModel.php +++ b/administrator/components/com_fields/src/Model/FieldModel.php @@ -997,9 +997,11 @@ protected function loadFormData() public function validate($form, $data, $group = null) { // Check if the values are unique. This should only apply for list, checkboxes and radio custom field types - if (\in_array($data['type'], ['list', 'checkboxes', 'radio']) + if ( + \in_array($data['type'], ['list', 'checkboxes', 'radio']) && !empty($data['fieldparams']['options']) - && \is_array($data['fieldparams']['options'])) { + && \is_array($data['fieldparams']['options']) + ) { $tmpValues = []; foreach ($data['fieldparams']['options'] as $option) { $tmpValues[] = $option['value']; diff --git a/administrator/components/com_guidedtours/src/Controller/AjaxController.php b/administrator/components/com_guidedtours/src/Controller/AjaxController.php index cdf73f68fdfdf..7e3706abb9f49 100644 --- a/administrator/components/com_guidedtours/src/Controller/AjaxController.php +++ b/administrator/components/com_guidedtours/src/Controller/AjaxController.php @@ -15,6 +15,7 @@ use Joomla\CMS\MVC\Controller\BaseController; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\Response\JsonResponse; +use Joomla\CMS\Session\Session; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; @@ -35,6 +36,12 @@ class AjaxController extends BaseController */ public function fetchUserState() { + // The request changes persisted user state, so it must carry a valid token. + if (!Session::checkToken('get')) { + echo new JsonResponse(null, Text::_('JINVALID_TOKEN'), true); + $this->app->close(); + } + $user = $this->app->getIdentity(); $tourId = $this->app->getInput()->getInt('tid', 0); diff --git a/administrator/components/com_installer/tmpl/update/default.php b/administrator/components/com_installer/tmpl/update/default.php index e493e91f3b0da..7b17f3cdf8c81 100644 --- a/administrator/components/com_installer/tmpl/update/default.php +++ b/administrator/components/com_installer/tmpl/update/default.php @@ -105,11 +105,11 @@ update_site_id; ?> - security)) : ?> + security)) : ?>
security); ?> -
- + + client_translated; ?> diff --git a/administrator/components/com_joomlaupdate/src/Model/UpdateModel.php b/administrator/components/com_joomlaupdate/src/Model/UpdateModel.php index 742ebfcbb0f4a..cd532fae82da9 100644 --- a/administrator/components/com_joomlaupdate/src/Model/UpdateModel.php +++ b/administrator/components/com_joomlaupdate/src/Model/UpdateModel.php @@ -511,12 +511,20 @@ public function getAutoUpdateVersion(): ?string */ public function getAutoUpdateRequirementsState(): bool { + // Check basic requirements of the *current* system foreach ($this->getPhpOptions() as $option) { if ($option->state !== true) { return false; } } + // Fetch update and check constraints - if the "otherinfo" is set, we have a constraint issue + $updateInfo = $this->getUpdateInformation(); + + if (!empty($updateInfo['object']) && !empty((array) $updateInfo['object']->get('otherUpdateInfo'))) { + return false; + } + return true; } diff --git a/administrator/components/com_menus/src/Model/ItemModel.php b/administrator/components/com_menus/src/Model/ItemModel.php index 418ed43c5125b..0e698469872c9 100644 --- a/administrator/components/com_menus/src/Model/ItemModel.php +++ b/administrator/components/com_menus/src/Model/ItemModel.php @@ -235,6 +235,15 @@ protected function batchCopy($value, $pks, $contexts) continue; } + // Check that the user is allowed to access the item + $itemMenuTypeId = (int) $this->getMenuTypeId($table->menutype); + + if ($table->menutype === 'main' || !$user->authorise('core.edit', 'com_menus.menu.' . $itemMenuTypeId)) { + $this->setError(Text::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + + return false; + } + // Copy is a bit tricky, because we also need to copy the children $query = $db->createQuery() ->select($db->quoteName('id')) diff --git a/administrator/components/com_templates/tmpl/template/default.php b/administrator/components/com_templates/tmpl/template/default.php index 881f5cc9c2d93..adb5ee1acf6cb 100644 --- a/administrator/components/com_templates/tmpl/template/default.php +++ b/administrator/components/com_templates/tmpl/template/default.php @@ -184,10 +184,10 @@ archive as $file) : ?>
  • -   +  escape($file); ?> -   +  escape($file); ?>
  • diff --git a/media_source/plg_system_guidedtours/js/guidedtours.es6.js b/media_source/plg_system_guidedtours/js/guidedtours.es6.js index b3a18eda01b5a..0235495f8682b 100644 --- a/media_source/plg_system_guidedtours/js/guidedtours.es6.js +++ b/media_source/plg_system_guidedtours/js/guidedtours.es6.js @@ -27,8 +27,10 @@ function emptyStorage() { */ function fetchTourState(tid, sid, context) { const fetchUrl = 'index.php?option=com_guidedtours&task=ajax.fetchUserState&format=json'; + // The endpoint persists user state, so the request must carry the CSRF token. + const token = Joomla.getOptions('com_guidedtours.token', ''); Joomla.request({ - url: `${fetchUrl}&tid=${tid}&sid=${sid}&context=${context}`, + url: `${fetchUrl}&${token}=1&tid=${tid}&sid=${sid}&context=${context}`, method: 'GET', perform: true, onSuccess: (response) => { diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 418dc86a677e4..7d4d3669973f6 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -3427,7 +3427,7 @@ parameters: Throw an Exception instead of using setError$# ''' identifier: method.deprecated - count: 35 + count: 36 path: administrator/components/com_menus/src/Model/ItemModel.php -