release: v4.8.10 user-configurable STUN/TURN servers
- add header gear + connection-screen entry points to Advanced network settings - render the ICE settings modal at the app root (reachable from any screen via event) - remove the standalone relay-only toggle/description from the start screen (relay-only now lives in the advanced settings panel) - fix crash from referencing main-component state inside EnhancedConnectionSetup - bump version to 4.8.10 across header, manifest, README, init message, disclaimer - document the feature in CHANGELOG and README
This commit is contained in:
+26
-43
@@ -509,28 +509,6 @@ import { loadIceSettings, saveIceSettings, clearIceSettings } from './network/ic
|
||||
className: "text-secondary max-w-2xl mx-auto"
|
||||
}, "Choose a connection method for a secure channel with ECDH encryption and Perfect Forward Secrecy.")
|
||||
]),
|
||||
React.createElement('label', {
|
||||
key: 'privacy-mode',
|
||||
className: "mb-6 mx-auto flex max-w-2xl items-start gap-3 rounded-xl border border-purple-500/20 bg-purple-500/10 p-4 text-left"
|
||||
}, [
|
||||
React.createElement('input', {
|
||||
key: 'input',
|
||||
type: 'checkbox',
|
||||
checked: relayOnlyMode,
|
||||
onChange: (event) => setRelayOnlyMode(event.target.checked),
|
||||
className: "mt-1"
|
||||
}),
|
||||
React.createElement('span', { key: 'copy' }, [
|
||||
React.createElement('span', {
|
||||
key: 'title',
|
||||
className: "block text-sm font-medium text-primary"
|
||||
}, 'Privacy mode: relay-only WebRTC'),
|
||||
React.createElement('span', {
|
||||
key: 'desc',
|
||||
className: "block text-sm text-secondary"
|
||||
}, 'Uses TURN relay-only when configured. Without TURN, direct WebRTC may expose IP addresses and relay-only connections cannot start.')
|
||||
])
|
||||
]),
|
||||
|
||||
React.createElement('div', {
|
||||
key: 'advanced-network',
|
||||
@@ -539,33 +517,17 @@ import { loadIceSettings, saveIceSettings, clearIceSettings } from './network/ic
|
||||
React.createElement('span', {
|
||||
key: 'status',
|
||||
className: "text-sm text-secondary"
|
||||
}, (Array.isArray(customIceServers) && customIceServers.length)
|
||||
? `Using ${customIceServers.length} custom ICE server(s)`
|
||||
: 'Using public ICE servers'),
|
||||
}, 'STUN/TURN servers'),
|
||||
React.createElement('button', {
|
||||
key: 'btn',
|
||||
type: 'button',
|
||||
onClick: () => setShowIceSettings(true),
|
||||
onClick: () => window.dispatchEvent(new CustomEvent('securebit:open-network-settings')),
|
||||
className: "px-3 py-2 text-sm rounded-lg border border-purple-500/30 text-primary"
|
||||
}, [
|
||||
React.createElement('i', { key: 'i', className: 'fas fa-network-wired mr-2' }),
|
||||
'Advanced network settings'
|
||||
])
|
||||
]),
|
||||
(typeof window !== 'undefined' && window.IceServerSettings) ? React.createElement(window.IceServerSettings, {
|
||||
key: 'ice-settings-modal',
|
||||
isOpen: showIceSettings,
|
||||
onClose: () => setShowIceSettings(false),
|
||||
initial: {
|
||||
useCustom: Array.isArray(customIceServers) && customIceServers.length > 0,
|
||||
serversText: iceServersText,
|
||||
privacyMode: relayOnlyMode ? 'relay-only' : 'standard',
|
||||
persisted: iceSettingsPersisted
|
||||
},
|
||||
hasSaved: iceSettingsPersisted,
|
||||
onApply: handleApplyIceSettings,
|
||||
onForget: handleForgetIceSettings
|
||||
}) : null,
|
||||
|
||||
React.createElement('div', {
|
||||
key: 'options',
|
||||
@@ -1620,6 +1582,13 @@ import { loadIceSettings, saveIceSettings, clearIceSettings } from './network/ic
|
||||
return () => { cancelled = true; };
|
||||
}, []);
|
||||
|
||||
// Global entry point: the header gear dispatches this event.
|
||||
React.useEffect(() => {
|
||||
const open = () => setShowIceSettings(true);
|
||||
window.addEventListener('securebit:open-network-settings', open);
|
||||
return () => window.removeEventListener('securebit:open-network-settings', open);
|
||||
}, []);
|
||||
|
||||
const handleApplyIceSettings = React.useCallback((next, persist) => {
|
||||
const servers = next.useCustom && Array.isArray(next.servers) ? next.servers : null;
|
||||
setCustomIceServers(servers && servers.length ? servers : null);
|
||||
@@ -2102,7 +2071,7 @@ import { loadIceSettings, saveIceSettings, clearIceSettings } from './network/ic
|
||||
}
|
||||
}
|
||||
|
||||
handleMessage(' SecureBit.chat Enhanced Security Edition v4.8.9 - ECDH + DTLS + SAS initialized. Ready to establish a secure connection with ECDH key exchange, DTLS fingerprint verification, and SAS authentication to prevent MITM attacks.', 'system');
|
||||
handleMessage(' SecureBit.chat Enhanced Security Edition v4.8.10 - ECDH + DTLS + SAS initialized. Ready to establish a secure connection with ECDH key exchange, DTLS fingerprint verification, and SAS authentication to prevent MITM attacks.', 'system');
|
||||
|
||||
const handleBeforeUnload = (event) => {
|
||||
if (event.type === 'beforeunload' && !isTabSwitching) {
|
||||
@@ -3791,9 +3760,23 @@ import { loadIceSettings, saveIceSettings, clearIceSettings } from './network/ic
|
||||
}
|
||||
}, [showQRScannerModal]);
|
||||
|
||||
return React.createElement('div', {
|
||||
className: "minimal-bg min-h-screen"
|
||||
return React.createElement('div', {
|
||||
className: "minimal-bg min-h-screen"
|
||||
}, [
|
||||
(typeof window !== 'undefined' && window.IceServerSettings) ? React.createElement(window.IceServerSettings, {
|
||||
key: 'ice-settings-modal',
|
||||
isOpen: showIceSettings,
|
||||
onClose: () => setShowIceSettings(false),
|
||||
initial: {
|
||||
useCustom: Array.isArray(customIceServers) && customIceServers.length > 0,
|
||||
serversText: iceServersText,
|
||||
privacyMode: relayOnlyMode ? 'relay-only' : 'standard',
|
||||
persisted: iceSettingsPersisted
|
||||
},
|
||||
hasSaved: iceSettingsPersisted,
|
||||
onApply: handleApplyIceSettings,
|
||||
onForget: handleForgetIceSettings
|
||||
}) : null,
|
||||
window.EnhancedMinimalHeader && React.createElement(window.EnhancedMinimalHeader, {
|
||||
key: 'header',
|
||||
status: connectionStatus,
|
||||
|
||||
@@ -539,7 +539,7 @@ const EnhancedMinimalHeader = ({
|
||||
React.createElement('p', {
|
||||
key: 'subtitle',
|
||||
className: 'text-xs sm:text-sm text-muted hidden sm:block'
|
||||
}, 'End-to-end freedom v4.8.9')
|
||||
}, 'End-to-end freedom v4.8.10')
|
||||
])
|
||||
]),
|
||||
|
||||
@@ -549,6 +549,17 @@ const EnhancedMinimalHeader = ({
|
||||
className: 'flex items-center space-x-2 sm:space-x-3'
|
||||
}, [
|
||||
|
||||
React.createElement('button', {
|
||||
key: 'network-settings',
|
||||
type: 'button',
|
||||
onClick: () => window.dispatchEvent(new CustomEvent('securebit:open-network-settings')),
|
||||
title: 'Advanced network settings (STUN/TURN)',
|
||||
'aria-label': 'Advanced network settings',
|
||||
className: 'w-8 h-8 rounded-full flex items-center justify-center text-muted hover:text-primary hover:bg-white/5 transition-colors duration-200'
|
||||
}, [
|
||||
React.createElement('i', { key: 'i', className: 'fas fa-network-wired text-sm' })
|
||||
]),
|
||||
|
||||
displaySecurityLevel && React.createElement('div', {
|
||||
key: 'security-level',
|
||||
className: 'hidden md:flex items-center space-x-2 cursor-pointer hover:opacity-80 transition-opacity duration-200',
|
||||
|
||||
Reference in New Issue
Block a user