feat(web): topologies nav entry and /mazenet route guard
New /topologies page lists topologies; a bare /mazenet now redirects there since the editor has no meaning without ?topology=<id>. Wizard picks up a note style + tweaked copy.
This commit is contained in:
@@ -13,6 +13,15 @@ import RemoteUpdates from './components/RemoteUpdates';
|
||||
import SwarmHosts from './components/SwarmHosts';
|
||||
import AgentEnrollment from './components/AgentEnrollment';
|
||||
import MazeNET from './components/MazeNET/MazeNET';
|
||||
import TopologyList from './components/TopologyList/TopologyList';
|
||||
|
||||
/* Guard the /mazenet route so it's always bound to a real topology.
|
||||
* Bare /mazenet → /topologies; ?topology=<id> → editor. */
|
||||
function MazeNETRoute() {
|
||||
const qs = typeof window !== 'undefined' ? window.location.search : '';
|
||||
const hasId = new URLSearchParams(qs).get('topology');
|
||||
return hasId ? <MazeNET /> : <Navigate to="/topologies" replace />;
|
||||
}
|
||||
|
||||
function isTokenValid(token: string): boolean {
|
||||
try {
|
||||
@@ -63,7 +72,8 @@ function App() {
|
||||
<Routes>
|
||||
<Route path="/" element={<Dashboard searchQuery={searchQuery} />} />
|
||||
<Route path="/fleet" element={<DeckyFleet />} />
|
||||
<Route path="/mazenet" element={<MazeNET />} />
|
||||
<Route path="/topologies" element={<TopologyList />} />
|
||||
<Route path="/mazenet" element={<MazeNETRoute />} />
|
||||
<Route path="/live-logs" element={<LiveLogs />} />
|
||||
<Route path="/bounty" element={<Bounty />} />
|
||||
<Route path="/attackers" element={<Attackers />} />
|
||||
|
||||
@@ -43,6 +43,7 @@ const Layout: React.FC<LayoutProps> = ({ children, onLogout, onSearch }) => {
|
||||
<nav className="sidebar-nav">
|
||||
<NavItem to="/" icon={<LayoutDashboard size={20} />} label="Dashboard" open={sidebarOpen} />
|
||||
<NavItem to="/fleet" icon={<Server size={20} />} label="Decoy Fleet" open={sidebarOpen} />
|
||||
<NavItem to="/topologies" icon={<Network size={20} />} label="Topologies" open={sidebarOpen} />
|
||||
<NavItem to="/mazenet" icon={<Network size={20} />} label="MazeNET" open={sidebarOpen} />
|
||||
<NavItem to="/live-logs" icon={<Terminal size={20} />} label="Live Logs" open={sidebarOpen} />
|
||||
<NavItem to="/bounty" icon={<Archive size={20} />} label="Bounty" open={sidebarOpen} />
|
||||
|
||||
@@ -176,6 +176,27 @@
|
||||
accent-color: var(--violet);
|
||||
}
|
||||
|
||||
.ctw-note {
|
||||
padding: 10px 12px;
|
||||
border: 1px dashed var(--violet);
|
||||
color: var(--text-color);
|
||||
font-size: 0.7rem;
|
||||
line-height: 1.5;
|
||||
letter-spacing: 0.3px;
|
||||
background: var(--violet-tint-10, rgba(238, 130, 238, 0.08));
|
||||
}
|
||||
.ctw-note strong {
|
||||
color: var(--violet);
|
||||
letter-spacing: 1px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
.ctw-note code {
|
||||
background: #000;
|
||||
padding: 1px 5px;
|
||||
font-family: var(--font-mono);
|
||||
color: var(--matrix, #33ff66);
|
||||
}
|
||||
|
||||
.ctw-error {
|
||||
padding: 10px 12px;
|
||||
border: 1px solid var(--alert, #e74c3c);
|
||||
|
||||
@@ -255,6 +255,14 @@ const CreateTopologyWizard: React.FC<Props> = ({ open, onClose, onCreated }) =>
|
||||
<>
|
||||
<div className="ctw-label">Where should this topology run?</div>
|
||||
<div className="ctw-grid-3">{step0Cards}</div>
|
||||
<div className="ctw-note">
|
||||
<strong>HEADS UP:</strong> the gateway decky publishes its
|
||||
service ports on the target host (e.g. <code>0.0.0.0:22</code>{' '}
|
||||
for SSH). Move any host-side daemons off collision ports
|
||||
BEFORE deploying — otherwise docker will fail with{' '}
|
||||
<code>address already in use</code>. On a fresh VPS this
|
||||
usually means relocating sshd to <code>2222</code>.
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user