diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index de04be594..af09bae78 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,7 +10,11 @@ name: Matomo for WordPress Tests -on: [push] +on: + workflow_dispatch: + push: + schedule: + - cron: "0 0 * * 0" permissions: actions: read diff --git a/.phpcs.xml.dist b/.phpcs.xml.dist index 92686cd27..932cef2b3 100644 --- a/.phpcs.xml.dist +++ b/.phpcs.xml.dist @@ -59,6 +59,7 @@ + @@ -83,4 +84,10 @@ */tests/* + + */tests/* + + + */tests/* + diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b97d11f8..ad63f02c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,12 @@ == Changelog === += 5.1.3 = +* Update Matomo core to version 5.1.1 (changes: https://matomo.org/changelog/matomo-5-1-1/) +* Moderate redesign to the feedback and get started admin pages. +* Redesign of the tracker settings admin page. + = 5.1.2 = -* Incomplete bug fix: the clickjacking or replay attack fix for functionality that hides notifications for users was incomplete. +* Incomplete bug fix: the session hijacking or replay attack fix for functionality that hides notifications for users was incomplete. * Bug fix: the wp-statistics import is broken when the newest version of wp-statistics is installed. = 5.1.1 = @@ -9,7 +14,7 @@ * Bug fix: system report error notice should only be shown to superusers. * Bug fix: patch Matomo core to fix an iconv() notice that can occur during geolocation. * Allow re-running updates from a specific version in troubleshooting page to help when WordPress fails to update the plugin completely. -* Very minor security fix: functionality that hides notifications for users is no longer able to be used in clickjacking or replay attacks. +* Very minor security fix: functionality that hides notifications for users is no longer able to be used in session hijacking or replay attacks. = 5.1.0 = * Upgrade Matomo core to version 5.1.0 (changes: https://matomo.org/changelog/matomo-5-1-0/). diff --git a/README.md b/README.md index 985c0e6ff..174d64acf 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ First ensure the database you want to inspect (mariadb or mysql) is the one that environment. Then, while the local environment is running in one shell, open another and run the command: ```bash -npm run compose -- run mariadb mariadb -h mariadb -u root -p +npm run mariadb mariadb ``` Enter `pass` for the password. diff --git a/app/core/UrlHelper.php b/app/core/UrlHelper.php index 6776a647f..199375fc2 100644 --- a/app/core/UrlHelper.php +++ b/app/core/UrlHelper.php @@ -142,8 +142,13 @@ public static function getParseUrlReverse($parsed) if (!is_array($parsed)) { return false; } + // According to RFC 1738, the chars ':', '@' and '/' need to be encoded in username or password part of an url + // We also encode '\' as a username or password containing that char, might be handled incorrectly by browsers + $escapeSpecialChars = function ($value) { + return str_replace([':', '@', '/', '\\'], [urlencode(':'), urlencode('@'), urlencode('/'), urlencode('\\')], $value); + }; $uri = !empty($parsed['scheme']) ? $parsed['scheme'] . ':' . (!strcasecmp($parsed['scheme'], 'mailto') ? '' : '//') : ''; - $uri .= !empty($parsed['user']) ? $parsed['user'] . (!empty($parsed['pass']) ? ':' . $parsed['pass'] : '') . '@' : ''; + $uri .= !empty($parsed['user']) ? $escapeSpecialChars($parsed['user']) . (!empty($parsed['pass']) ? ':' . $escapeSpecialChars($parsed['pass']) : '') . '@' : ''; $uri .= !empty($parsed['host']) ? $parsed['host'] : ''; $uri .= !empty($parsed['port']) ? ':' . $parsed['port'] : ''; if (!empty($parsed['path'])) { diff --git a/app/core/Version.php b/app/core/Version.php index 445807636..1f1bb0278 100644 --- a/app/core/Version.php +++ b/app/core/Version.php @@ -20,7 +20,7 @@ final class Version * The current Matomo version. * @var string */ - public const VERSION = '5.1.0'; + public const VERSION = '5.1.1'; public const MAJOR_VERSION = 5; public function isStableVersion($version) : bool { diff --git a/app/lang/dev.json b/app/lang/dev.json index cd5596307..72adabc8f 100644 --- a/app/lang/dev.json +++ b/app/lang/dev.json @@ -1,9 +1,5 @@ { "General": { "TranslatorName": "Matomo Development Team" - }, - "Intl": { - "OriginalLanguageName": "Development", - "EnglishLanguageName": "Development" } -} \ No newline at end of file +} diff --git a/app/plugins/Login/Controller.php b/app/plugins/Login/Controller.php index 987725a55..f169beeff 100644 --- a/app/plugins/Login/Controller.php +++ b/app/plugins/Login/Controller.php @@ -265,7 +265,7 @@ protected function authenticateAndRedirect($login, $password, $urlToRedirect = f // remove password reset entry if it exists $this->passwordResetter->removePasswordResetInfo($login); $parsedUrl = parse_url($urlToRedirect); - if (!empty($urlToRedirect) && false === $parsedUrl) { + if (!empty($urlToRedirect) && false === $parsedUrl || !empty($parsedUrl['scheme']) && empty($parsedUrl['host'])) { $e = new \Piwik\Exception\Exception('The redirect URL is not valid.'); $e->setIsHtmlMessage(); throw $e; @@ -276,6 +276,10 @@ protected function authenticateAndRedirect($login, $password, $urlToRedirect = f $e->setIsHtmlMessage(); throw $e; } + // We put together the url based on the parsed parameters manually to ensure it might not redirect to unexpected locations + // unescaped slashes in username or password part for example have unexpected results in browsers + // for protocol less urls starting with //, we need to prepend the double slash to have a url that passes the valid url check in redirect logic + $urlToRedirect = (strpos($urlToRedirect, '//') === 0 ? '//' : '') . UrlHelper::getParseUrlReverse($parsedUrl); if (empty($urlToRedirect)) { $redirect = Request::fromRequest()->getStringParameter('form_redirect', ''); $module = Request::fromQueryString(UrlHelper::getQueryFromUrl($redirect))->getStringParameter('module', ''); diff --git a/app/plugins/Marketplace/Controller.php b/app/plugins/Marketplace/Controller.php index 6d2cf20fc..5a580d2be 100644 --- a/app/plugins/Marketplace/Controller.php +++ b/app/plugins/Marketplace/Controller.php @@ -205,6 +205,7 @@ public function overview() $view->isPluginUploadEnabled = CorePluginsAdmin::isPluginUploadEnabled(); $view->uploadLimit = SettingsServer::getPostMaxUploadSize(); $view->inReportingMenu = (bool) Common::getRequestVar('embed', 0, 'int'); + $view->numUsers = $this->environment->getNumUsers(); return $view->render(); } public function updateOverview() : string diff --git a/app/plugins/Marketplace/Marketplace.php b/app/plugins/Marketplace/Marketplace.php index 8c390adfe..41d66919a 100644 --- a/app/plugins/Marketplace/Marketplace.php +++ b/app/plugins/Marketplace/Marketplace.php @@ -149,7 +149,6 @@ public function getClientSideTranslationKeys(&$translationKeys) $translationKeys[] = 'Marketplace_AutoUpdateDisabledWarning'; $translationKeys[] = 'Marketplace_ByXDevelopers'; $translationKeys[] = 'Marketplace_ClickToCompletePurchase'; - $translationKeys[] = 'Marketplace_CurrentNumPiwikUsers'; $translationKeys[] = 'Marketplace_Developer'; $translationKeys[] = 'Marketplace_FeaturedPlugin'; $translationKeys[] = 'Marketplace_LastCommitTime'; diff --git a/app/plugins/Marketplace/stylesheets/plugin-details.less b/app/plugins/Marketplace/stylesheets/plugin-details.less index 262bf5e27..72f5b9b2c 100644 --- a/app/plugins/Marketplace/stylesheets/plugin-details.less +++ b/app/plugins/Marketplace/stylesheets/plugin-details.less @@ -308,6 +308,16 @@ max-height: calc(~"100vh - 250px"); } + &--with-free-trial { + @media (max-width: 660px) { + max-height: calc(~"90vh - 270px"); + } + + @media (max-width: 480px) { + max-height: calc(~"100vh - 270px"); + } + } + h2, h3, h4, h5, h6 { margin: 20px 0 10px 0; color: #000000; @@ -455,6 +465,8 @@ padding: 24px; height: 90px; border-top: 1px solid #aaa; + margin-top: 1px; // to prevent images overflowing the border + box-sizing: border-box; display: flex; justify-content: space-between; @@ -480,10 +492,115 @@ .matomo-badge-modal { position: initial; + width: 64px; + height: 40px; @media (max-width: 480px) { display: none; } } + + &--with-free-trial { + @media (max-width: 660px) { + padding: 16px 24px; + height: 110px; + } + + .cta-container-modal { + justify-content: flex-end; + } + + .cta-container { + width: 100%; + margin-left: 1rem; + display: flex; + justify-content: flex-end; + box-sizing: border-box; + + .free-trial { + display: flex; + } + + .free-trial-lead-in { + color: #5bb75b; + font-size: 12px; + font-weight: bold; + display: inline-block; + text-align: right; + flex-grow: 1; + flex-shrink: 1; + align-content: center; + padding-right: 1rem; + } + + .free-trial-dropdown { + width: 240px; + height: 36px; + vertical-align: top; + flex-shrink: 0; + } + + .addToCartLink { + width: auto; + max-width: 240px; + vertical-align: top; + padding: 0 1rem; + margin-left: 1rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + flex-shrink: 0; + } + + @media (max-width: 660px) { + margin-left: 0; + flex-direction: column; /* Stack items vertically */ + justify-content: flex-start; /* Align items to the start */ + + .free-trial-lead-in { + width: 50%; + } + + .free-trial-dropdown { + width: 50%; + } + + .addToCartLink { + width: 50%; + min-width: 50%; + margin-top: 10px; /* space between rows */ + margin-left: 0; + align-self: flex-end; + } + } + + @media (max-width: 400px) { + .addToCartLink { + width: 100%; + min-width: 100%; + } + } + } + + .matomo-badge-modal { + position: initial; + + @media (max-width: 767px) { + width: 48px; + height: 32px; + } + + @media (max-width: 660px) { + display: initial; + position: absolute; + bottom: 16px; + } + + @media (max-width: 400px) { + display: none; + } + } + + } } } diff --git a/app/plugins/Marketplace/templates/overview.twig b/app/plugins/Marketplace/templates/overview.twig index 4cf0168b4..c971830b1 100644 --- a/app/plugins/Marketplace/templates/overview.twig +++ b/app/plugins/Marketplace/templates/overview.twig @@ -26,6 +26,7 @@ default-sort="{{ defaultSort|json_encode }}" plugin-sort-options="{{ pluginSortOptions|json_encode }}" num-available-plugins-by-type="{{ numAvailablePluginsByType|json_encode }}" + num-users="{{ numUsers|json_encode }}" > -