diff --git a/Block/SentryScript.php b/Block/SentryScript.php index 81e2657..b8ce75d 100644 --- a/Block/SentryScript.php +++ b/Block/SentryScript.php @@ -102,6 +102,35 @@ public function useScriptTag(): bool return $this->dataHelper->useScriptTag(); } + /** + * Assembles and returns the JS script path. + */ + public function getJsUrl(): string + { + $bundleFile = $this->dataHelper->getLoaderScript(); + if ($bundleFile) { + return $bundleFile; + } + + $bundleFile = 'bundle'; + + if ($this->isTracingEnabled()) { + $bundleFile .= '.tracing'; + } + + if ($this->useSessionReplay()) { + $bundleFile .= '.replay'; + } + + $bundleFile .= '.min.js'; + + return sprintf( + 'https://browser.sentry-cdn.com/%s/%s', + $this->getJsSdkVersion(), + $bundleFile + ); + } + /** * Whether to enable session replay. */ diff --git a/Helper/Data.php b/Helper/Data.php index d4f0aee..25f9ead 100644 --- a/Helper/Data.php +++ b/Helper/Data.php @@ -95,6 +95,7 @@ class Data extends AbstractHelper 'cron_monitoring_enabled' => ['type' => 'bool'], 'track_crons' => ['type' => 'array'], 'enable_csp_report_url' => ['type' => 'bool'], + 'loader_script' => ['type' => 'string'], ]; /** @@ -234,6 +235,16 @@ public function getJsSdkVersion(): string return $this->collectModuleConfig()['js_sdk_version'] ?: SentryScript::CURRENT_VERSION; } + /** + * Get the loaderscript copied from Sentry. + * + * @return string The url to sentry's loading script e.g. https://js.sentry-cdn.com/x0xx00x.min.js + */ + public function getLoaderScript(): string + { + return $this->collectModuleConfig()['loader_script']; + } + /** * Get the current environment. * diff --git a/Model/Collector/SentryRelatedCspCollector.php b/Model/Collector/SentryRelatedCspCollector.php index cec3e69..04ceab2 100644 --- a/Model/Collector/SentryRelatedCspCollector.php +++ b/Model/Collector/SentryRelatedCspCollector.php @@ -34,6 +34,22 @@ public function collect(array $defaultPolicies = []): array ['https://browser.sentry-cdn.com'] ); + $policies[] = new FetchPolicy( + 'script-src', + false, + ['https://js.sentry-cdn.com'] + ); + + $customLoader = $this->dataHelper->getLoaderScript(); + $customLoaderHost = is_string($customLoader) ? UriFactory::factory($customLoader) : null; + if ($customLoaderHost !== null) { + $policies[] = new FetchPolicy( + 'script-src', + false, + [$customLoaderHost->getScheme().'://'.$customLoaderHost->getHost()] + ); + } + $dsn = $this->dataHelper->getDsn(); $dsnHost = is_string($dsn) ? UriFactory::factory($dsn)->getHost() : null; if (!empty($dsnHost)) { diff --git a/view/frontend/templates/script/sentry.phtml b/view/frontend/templates/script/sentry.phtml index aec6b32..7421077 100644 --- a/view/frontend/templates/script/sentry.phtml +++ b/view/frontend/templates/script/sentry.phtml @@ -8,26 +8,7 @@ if (!$block->canUseScriptTag($block->getNameInLayout())) { ?> useScriptTag()): ?> - isTracingEnabled()) { - $bundleFile .= '.tracing'; - } - - if ($block->useSessionReplay()) { - $bundleFile .= '.replay'; - } - - $bundleFile .= '.min.js'; - - $remoteFile = sprintf( - 'https://browser.sentry-cdn.com/%s/%s', - $escaper->escapeHtmlAttr($block->getJsSdkVersion()), - $bundleFile - ); - ?> - renderTag('script', ['src' => $remoteFile, 'crossorigin' => 'anonymous']) ?> + renderTag('script', ['src' => $block->getJsUrl(), 'crossorigin' => 'anonymous']) ?> renderTag('script', [], $block->getLayout()->createBlock(\JustBetter\Sentry\Block\SentryScript::class) ->setTemplate('JustBetter_Sentry::script/sentry_init.phtml') ->toHtml(), false); ?>