fix: gate debug window hooks behind explicit flag
This commit is contained in:
+1
-1
@@ -11,7 +11,7 @@
|
|||||||
"dev": "npm run build && python -m http.server 8000",
|
"dev": "npm run build && python -m http.server 8000",
|
||||||
"watch": "npx tailwindcss -i src/styles/tw-input.css -o assets/tailwind.css --watch",
|
"watch": "npx tailwindcss -i src/styles/tw-input.css -o assets/tailwind.css --watch",
|
||||||
"serve": "npx http-server -p 8000",
|
"serve": "npx http-server -p 8000",
|
||||||
"test": "node tests/sas-verification.test.mjs && node tests/file-transfer-consent.test.mjs && node tests/incoming-message-sanitization.test.mjs && node tests/file-type-allowlist.test.mjs && node tests/webrtc-privacy-mode.test.mjs && node tests/indexeddb-metadata-encryption.test.mjs && node tests/disconnect-cleanup.test.mjs && node tests/timer-lifecycle.test.mjs && node tests/file-transfer-cleanup.test.mjs && node tests/file-transfer-ui-cleanup.test.mjs && node tests/file-transfer-callback-propagation.test.mjs"
|
"test": "node tests/sas-verification.test.mjs && node tests/file-transfer-consent.test.mjs && node tests/incoming-message-sanitization.test.mjs && node tests/file-type-allowlist.test.mjs && node tests/webrtc-privacy-mode.test.mjs && node tests/indexeddb-metadata-encryption.test.mjs && node tests/disconnect-cleanup.test.mjs && node tests/timer-lifecycle.test.mjs && node tests/file-transfer-cleanup.test.mjs && node tests/file-transfer-ui-cleanup.test.mjs && node tests/file-transfer-callback-propagation.test.mjs && node tests/debug-window-hooks.test.mjs"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"p2p",
|
"p2p",
|
||||||
|
|||||||
+11
-25
@@ -1,4 +1,4 @@
|
|||||||
|
import { installDebugWindowHooks } from './utils/debugWindowHooks.js';
|
||||||
// Enhanced Copy Button with better UX
|
// Enhanced Copy Button with better UX
|
||||||
const EnhancedCopyButton = ({ text, className = "", children }) => {
|
const EnhancedCopyButton = ({ text, className = "", children }) => {
|
||||||
const [copied, setCopied] = React.useState(false);
|
const [copied, setCopied] = React.useState(false);
|
||||||
@@ -1639,32 +1639,18 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Global functions for cleanup
|
|
||||||
React.useEffect(() => {
|
|
||||||
window.forceCleanup = () => {
|
|
||||||
handleClearData();
|
|
||||||
if (webrtcManagerRef.current) {
|
|
||||||
webrtcManagerRef.current.disconnect();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
window.clearLogs = () => {
|
|
||||||
if (typeof console.clear === 'function') {
|
|
||||||
console.clear();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
delete window.forceCleanup;
|
|
||||||
delete window.clearLogs;
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const webrtcManagerRef = React.useRef(null);
|
const webrtcManagerRef = React.useRef(null);
|
||||||
const notificationIntegrationRef = React.useRef(null);
|
const notificationIntegrationRef = React.useRef(null);
|
||||||
// Expose for modules/UI that run outside this closure (e.g., inline handlers)
|
|
||||||
// Safe because it's a ref object and we maintain it centrally here
|
// Development-only debug helpers. Production never exposes
|
||||||
window.webrtcManagerRef = webrtcManagerRef;
|
// manager internals or cleanup controls on `window`.
|
||||||
|
React.useEffect(() => {
|
||||||
|
return installDebugWindowHooks({
|
||||||
|
targetWindow: window,
|
||||||
|
webrtcManagerRef,
|
||||||
|
onClearData: handleClearData
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
const addMessageWithAutoScroll = React.useCallback((message, type) => {
|
const addMessageWithAutoScroll = React.useCallback((message, type) => {
|
||||||
const newMessage = {
|
const newMessage = {
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
function isSecureBitDebugEnabled(targetWindow = globalThis.window) {
|
||||||
|
return targetWindow?.SECUREBIT_DEBUG === true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function installDebugWindowHooks({
|
||||||
|
targetWindow = globalThis.window,
|
||||||
|
webrtcManagerRef,
|
||||||
|
onClearData,
|
||||||
|
clearConsole = () => {
|
||||||
|
if (typeof console.clear === 'function') {
|
||||||
|
console.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
if (!isSecureBitDebugEnabled(targetWindow)) {
|
||||||
|
return () => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
targetWindow.forceCleanup = () => {
|
||||||
|
onClearData();
|
||||||
|
if (webrtcManagerRef.current) {
|
||||||
|
webrtcManagerRef.current.disconnect();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
targetWindow.clearLogs = clearConsole;
|
||||||
|
targetWindow.webrtcManagerRef = webrtcManagerRef;
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
delete targetWindow.forceCleanup;
|
||||||
|
delete targetWindow.clearLogs;
|
||||||
|
delete targetWindow.webrtcManagerRef;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export { installDebugWindowHooks, isSecureBitDebugEnabled };
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
import assert from 'node:assert/strict';
|
||||||
|
|
||||||
|
const { installDebugWindowHooks, isSecureBitDebugEnabled } = await import('../src/utils/debugWindowHooks.js');
|
||||||
|
|
||||||
|
// Production mode does not expose debug/control globals.
|
||||||
|
{
|
||||||
|
const targetWindow = {};
|
||||||
|
const managerRef = { current: { disconnect() {} } };
|
||||||
|
const cleanup = installDebugWindowHooks({
|
||||||
|
targetWindow,
|
||||||
|
webrtcManagerRef: managerRef,
|
||||||
|
onClearData() {}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.equal(isSecureBitDebugEnabled(targetWindow), false);
|
||||||
|
assert.equal('forceCleanup' in targetWindow, false);
|
||||||
|
assert.equal('clearLogs' in targetWindow, false);
|
||||||
|
assert.equal('webrtcManagerRef' in targetWindow, false);
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug mode exposes hooks only when explicitly requested.
|
||||||
|
{
|
||||||
|
let clearDataCalls = 0;
|
||||||
|
let disconnectCalls = 0;
|
||||||
|
let clearLogCalls = 0;
|
||||||
|
const targetWindow = { SECUREBIT_DEBUG: true };
|
||||||
|
const managerRef = {
|
||||||
|
current: {
|
||||||
|
disconnect() {
|
||||||
|
disconnectCalls += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const cleanup = installDebugWindowHooks({
|
||||||
|
targetWindow,
|
||||||
|
webrtcManagerRef: managerRef,
|
||||||
|
onClearData() {
|
||||||
|
clearDataCalls += 1;
|
||||||
|
},
|
||||||
|
clearConsole() {
|
||||||
|
clearLogCalls += 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.equal(isSecureBitDebugEnabled(targetWindow), true);
|
||||||
|
assert.equal(targetWindow.webrtcManagerRef, managerRef);
|
||||||
|
targetWindow.forceCleanup();
|
||||||
|
targetWindow.clearLogs();
|
||||||
|
assert.equal(clearDataCalls, 1);
|
||||||
|
assert.equal(disconnectCalls, 1);
|
||||||
|
assert.equal(clearLogCalls, 1);
|
||||||
|
|
||||||
|
cleanup();
|
||||||
|
assert.equal('forceCleanup' in targetWindow, false);
|
||||||
|
assert.equal('clearLogs' in targetWindow, false);
|
||||||
|
assert.equal('webrtcManagerRef' in targetWindow, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normal cleanup remains available through the app-owned callback path.
|
||||||
|
{
|
||||||
|
let clearDataCalls = 0;
|
||||||
|
const onClearData = () => {
|
||||||
|
clearDataCalls += 1;
|
||||||
|
};
|
||||||
|
installDebugWindowHooks({
|
||||||
|
targetWindow: {},
|
||||||
|
webrtcManagerRef: { current: null },
|
||||||
|
onClearData
|
||||||
|
});
|
||||||
|
onClearData();
|
||||||
|
assert.equal(clearDataCalls, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Debug window hook tests passed');
|
||||||
Reference in New Issue
Block a user