TF-4343 Fix load Sentry from Sentry CDN (#4348)
This commit is contained in:
+1
-1
@@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
|||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 0.27.2
|
version: 0.28.2-rc01
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.0.0 <4.0.0"
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
|
|||||||
@@ -41,6 +41,10 @@
|
|||||||
<script src="worker_service/worker_service.js"></script>
|
<script src="worker_service/worker_service.js"></script>
|
||||||
<script src="i18n/translater.js"></script>
|
<script src="i18n/translater.js"></script>
|
||||||
<script src="https://unpkg.com/@dotlottie/player-component@2.7.12/dist/dotlottie-player.mjs" type="module"></script>
|
<script src="https://unpkg.com/@dotlottie/player-component@2.7.12/dist/dotlottie-player.mjs" type="module"></script>
|
||||||
|
<!-- Load Sentry SDK first (self-hosted bundle), then interceptor to block any subsequent CDN injection.
|
||||||
|
Order matters: the interceptor must activate after the SDK is ready so it can patch document.createElement. -->
|
||||||
|
<script src="js/sentry-tracing.min.js?v=1.0.0" integrity="sha384-SFODEb3T2QkMjTr3S1it5zIK0cIW7jsComFUkmJ9nU9uaWs3AzA6cubt8xn0zW7A" crossorigin="anonymous"></script>
|
||||||
|
<script src="js/sentry-interceptor.js?v=1.0.0" integrity="sha384-uThyomTT1K0+gzqsKuq4UoZXu3SABtbtP7Y3NXFyvabuIQPGYszSO41UBrcs5czI" crossorigin="anonymous"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
(function() {
|
||||||
|
const originalCreateElement = document.createElement;
|
||||||
|
|
||||||
|
// Only block the specific tracing bundle we self-host. Narrowing to this pathname
|
||||||
|
// prevents silently swallowing future CDN assets that have no local replacement.
|
||||||
|
const BLOCKED_PATHNAME = '/bundle.tracing.min.js';
|
||||||
|
|
||||||
|
function isSentryCdnHostname(hostname) {
|
||||||
|
return hostname === 'sentry-cdn.com' || hostname.endsWith('.sentry-cdn.com');
|
||||||
|
}
|
||||||
|
|
||||||
|
function shouldBlockSentryUrl(urlString) {
|
||||||
|
if (!urlString) return false;
|
||||||
|
try {
|
||||||
|
const parsed = new URL(urlString, document.baseURI);
|
||||||
|
const hostname = parsed.hostname.toLowerCase();
|
||||||
|
const pathname = parsed.pathname.toLowerCase();
|
||||||
|
return isSentryCdnHostname(hostname) && pathname.endsWith(BLOCKED_PATHNAME);
|
||||||
|
} catch (e) {
|
||||||
|
// Fallback for non-parseable URLs: check if it looks like a plain hostname
|
||||||
|
// (no whitespace, no path/query/fragment separators).
|
||||||
|
const str = String(urlString).trim().toLowerCase();
|
||||||
|
const isHostLike = str.length > 0 && !/[\s/?#]/.test(str);
|
||||||
|
return isHostLike && isSentryCdnHostname(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function blockAndNotify(element, channel, urlString) {
|
||||||
|
console.log('[Sentry Interceptor] 🛑 Blocked CDN request (' + channel + '):', urlString);
|
||||||
|
// Fire a synthetic 'load' event so the Sentry SDK's internal Promise resolves
|
||||||
|
// cleanly instead of hanging indefinitely waiting for a CDN script we blocked.
|
||||||
|
setTimeout(() => element.dispatchEvent(new Event('load')), 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeSrcSetter(nativeSrcDescriptor) {
|
||||||
|
return function(val) {
|
||||||
|
const urlString = val ? String(val) : '';
|
||||||
|
if (shouldBlockSentryUrl(urlString)) {
|
||||||
|
blockAndNotify(this, 'Property', urlString);
|
||||||
|
} else {
|
||||||
|
nativeSrcDescriptor?.set?.call(this, val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeSrcGetter(nativeSrcDescriptor) {
|
||||||
|
return function() {
|
||||||
|
return nativeSrcDescriptor?.get?.call(this) ?? '';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeSetAttribute(originalSetAttribute) {
|
||||||
|
return function(name, value) {
|
||||||
|
const urlString = value ? String(value) : '';
|
||||||
|
if (String(name).toLowerCase() === 'src' && shouldBlockSentryUrl(urlString)) {
|
||||||
|
blockAndNotify(this, 'Attribute', urlString);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
originalSetAttribute.call(this, name, value);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function patchScriptElement(element) {
|
||||||
|
const nativeSrcDescriptor = Object.getOwnPropertyDescriptor(HTMLScriptElement.prototype, 'src');
|
||||||
|
Object.defineProperty(element, 'src', {
|
||||||
|
configurable: true,
|
||||||
|
set: makeSrcSetter(nativeSrcDescriptor),
|
||||||
|
get: makeSrcGetter(nativeSrcDescriptor),
|
||||||
|
});
|
||||||
|
element.setAttribute = makeSetAttribute(element.setAttribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load order: sentry-tracing.min.js (self-hosted SDK) must run before this interceptor.
|
||||||
|
// This interceptor patches document.createElement to block any subsequent CDN injection
|
||||||
|
// the SDK may attempt at runtime.
|
||||||
|
document.createElement = function(tagName, options) {
|
||||||
|
const element = originalCreateElement.call(document, tagName, options);
|
||||||
|
if (String(tagName).toLowerCase() === 'script') {
|
||||||
|
patchScriptElement(element);
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
};
|
||||||
|
})();
|
||||||
Vendored
+3
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user