11<?php
22
3+ /*
4+ * This file is part of the Symfony package.
5+ *
6+ * (c) Fabien Potencier <[email protected] > 7+ *
8+ * For the full copyright and license information, please view the LICENSE
9+ * file that was distributed with this source code.
10+ */
11+
312namespace Symfony \UX \Turbo \EventSubscriber ;
413
514use Symfony \Component \DependencyInjection \Attribute \When ;
615use Symfony \Component \EventDispatcher \EventSubscriberInterface ;
716use Symfony \Component \HttpKernel \Event \ResponseEvent ;
817use Symfony \Component \HttpKernel \KernelEvents ;
918
10-
1119/**
12- * Allows the Web Debug Toolbar (WDT) when navigating via Turbo Drive when a strict Content-Security-Policy is set.
20+ * Allows the Web Debug Toolbar (WDT) when navigating via Turbo Drive when a strict Content-Security-Policy is set.
1321 * This is done by reusing WDT nonces.
1422 */
15-
1623#[When(env: 'dev ' )]
1724class WebDebugToolbarTurboDriveFixSubscriber implements EventSubscriberInterface
1825{
@@ -21,57 +28,58 @@ public function onKernelResponse(ResponseEvent $event): void
2128 $ request = $ event ->getRequest ();
2229 $ routeName = $ request ->get ('_route ' );
2330
24- if ($ routeName === '_wdt ' ) {return ;}
25- if ($ request ->headers ->has ('X-Turbo-Request-Id ' )) {return ;}
26- if ('html ' !== $ request ->getRequestFormat ()) {return ;}
31+ if ('_wdt ' === $ routeName ) {
32+ return ;
33+ }
34+ if ($ request ->headers ->has ('X-Turbo-Request-Id ' )) {
35+ return ;
36+ }
37+ if ('html ' !== $ request ->getRequestFormat ()) {
38+ return ;
39+ }
2740
2841 $ response = $ event ->getResponse ();
2942 $ content = $ response ->getContent ();
30-
43+
3144 $ scriptContent = <<<'EOD'
32- document.addEventListener('turbo:before-fetch-request', (event) =>
45+ document.addEventListener('turbo:before-fetch-request', (event) =>
3346 {
3447 var wdt = document.querySelector('.sf-toolbar');
3548 if (wdt)
3649 {
3750 let wdtStyle = wdt.nextElementSibling;
3851 let wdtScript = wdtStyle.nextElementSibling;
39-
52+
4053 if (wdtStyle.nonce) {event.detail.fetchOptions.headers['X-SymfonyProfiler-Style-Nonce'] = wdtStyle.nonce;}
4154 if (wdtScript.nonce) {event.detail.fetchOptions.headers['X-SymfonyProfiler-Script-Nonce'] = wdtScript.nonce;}
4255 }
4356 });
4457 EOD;
45- $ scriptTag = '<script> ' . $ scriptContent . '</script> ' ;
58+ $ scriptTag = '<script> ' . $ scriptContent. '</script> ' ;
4659
4760 $ hash = base64_encode (hash ('sha256 ' , $ scriptContent , true ));
48- $ hashString = "'sha256- " . $ hash . "' " ;
61+ $ hashString = "'sha256- " . $ hash. "' " ;
4962
5063 $ csp = $ response ->headers ->get ('Content-Security-Policy ' );
51- if ($ csp )
52- {
53- if (preg_match ('/script-src\s+([^;]+)/ ' , $ csp , $ matches ))
54- {
64+ if ($ csp ) {
65+ if (preg_match ('/script-src\s+([^;]+)/ ' , $ csp , $ matches )) {
5566 $ scriptSrc = $ matches [1 ];
5667
57- if (false === strpos ($ scriptSrc , $ hashString ))
58- {
59- $ newScriptSrc = $ scriptSrc . ' ' . $ hashString ;
60- $ csp = str_replace ($ matches [0 ], 'script-src ' . $ newScriptSrc , $ csp );
68+ if (!str_contains ($ scriptSrc , $ hashString )) {
69+ $ newScriptSrc = $ scriptSrc .' ' .$ hashString ;
70+ $ csp = str_replace ($ matches [0 ], 'script-src ' .$ newScriptSrc , $ csp );
6171 }
62- }
63- else
64- {
65- $ csp .= "; script-src 'self' " . $ hashString ;
72+ } else {
73+ $ csp .= "; script-src 'self' " .$ hashString ;
6674 }
6775 $ response ->headers ->set ('Content-Security-Policy ' , $ csp );
6876 }
6977
70- $ modifiedContent = str_replace ('</head> ' , $ scriptTag . '</head> ' , $ content );
78+ $ modifiedContent = str_replace ('</head> ' , $ scriptTag. '</head> ' , $ content );
7179 $ response ->setContent ($ modifiedContent );
7280 }
73-
74- public static function getSubscribedEvents () : array
81+
82+ public static function getSubscribedEvents (): array
7583 {
7684 return [
7785 KernelEvents::RESPONSE => ['onKernelResponse ' , -999999 ],
0 commit comments