Skip to content

Commit ec86c77

Browse files
committed
[BUGFIX] Fixed CSP issues in Cornerstone form element and Dashboard backend module, fixed some more dark mode styling issues
1 parent 7e12065 commit ec86c77

File tree

13 files changed

+95
-36
lines changed

13 files changed

+95
-36
lines changed

Build/phpstan/phpstan.cms11.neon

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ parameters:
1313
- '#TYPO3\\CMS\\Extbase\\Mvc\\RequestInterface#'
1414
- '#TYPO3\\CMS\\Core\\View\\ViewInterface#'
1515
- '#TYPO3\\CMS\\Core\\Domain\\Repository\\PageRepository::getLanguageOverlay#'
16+
- '#TYPO3\\CMS\\Core\\Domain\\ConsumableString#'
1617
- '#frontend.page.information#'
1718
- '#ModifyPageLayoutContentEvent#'
1819
- '#AfterCacheableContentIsGeneratedEvent#'
@@ -21,6 +22,7 @@ parameters:
2122
- '#addJsInlineCode#'
2223
- '#calculateLifetimeForPage#'
2324
- '#CacheLifetimeCalculator#'
25+
- '#nonce#'
2426
typo3:
2527
requestGetAttributeMapping:
2628
handlerRequest: string

Build/phpstan/phpstan.cms12.neon

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ parameters:
1111
- '#protected method getRecordOverlay#'
1212
typo3:
1313
requestGetAttributeMapping:
14-
handlerRequest: string
14+
handlerRequest: string
15+
nonce: TYPO3\CMS\Core\Security\ContentSecurityPolicy\ConsumableNonce

Build/phpstan/phpstan.cms13.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ parameters:
1414
requestGetAttributeMapping:
1515
frontend.page.information: TYPO3\CMS\Frontend\Page\PageInformation
1616
handlerRequest: string
17+
nonce: TYPO3\CMS\Core\Security\ContentSecurityPolicy\ConsumableNonce

Build/resources/sass/backend-module.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ $gutter: 32px;
1919
}
2020

2121
&-content {
22+
color: var(--typo3-state-default-color, #000);
2223

2324
.row {
2425
max-width: 1650px;

Build/resources/sass/backend-module/_headings.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
color: $yoast_color_headings;
44

55
span {
6-
color: #000;
6+
color: var(--typo3-state-default-color, #000);
77
}
88
}
99
}

Build/resources/yarn.lock

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -993,13 +993,20 @@
993993
core-js "^2.5.7"
994994
regenerator-runtime "^0.12.0"
995995

996-
"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.14.8", "@babel/runtime@^7.16.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.21.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
996+
"@babel/runtime@^7.1.2", "@babel/runtime@^7.13.10", "@babel/runtime@^7.14.8", "@babel/runtime@^7.16.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.21.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
997997
version "7.26.0"
998998
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1"
999999
integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==
10001000
dependencies:
10011001
regenerator-runtime "^0.14.0"
10021002

1003+
"@babel/runtime@^7.12.5":
1004+
version "7.26.7"
1005+
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.7.tgz#f4e7fe527cd710f8dc0618610b61b4b060c3c341"
1006+
integrity sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==
1007+
dependencies:
1008+
regenerator-runtime "^0.14.0"
1009+
10031010
"@babel/template@^7.25.9", "@babel/template@^7.3.3":
10041011
version "7.25.9"
10051012
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.9.tgz#ecb62d81a8a6f5dc5fe8abfc3901fc52ddf15016"
@@ -2120,16 +2127,16 @@
21202127
integrity sha512-oocsqY7g0cR+Gur5jRQLSrX2OtpMLMse1I10JQBm8CdGMrDkh1Mg2gjsiquMHRtBs4Qwu5wgEp5GgIYHk4SNPw==
21212128

21222129
"@tanstack/react-virtual@^3.0.0-beta.60":
2123-
version "3.10.8"
2124-
resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.10.8.tgz#bf4b06f157ed298644a96ab7efc1a2b01ab36e3c"
2125-
integrity sha512-VbzbVGSsZlQktyLrP5nxE+vE1ZR+U0NFAWPbJLoG2+DKPwd2D7dVICTVIIaYlJqX1ZCEnYDbaOpmMwbsyhBoIA==
2130+
version "3.11.3"
2131+
resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.11.3.tgz#cd62ecc431043c4a9ca24ea8dfcc2a70f4805380"
2132+
integrity sha512-vCU+OTylXN3hdC8RKg68tPlBPjjxtzon7Ys46MgrSLE+JhSjSTPvoQifV6DQJeJmA8Q3KT6CphJbejupx85vFw==
21262133
dependencies:
2127-
"@tanstack/virtual-core" "3.10.8"
2134+
"@tanstack/virtual-core" "3.11.3"
21282135

2129-
"@tanstack/virtual-core@3.10.8":
2130-
version "3.10.8"
2131-
resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.10.8.tgz#975446a667755222f62884c19e5c3c66d959b8b4"
2132-
integrity sha512-PBu00mtt95jbKFi6Llk9aik8bnR3tR/oQP1o3TSi+iG//+Q2RTIzCEgKkHG8BB86kxMNW6O8wku+Lmi+QFR6jA==
2136+
"@tanstack/virtual-core@3.11.3":
2137+
version "3.11.3"
2138+
resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.11.3.tgz#ab92ff899825e2d71fc9914dda2847a099d43862"
2139+
integrity sha512-v2mrNSnMwnPJtcVqNvV0c5roGCBqeogN8jDtgtuHCphdwBasOZ17x8UV8qpHUh+u0MLfX43c0uUHKje0s+Zb0w==
21332140

21342141
"@tootallnate/once@2":
21352142
version "2.0.0"
@@ -3697,9 +3704,9 @@
36973704
integrity sha512-gp2vPCJesNLG4QYxp/wWOTch88D4a0TkS2GL4N23Rfrl2XrUoM0HHTzRtk0rGd+xMLn/a4fYMI6976HjblhEcg==
36983705

36993706
"@yoast/ui-library@^4.0.0":
3700-
version "4.0.0"
3701-
resolved "https://registry.yarnpkg.com/@yoast/ui-library/-/ui-library-4.0.0.tgz#e597bf92f3b7d0082fe56cd767f0cab321c8f936"
3702-
integrity sha512-9vlDJYtkpleNeknAu7o/b4nRZDtPJW1Rll1yCNkVB8/6hzlOPWIGROphkv0q+sooHf0ftkeXFIGowZGExoJbnw==
3707+
version "4.1.0"
3708+
resolved "https://registry.yarnpkg.com/@yoast/ui-library/-/ui-library-4.1.0.tgz#d81d056219a286908e4c1f319853f40374a827de"
3709+
integrity sha512-xJefGYKWcw4izS7y6hYM4ZhUG+dNtub5g2hwqzT6q28veI10CIkzpKvuh3qWA/30v0WJIaX6o4AXhN1ZtUOnYA==
37033710
dependencies:
37043711
"@headlessui/react" "^1.7.8"
37053712
"@heroicons/react" "^1.0.6"
@@ -8644,9 +8651,9 @@ grunt-eslint@^21.0.0:
86448651
chalk "^2.1.0"
86458652
eslint "^5.16.0"
86468653

8647-
"grunt-glotpress@git+https://github.com/Yoast/grunt-glotpress.git#main":
8654+
"grunt-glotpress@https://github.com/Yoast/grunt-glotpress.git#main":
86488655
version "0.3.0"
8649-
resolved "git+https://github.com/Yoast/grunt-glotpress.git#e6ccc69c2532d126f5d8a30397ffd012e55b6eec"
8656+
resolved "https://github.com/Yoast/grunt-glotpress.git#e6ccc69c2532d126f5d8a30397ffd012e55b6eec"
86508657
dependencies:
86518658
request "^2.88.0"
86528659
request-promise-native "^1.0.7"

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ We will follow [Semantic Versioning](http://semver.org/).
1818
- Updates scss files to work with the new dark mode in TYPO3 13
1919
- Labels for Readability and SEO score are now taken from the Yoast translations instead of xlf
2020

21+
### Fixed
22+
- CSP issues within the `Cornerstone` form element and the Dashboard backend module
23+
- Dark mode styling for the Dashboard and Overview backend module
24+
2125
## 10.1.0 January 27, 2025
2226
### Added
2327
- `TypoScriptStructuredDataProvider` to add structured data to the page, configured with TypoScript (premium functionality)

Classes/Controller/DashboardController.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,30 @@
55
namespace YoastSeoForTypo3\YoastSeo\Controller;
66

77
use Psr\Http\Message\ResponseInterface;
8+
use TYPO3\CMS\Core\Domain\ConsumableString;
9+
use TYPO3\CMS\Core\Information\Typo3Version;
10+
use TYPO3\CMS\Core\Utility\GeneralUtility;
811

912
class DashboardController extends AbstractBackendController
1013
{
1114
public function indexAction(): ResponseInterface
1215
{
13-
return $this->returnResponse('Dashboard/Index');
16+
return $this->returnResponse(
17+
'Dashboard/Index',
18+
['nonce' => $this->getNonce()]
19+
);
20+
}
21+
22+
protected function getNonce(): string
23+
{
24+
if (GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion() < 12) {
25+
return '';
26+
}
27+
/** @var ConsumableString|null $nonceAttribute */
28+
$nonceAttribute = $this->request->getAttribute('nonce');
29+
if ($nonceAttribute instanceof ConsumableString) {
30+
return $nonceAttribute->consume();
31+
}
32+
return '';
1433
}
1534
}

Classes/Form/Element/Cornerstone.php

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,49 @@
44

55
namespace YoastSeoForTypo3\YoastSeo\Form\Element;
66

7-
use TYPO3\CMS\Backend\Form\AbstractNode;
7+
use TYPO3\CMS\Backend\Form\Element\CheckboxElement;
8+
use TYPO3\CMS\Core\Information\Typo3Version;
89
use TYPO3\CMS\Core\Utility\GeneralUtility;
9-
use YoastSeoForTypo3\YoastSeo\Service\Form\NodeTemplateService;
10-
11-
class Cornerstone extends AbstractNode
10+
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
11+
12+
/**
13+
* TODO: This should be handled differently in the future, for example by overriding appendValueToLabelInDebugMode
14+
* but due to the differences between 11, 12 and 13 there's currently no way to add the html to the label in a clean way
15+
* the old way was to provide a custom html template but that caused problems with the inline javascript (CSP)
16+
* This way the core method is used and thus works for every version, but it's not clean
17+
*/
18+
class Cornerstone extends CheckboxElement
1219
{
13-
// TODO: Use constructor DI when TYPO3 v11 can be dropped
14-
protected NodeTemplateService $templateService;
15-
1620
/**
1721
* @return array<string, mixed>
1822
*/
1923
public function render(): array
2024
{
21-
$this->init();
22-
23-
$resultArray = $this->initializeResultArray();
24-
$resultArray['html'] = $this->templateService->renderView('Cornerstone', ['data' => $this->data]);
25-
26-
return $resultArray;
25+
$checkboxResultArray = parent::render();
26+
27+
if (GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion() < 12) {
28+
$checkboxResultArray['html'] = str_replace(
29+
'<span class="form-check-label-text">',
30+
'<span class="form-check-label-text">' . $this->getLabelWithYoastLink(),
31+
$checkboxResultArray['html']
32+
);
33+
} else {
34+
$checkboxResultArray['html'] = preg_replace(
35+
'/(<label class="form-check-label"[^>]*>)(.*?)(<\/label>)/is',
36+
'$1$2' . $this->getLabelWithYoastLink() . '$3',
37+
$checkboxResultArray['html']
38+
);
39+
}
40+
41+
return $checkboxResultArray;
2742
}
2843

29-
protected function init(): void
44+
protected function getLabelWithYoastLink(): string
3045
{
31-
$this->templateService = GeneralUtility::makeInstance(NodeTemplateService::class);
46+
return LocalizationUtility::translate(
47+
'LLL:EXT:yoast_seo/Resources/Private/Language/BackendModule.xlf:thisPageIsCornerstoneContent',
48+
'yoast_seo',
49+
['https://yoa.st/metabox-help-cornerstone']
50+
) ?? '';
3251
}
3352
}

Resources/Private/Partials/Dashboard/View.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ <h2>
9494
<button type="submit" name="subscribe" id="mc-embedded-subscribe" class="yoast-button yoast-button--noarrow yoast-button--extension yoast-button--extension-cta yoast-link" style="margin-top: 10px;">{f:translate(key: 'LLL:EXT:yoast_seo/Resources/Private/Language/BackendModule.xlf:dashboard.seoTips.submit')}</button>
9595
</form>
9696

97-
<script type="text/javascript" src="{f:uri.resource(path:'EXT:yoast_seo/Resources/Public/JavaScript/dist/mc-validate.js')}"></script>
98-
<script type="text/javascript">(function($) {window.fnames = new Array(); window.ftypes = new Array();fnames[0]=EMAIL;ftypes[0]=email;fnames[1]=LBTITLE;ftypes[1]=text;fnames[2]=LBADTEXT;ftypes[2]=text;fnames[3]=LBADLINK;ftypes[3]=text;fnames[4]=LBIMAGEURL;ftypes[4]=text;fnames[5]=LBPIXEL;ftypes[5]=text;fnames[6]=LAUNCHBIT;ftypes[6]=text;fnames[7]=NAME;ftypes[7]=text;fnames[8]=FIRST_TIME;ftypes[8]=text;}(jQuery));var $mcj = jQuery.noConflict(true);</script>
97+
<script type="text/javascript" src="{f:uri.resource(path:'EXT:yoast_seo/Resources/Public/JavaScript/dist/mc-validate.js')}" nonce="{nonce}"></script>
98+
<script type="text/javascript" nonce="{nonce}">(function($) {window.fnames = new Array(); window.ftypes = new Array();fnames[0]='EMAIL';ftypes[0]='email';fnames[1]='LBTITLE';ftypes[1]='text';fnames[2]='LBADTEXT';ftypes[2]='text';fnames[3]='LBADLINK';ftypes[3]='text';fnames[4]='LBIMAGEURL';ftypes[4]='text';fnames[5]='LBPIXEL';ftypes[5]='text';fnames[6]='LAUNCHBIT';ftypes[6]='text';fnames[7]='NAME';ftypes[7]='text';fnames[8]='FIRST_TIME';ftypes[8]='text';}(jQuery));var $mcj = jQuery.noConflict(true);</script>
9999

100100
</div>
101101
</div>

Resources/Private/Templates/Dashboard/Index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<f:layout name="{layout}" />
55

66
<f:section name="Content">
7-
<f:render partial="Dashboard/View" />
7+
<f:render partial="Dashboard/View" arguments="{_all}" />
88
</f:section>
99

1010
</html>

Resources/Public/CSS/yoast-seo-backend.min.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tests/Unit/Controller/DashboardControllerTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
use PHPUnit\Framework\Attributes\CoversClass;
88
use PHPUnit\Framework\Attributes\Test;
99
use TYPO3\CMS\Core\Http\HtmlResponse;
10+
use TYPO3\CMS\Core\Http\ServerRequest;
1011
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
12+
use TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters;
13+
use TYPO3\CMS\Extbase\Mvc\Request;
1114
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
1215
use YoastSeoForTypo3\YoastSeo\Controller\DashboardController;
1316

@@ -41,6 +44,8 @@ public function isActionController(): void
4144
#[Test]
4245
public function indexActionReturnsHtmlResponse(): void
4346
{
47+
$serverRequest = (new ServerRequest())->withAttribute('extbase', new ExtbaseRequestParameters());
48+
$this->subject->_set('request', new Request($serverRequest));
4449
$result = $this->subject->indexAction();
4550

4651
self::assertInstanceOf(HtmlResponse::class, $result);

0 commit comments

Comments
 (0)