mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-05-13 12:04:56 +02:00
fix: allow Docker internal IPs for local operator + bump changelog text sizes
- require_local_operator now recognizes Docker bridge network IPs (172.x, 192.168.x, 10.x) as local, fixing "Forbidden — local operator access only" when frontend container calls wormhole/mesh endpoints - Bumped all changelog modal text from 8-9px to 11-13px for readability
This commit is contained in:
+12
-2
@@ -1073,10 +1073,20 @@ def require_admin(request: Request):
|
||||
raise HTTPException(status_code=403, detail=detail)
|
||||
|
||||
|
||||
def _is_local_or_docker(host: str) -> bool:
|
||||
"""Return True if the IP is loopback or a Docker-internal private network."""
|
||||
if host in {"127.0.0.1", "::1", "localhost"}:
|
||||
return True
|
||||
# Docker bridge networks use 172.x.x.x or 192.168.x.x ranges
|
||||
if host.startswith("172.") or host.startswith("192.168.") or host.startswith("10."):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def require_local_operator(request: Request):
|
||||
"""Allow local tooling on loopback, or a valid admin key from elsewhere."""
|
||||
"""Allow local tooling on loopback / Docker internal network, or a valid admin key."""
|
||||
host = (request.client.host or "").lower() if request.client else ""
|
||||
if host in {"127.0.0.1", "::1", "localhost"} or (_debug_mode_enabled() and host == "test"):
|
||||
if _is_local_or_docker(host) or (_debug_mode_enabled() and host == "test"):
|
||||
return
|
||||
admin_key = _current_admin_key()
|
||||
presented = str(request.headers.get("X-Admin-Key", "") or "").strip()
|
||||
|
||||
@@ -20,7 +20,7 @@ const STORAGE_KEY = `shadowbroker_changelog_v${CURRENT_VERSION}`;
|
||||
const RELEASE_TITLE = 'InfoNet Experimental Testnet — Decentralized Intelligence Experiment';
|
||||
|
||||
const HEADLINE_FEATURE = {
|
||||
icon: <Terminal size={16} className="text-cyan-400" />,
|
||||
icon: <Terminal size={20} className="text-cyan-400" />,
|
||||
title: 'InfoNet Experimental Testnet is Live',
|
||||
subtitle: 'The first decentralized intelligence mesh built directly into an OSINT platform. This is an experimental testnet — NOT a privacy tool.',
|
||||
details: [
|
||||
@@ -34,43 +34,43 @@ const HEADLINE_FEATURE = {
|
||||
|
||||
const NEW_FEATURES = [
|
||||
{
|
||||
icon: <Radio size={14} className="text-amber-400" />,
|
||||
icon: <Radio size={18} className="text-amber-400" />,
|
||||
title: 'Meshtastic + APRS Radio Integration',
|
||||
desc: 'Live Meshtastic mesh radio nodes plotted worldwide via MQTT. APRS amateur radio positioning via APRS-IS TCP feed. Both integrated into Mesh Chat and the SIGINT grid. Note: Mesh radio is NOT private — RF transmissions are public by nature.',
|
||||
color: 'amber',
|
||||
},
|
||||
{
|
||||
icon: <Terminal size={14} className="text-cyan-400" />,
|
||||
icon: <Terminal size={18} className="text-cyan-400" />,
|
||||
title: 'Mesh Terminal',
|
||||
desc: 'Built-in command-line interface. Send messages, DMs, run market commands, inspect gate state. Draggable panel, minimizes to the top bar. Type "help" to see everything.',
|
||||
color: 'cyan',
|
||||
},
|
||||
{
|
||||
icon: <Search size={14} className="text-green-400" />,
|
||||
icon: <Search size={18} className="text-green-400" />,
|
||||
title: 'Shodan Device Search',
|
||||
desc: 'Query Shodan directly from ShadowBroker. Search internet-connected devices by keyword, CVE, or port — results plotted as a live overlay on the map with configurable marker style.',
|
||||
color: 'green',
|
||||
},
|
||||
{
|
||||
icon: <Camera size={14} className="text-emerald-400" />,
|
||||
icon: <Camera size={18} className="text-emerald-400" />,
|
||||
title: 'CCTV Mesh Expanded — 12 Sources, 11,000+ Cameras',
|
||||
desc: 'Massive expansion: added Spain (DGT national + Madrid city), California (12 Caltrans districts), Washington State, Georgia, Illinois, Michigan, and Windy Webcams. Now covers 6 countries. Enabled by default.',
|
||||
color: 'emerald',
|
||||
},
|
||||
{
|
||||
icon: <TrainFront size={14} className="text-blue-400" />,
|
||||
icon: <TrainFront size={18} className="text-blue-400" />,
|
||||
title: 'Train Tracking (Amtrak + European Rail)',
|
||||
desc: 'Real-time Amtrak train positions across the US and European rail via DigiTraffic. Speed, heading, route, and status for every train on the network.',
|
||||
color: 'blue',
|
||||
},
|
||||
{
|
||||
icon: <Globe size={14} className="text-purple-400" />,
|
||||
icon: <Globe size={18} className="text-purple-400" />,
|
||||
title: '8 New Intelligence Layers',
|
||||
desc: 'Volcanoes (Smithsonian), air quality PM2.5 (OpenAQ), severe weather alerts, fishing activity (Global Fishing Watch), military bases, 35K+ power plants, SatNOGS ground stations, TinyGS LoRa satellites, VIIRS nightlights.',
|
||||
color: 'purple',
|
||||
},
|
||||
{
|
||||
icon: <Shield size={14} className="text-yellow-400" />,
|
||||
icon: <Shield size={18} className="text-yellow-400" />,
|
||||
title: 'Sentinel Hub Imagery + Desktop Shell Scaffold',
|
||||
desc: 'Copernicus CDSE satellite imagery via Sentinel Hub Process API with OAuth2 token flow. Desktop-native control routing scaffold (pre-Tauri) with session profiles and audit trail.',
|
||||
color: 'yellow',
|
||||
@@ -206,7 +206,7 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
|
||||
className="fixed inset-0 z-[10001] flex items-center justify-center pointer-events-none"
|
||||
>
|
||||
<div
|
||||
className="w-[620px] max-h-[90vh] bg-[var(--bg-secondary)]/98 border border-cyan-900/50 pointer-events-auto flex flex-col overflow-hidden"
|
||||
className="w-[700px] max-h-[90vh] bg-[var(--bg-secondary)]/98 border border-cyan-900/50 pointer-events-auto flex flex-col overflow-hidden"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{/* Header */}
|
||||
@@ -214,14 +214,14 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="px-2 py-1 bg-cyan-500/15 border border-cyan-500/30 text-[10px] font-mono font-bold text-cyan-400 tracking-widest">
|
||||
<div className="px-2.5 py-1 bg-cyan-500/15 border border-cyan-500/30 text-xs font-mono font-bold text-cyan-400 tracking-widest">
|
||||
v{CURRENT_VERSION}
|
||||
</div>
|
||||
<h2 className="text-sm font-bold tracking-[0.15em] text-[var(--text-primary)] font-mono">
|
||||
<h2 className="text-base font-bold tracking-[0.15em] text-[var(--text-primary)] font-mono">
|
||||
WHAT'S NEW
|
||||
</h2>
|
||||
</div>
|
||||
<p className="text-[9px] text-cyan-500/70 font-mono tracking-widest mt-1">
|
||||
<p className="text-[11px] text-cyan-500/70 font-mono tracking-widest mt-1">
|
||||
{RELEASE_TITLE.toUpperCase()}
|
||||
</p>
|
||||
</div>
|
||||
@@ -239,14 +239,14 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
|
||||
{/* === HEADLINE: InfoNet Testnet === */}
|
||||
<div className="border border-cyan-500/30 bg-cyan-950/20 p-4 space-y-3">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 border border-cyan-500/40 bg-cyan-500/10 flex items-center justify-center flex-shrink-0">
|
||||
<div className="w-9 h-9 border border-cyan-500/40 bg-cyan-500/10 flex items-center justify-center flex-shrink-0">
|
||||
{HEADLINE_FEATURE.icon}
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-[11px] font-mono text-cyan-300 font-bold tracking-wide">
|
||||
<div className="text-sm font-mono text-cyan-300 font-bold tracking-wide">
|
||||
{HEADLINE_FEATURE.title}
|
||||
</div>
|
||||
<div className="text-[9px] font-mono text-cyan-500/80 mt-0.5">
|
||||
<div className="text-xs font-mono text-cyan-500/80 mt-0.5">
|
||||
{HEADLINE_FEATURE.subtitle}
|
||||
</div>
|
||||
</div>
|
||||
@@ -256,7 +256,7 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
|
||||
{HEADLINE_FEATURE.details.map((para, i) => (
|
||||
<p
|
||||
key={i}
|
||||
className="text-[9px] font-mono text-[var(--text-secondary)] leading-relaxed"
|
||||
className="text-xs font-mono text-[var(--text-secondary)] leading-relaxed"
|
||||
>
|
||||
{para}
|
||||
</p>
|
||||
@@ -265,12 +265,12 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
|
||||
|
||||
{/* Testnet disclaimer */}
|
||||
<div className="flex items-start gap-2 p-2.5 border border-red-500/30 bg-red-950/20">
|
||||
<span className="text-red-400 text-[10px] mt-0.5 flex-shrink-0 font-bold">!!</span>
|
||||
<span className="text-red-400 text-xs mt-0.5 flex-shrink-0 font-bold">!!</span>
|
||||
<div className="space-y-1.5">
|
||||
<span className="text-[8px] font-mono text-red-400/90 leading-relaxed block font-bold">
|
||||
<span className="text-[11px] font-mono text-red-400/90 leading-relaxed block font-bold">
|
||||
EXPERIMENTAL TESTNET — NO PRIVACY GUARANTEE
|
||||
</span>
|
||||
<span className="text-[8px] font-mono text-amber-400/80 leading-relaxed block">
|
||||
<span className="text-[11px] font-mono text-amber-400/80 leading-relaxed block">
|
||||
InfoNet messages are obfuscated but NOT encrypted end-to-end. The Mesh network
|
||||
(Meshtastic/APRS) is NOT private — radio transmissions are inherently
|
||||
public. Do not send anything sensitive on any channel. Privacy and E2E encryption
|
||||
@@ -281,7 +281,7 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
|
||||
|
||||
{/* CTA */}
|
||||
<div className="text-center pt-1">
|
||||
<span className="text-[8px] font-mono text-cyan-400 tracking-[0.25em] font-bold">
|
||||
<span className="text-[11px] font-mono text-cyan-400 tracking-[0.25em] font-bold">
|
||||
{HEADLINE_FEATURE.callToAction}
|
||||
</span>
|
||||
</div>
|
||||
@@ -289,8 +289,8 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
|
||||
|
||||
{/* === Other New Features === */}
|
||||
<div>
|
||||
<div className="text-[9px] font-mono tracking-[0.2em] text-cyan-400 font-bold mb-3 flex items-center gap-2">
|
||||
<div className="w-1.5 h-1.5 rounded-full bg-cyan-400 animate-pulse" />
|
||||
<div className="text-xs font-mono tracking-[0.2em] text-cyan-400 font-bold mb-3 flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-cyan-400 animate-pulse" />
|
||||
NEW CAPABILITIES
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
@@ -301,10 +301,10 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
|
||||
>
|
||||
<div className="mt-0.5 flex-shrink-0">{f.icon}</div>
|
||||
<div>
|
||||
<div className="text-[10px] font-mono text-[var(--text-primary)] font-bold">
|
||||
<div className="text-[13px] font-mono text-[var(--text-primary)] font-bold">
|
||||
{f.title}
|
||||
</div>
|
||||
<div className="text-[9px] font-mono text-[var(--text-muted)] leading-relaxed mt-0.5">
|
||||
<div className="text-xs font-mono text-[var(--text-muted)] leading-relaxed mt-0.5">
|
||||
{f.desc}
|
||||
</div>
|
||||
</div>
|
||||
@@ -315,15 +315,15 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
|
||||
|
||||
{/* Bug Fixes */}
|
||||
<div>
|
||||
<div className="text-[9px] font-mono tracking-[0.2em] text-green-400 font-bold mb-3 flex items-center gap-2">
|
||||
<Bug size={10} className="text-green-400" />
|
||||
<div className="text-xs font-mono tracking-[0.2em] text-green-400 font-bold mb-3 flex items-center gap-2">
|
||||
<Bug size={14} className="text-green-400" />
|
||||
FIXES & IMPROVEMENTS
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
{BUG_FIXES.map((fix, i) => (
|
||||
<div key={i} className="flex items-start gap-2 px-3 py-1.5">
|
||||
<span className="text-green-500 text-[10px] mt-0.5 flex-shrink-0">+</span>
|
||||
<span className="text-[9px] font-mono text-[var(--text-secondary)] leading-relaxed">
|
||||
<span className="text-green-500 text-xs mt-0.5 flex-shrink-0">+</span>
|
||||
<span className="text-xs font-mono text-[var(--text-secondary)] leading-relaxed">
|
||||
{fix}
|
||||
</span>
|
||||
</div>
|
||||
@@ -333,8 +333,8 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
|
||||
|
||||
{/* Contributors */}
|
||||
<div>
|
||||
<div className="text-[9px] font-mono tracking-[0.2em] text-pink-400 font-bold mb-3 flex items-center gap-2">
|
||||
<Heart size={10} className="text-pink-400" />
|
||||
<div className="text-xs font-mono tracking-[0.2em] text-pink-400 font-bold mb-3 flex items-center gap-2">
|
||||
<Heart size={14} className="text-pink-400" />
|
||||
COMMUNITY CONTRIBUTORS
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
@@ -343,19 +343,19 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
|
||||
key={i}
|
||||
className="flex items-start gap-2 px-3 py-2 border border-pink-500/20 bg-pink-500/5"
|
||||
>
|
||||
<span className="text-pink-400 text-[10px] mt-0.5 flex-shrink-0">
|
||||
<span className="text-pink-400 text-xs mt-0.5 flex-shrink-0">
|
||||
♥
|
||||
</span>
|
||||
<div>
|
||||
<span className="text-[10px] font-mono text-pink-300 font-bold">
|
||||
<span className="text-[13px] font-mono text-pink-300 font-bold">
|
||||
{c.name}
|
||||
</span>
|
||||
<span className="text-[9px] font-mono text-[var(--text-muted)]">
|
||||
<span className="text-xs font-mono text-[var(--text-muted)]">
|
||||
{' '}
|
||||
— {c.desc}
|
||||
</span>
|
||||
{c.pr && (
|
||||
<span className="text-[8px] font-mono text-[var(--text-muted)]">
|
||||
<span className="text-[11px] font-mono text-[var(--text-muted)]">
|
||||
{' '}
|
||||
(PR {c.pr})
|
||||
</span>
|
||||
@@ -371,7 +371,7 @@ const ChangelogModal = React.memo(function ChangelogModal({ onClose }: Changelog
|
||||
<div className="p-4 border-t border-[var(--border-primary)]/80 flex items-center justify-center">
|
||||
<button
|
||||
onClick={handleDismiss}
|
||||
className="px-8 py-2.5 bg-cyan-500/15 border border-cyan-500/40 text-cyan-400 hover:bg-cyan-500/25 text-[10px] font-mono tracking-[0.2em] transition-all"
|
||||
className="px-8 py-2.5 bg-cyan-500/15 border border-cyan-500/40 text-cyan-400 hover:bg-cyan-500/25 text-xs font-mono tracking-[0.2em] transition-all"
|
||||
>
|
||||
ACKNOWLEDGED
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user