@optilogic/core 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +64 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +64 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/file-view/components/HtmlRenderer.tsx +108 -2
package/dist/index.d.cts
CHANGED
|
@@ -2968,7 +2968,24 @@ declare namespace CsvRenderer {
|
|
|
2968
2968
|
/**
|
|
2969
2969
|
* HtmlRenderer
|
|
2970
2970
|
*
|
|
2971
|
-
* Renders HTML content in a
|
|
2971
|
+
* Renders HTML content in a triple-locked iframe:
|
|
2972
|
+
*
|
|
2973
|
+
* Layer 1 — `sandbox="allow-scripts"` (no allow-same-origin):
|
|
2974
|
+
* Opaque origin. No access to parent DOM, cookies, localStorage,
|
|
2975
|
+
* sessionStorage, or IndexedDB. No form submission, popups,
|
|
2976
|
+
* top-navigation, or pointer-lock.
|
|
2977
|
+
*
|
|
2978
|
+
* Layer 2 — Content-Security-Policy (iframe `csp` attr + meta fallback):
|
|
2979
|
+
* Blocks ALL network requests (fetch, XHR, WebSocket, sendBeacon,
|
|
2980
|
+
* image pings, external scripts/styles/fonts). Only inline scripts,
|
|
2981
|
+
* inline styles, and data:/blob: images are allowed.
|
|
2982
|
+
*
|
|
2983
|
+
* Layer 3 — Permissions-Policy via `allow` attribute:
|
|
2984
|
+
* Explicitly denies every device/sensor API (camera, microphone,
|
|
2985
|
+
* geolocation, payment, USB, display-capture, etc.).
|
|
2986
|
+
*
|
|
2987
|
+
* Additional hardening:
|
|
2988
|
+
* - referrerpolicy="no-referrer" — no URL leakage to embedded content
|
|
2972
2989
|
*/
|
|
2973
2990
|
declare function HtmlRenderer({ content, fileName, className, }: FileRendererProps): react_jsx_runtime.JSX.Element;
|
|
2974
2991
|
declare namespace HtmlRenderer {
|
package/dist/index.d.ts
CHANGED
|
@@ -2968,7 +2968,24 @@ declare namespace CsvRenderer {
|
|
|
2968
2968
|
/**
|
|
2969
2969
|
* HtmlRenderer
|
|
2970
2970
|
*
|
|
2971
|
-
* Renders HTML content in a
|
|
2971
|
+
* Renders HTML content in a triple-locked iframe:
|
|
2972
|
+
*
|
|
2973
|
+
* Layer 1 — `sandbox="allow-scripts"` (no allow-same-origin):
|
|
2974
|
+
* Opaque origin. No access to parent DOM, cookies, localStorage,
|
|
2975
|
+
* sessionStorage, or IndexedDB. No form submission, popups,
|
|
2976
|
+
* top-navigation, or pointer-lock.
|
|
2977
|
+
*
|
|
2978
|
+
* Layer 2 — Content-Security-Policy (iframe `csp` attr + meta fallback):
|
|
2979
|
+
* Blocks ALL network requests (fetch, XHR, WebSocket, sendBeacon,
|
|
2980
|
+
* image pings, external scripts/styles/fonts). Only inline scripts,
|
|
2981
|
+
* inline styles, and data:/blob: images are allowed.
|
|
2982
|
+
*
|
|
2983
|
+
* Layer 3 — Permissions-Policy via `allow` attribute:
|
|
2984
|
+
* Explicitly denies every device/sensor API (camera, microphone,
|
|
2985
|
+
* geolocation, payment, USB, display-capture, etc.).
|
|
2986
|
+
*
|
|
2987
|
+
* Additional hardening:
|
|
2988
|
+
* - referrerpolicy="no-referrer" — no URL leakage to embedded content
|
|
2972
2989
|
*/
|
|
2973
2990
|
declare function HtmlRenderer({ content, fileName, className, }: FileRendererProps): react_jsx_runtime.JSX.Element;
|
|
2974
2991
|
declare namespace HtmlRenderer {
|
package/dist/index.js
CHANGED
|
@@ -7450,18 +7450,80 @@ function CsvRenderer({ content, className }) {
|
|
|
7450
7450
|
) });
|
|
7451
7451
|
}
|
|
7452
7452
|
CsvRenderer.displayName = "CsvRenderer";
|
|
7453
|
+
var CSP_POLICY = [
|
|
7454
|
+
"default-src 'none'",
|
|
7455
|
+
"script-src 'unsafe-inline'",
|
|
7456
|
+
"style-src 'unsafe-inline'",
|
|
7457
|
+
"img-src data: blob:"
|
|
7458
|
+
].join("; ");
|
|
7459
|
+
var PERMISSIONS_POLICY = [
|
|
7460
|
+
"camera=()",
|
|
7461
|
+
"microphone=()",
|
|
7462
|
+
"geolocation=()",
|
|
7463
|
+
"payment=()",
|
|
7464
|
+
"usb=()",
|
|
7465
|
+
"display-capture=()",
|
|
7466
|
+
"fullscreen=()",
|
|
7467
|
+
"autoplay=()",
|
|
7468
|
+
"web-share=()",
|
|
7469
|
+
"screen-wake-lock=()",
|
|
7470
|
+
"xr-spatial-tracking=()",
|
|
7471
|
+
"magnetometer=()",
|
|
7472
|
+
"gyroscope=()",
|
|
7473
|
+
"accelerometer=()"
|
|
7474
|
+
].join(", ");
|
|
7475
|
+
function buildSandboxedHtml(content) {
|
|
7476
|
+
return `<!DOCTYPE html>
|
|
7477
|
+
<html>
|
|
7478
|
+
<head>
|
|
7479
|
+
<meta http-equiv="Content-Security-Policy" content="${CSP_POLICY}">
|
|
7480
|
+
<script>
|
|
7481
|
+
// Neutralise APIs that the sandbox + CSP can't fully block.
|
|
7482
|
+
// This runs in <head> before any user content in <body>.
|
|
7483
|
+
// Uses Object.defineProperty to make overrides non-configurable
|
|
7484
|
+
// so user scripts cannot restore the original via prototype tricks.
|
|
7485
|
+
(function(){
|
|
7486
|
+
// postMessage: iframe can message parent even without allow-same-origin.
|
|
7487
|
+
// Kill it so content can't probe or spam any future parent listeners.
|
|
7488
|
+
// Also kill parent/top refs as an extra layer.
|
|
7489
|
+
var noop = function(){};
|
|
7490
|
+
try { Object.defineProperty(window, 'postMessage', { value: noop, writable: false, configurable: false }); } catch(e) {}
|
|
7491
|
+
try { Object.defineProperty(window, 'parent', { value: window, writable: false, configurable: false }); } catch(e) {}
|
|
7492
|
+
try { Object.defineProperty(window, 'top', { value: window, writable: false, configurable: false }); } catch(e) {}
|
|
7493
|
+
try { Object.defineProperty(window, 'opener', { value: null, writable: false, configurable: false }); } catch(e) {}
|
|
7494
|
+
|
|
7495
|
+
// RTCPeerConnection: not governed by CSP; could contact a STUN server
|
|
7496
|
+
// over UDP to leak the user's IP. Kill all browser-prefixed variants.
|
|
7497
|
+
var rtcNames = ['RTCPeerConnection', 'webkitRTCPeerConnection', 'mozRTCPeerConnection'];
|
|
7498
|
+
for (var i = 0; i < rtcNames.length; i++) {
|
|
7499
|
+
try { Object.defineProperty(window, rtcNames[i], { value: undefined, writable: false, configurable: false }); } catch(e) {}
|
|
7500
|
+
}
|
|
7501
|
+
})();
|
|
7502
|
+
</script>
|
|
7503
|
+
</head>
|
|
7504
|
+
<body>${content}</body>
|
|
7505
|
+
</html>`;
|
|
7506
|
+
}
|
|
7453
7507
|
function HtmlRenderer({
|
|
7454
7508
|
content,
|
|
7455
7509
|
fileName,
|
|
7456
7510
|
className
|
|
7457
7511
|
}) {
|
|
7512
|
+
const srcDoc = React20.useMemo(
|
|
7513
|
+
() => buildSandboxedHtml(content ?? ""),
|
|
7514
|
+
[content]
|
|
7515
|
+
);
|
|
7516
|
+
const iframeProps = { csp: CSP_POLICY };
|
|
7458
7517
|
return /* @__PURE__ */ jsx(
|
|
7459
7518
|
"iframe",
|
|
7460
7519
|
{
|
|
7461
|
-
srcDoc
|
|
7520
|
+
srcDoc,
|
|
7462
7521
|
sandbox: "allow-scripts",
|
|
7463
7522
|
title: fileName,
|
|
7464
|
-
|
|
7523
|
+
referrerPolicy: "no-referrer",
|
|
7524
|
+
allow: PERMISSIONS_POLICY,
|
|
7525
|
+
className: cn("h-full w-full border-0", className),
|
|
7526
|
+
...iframeProps
|
|
7465
7527
|
}
|
|
7466
7528
|
);
|
|
7467
7529
|
}
|