Entries This Round
@@ -182,6 +225,21 @@ export default function RafflePage() {
{errMsg}
)}
+
+
Pay with USD balance
+
+ Same ticket — charges your Bitcoin-funded USD balance at ≈ ${ticketUsd.toFixed(2)} (live BTC spot). No separate txid needed.
+
+
+
+
{!user && (
Sign in{" "}
diff --git a/app/root-layout-client.tsx b/app/root-layout-client.tsx
index 0ef37ee..9876f66 100644
--- a/app/root-layout-client.tsx
+++ b/app/root-layout-client.tsx
@@ -8,26 +8,48 @@ import HubChatterPublicStrip from "@/components/HubChatterPublicStrip";
import AppProviders from "@/components/AppProviders";
import DarkWebLaunchFooter from "@/components/DarkWebLaunchFooter";
+const DDOS_KEY = "ddos_verified";
+
+function readDdosVerified(): boolean {
+ if (typeof window === "undefined") return false;
+ try {
+ if (sessionStorage.getItem(DDOS_KEY) === "true") return true;
+ } catch {
+ /* sessionStorage blocked */
+ }
+ try {
+ if (localStorage.getItem(DDOS_KEY) === "true") return true;
+ } catch {
+ /* localStorage blocked */
+ }
+ return false;
+}
+
+function persistDdosVerified(): void {
+ try {
+ sessionStorage.setItem(DDOS_KEY, "true");
+ } catch {
+ /* ignore */
+ }
+ try {
+ localStorage.setItem(DDOS_KEY, "true");
+ } catch {
+ /* ignore */
+ }
+}
+
export default function RootLayoutClient({ children }: { children: React.ReactNode }) {
+ /** Always start true for matching server/client HTML; effect unlocks if already verified. */
const [isProtected, setIsProtected] = useState(true);
useEffect(() => {
- try {
- const hasSeenDDoS = sessionStorage.getItem("ddos_verified");
- if (hasSeenDDoS) {
- setIsProtected(false);
- }
- } catch {
- // sessionStorage blocked (rare) — still allow progress overlay to complete
+ if (readDdosVerified()) {
+ setIsProtected(false);
}
}, []);
const handleComplete = useCallback(() => {
- try {
- sessionStorage.setItem("ddos_verified", "true");
- } catch {
- /* ignore */
- }
+ persistDdosVerified();
setIsProtected(false);
}, []);
diff --git a/app/vault/page.tsx b/app/vault/page.tsx
index d00e418..5a6a837 100644
--- a/app/vault/page.tsx
+++ b/app/vault/page.tsx
@@ -2,152 +2,242 @@
import Link from "next/link";
import { useState, useEffect, useCallback } from "react";
+import { useAccount } from "@/contexts/AccountContext";
-export default function VaultNetworkPage() {
+type Msg = { id: string; from: string; text: string; ts: number; channel?: string };
+
+export default function VaultAdminDashboard() {
+ const { user, hydrated, signIn } = useAccount();
const [btcUsd, setBtcUsd] = useState(null);
- const [btcErr, setBtcErr] = useState(null);
+ const [messages, setMessages] = useState([]);
const [broadcast, setBroadcast] = useState("");
const [terminalLines, setTerminalLines] = useState([]);
- const [sessionToken, setSessionToken] = useState("");
+ const [loginPass, setLoginPass] = useState("");
+ const [loginError, setLoginError] = useState("");
const fetchBtc = useCallback(async () => {
try {
const res = await fetch("https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd", {
cache: "no-store",
});
- if (!res.ok) throw new Error("rate http");
- const j = (await res.json()) as { bitcoin?: { usd?: number } };
- const p = j.bitcoin?.usd;
- if (p && Number.isFinite(p)) {
- setBtcUsd(p);
- setBtcErr(null);
- } else throw new Error("bad payload");
+ const j = await res.json();
+ setBtcUsd(j.bitcoin?.usd || null);
} catch {
- setBtcErr("Could not load BTC/USD");
+ // ignore
+ }
+ }, []);
+
+ const fetchMessages = useCallback(async () => {
+ try {
+ const res = await fetch("/api/messages?channel=all");
+ const data = await res.json();
+ if (data.ok) setMessages(data.messages);
+ } catch {
+ // ignore
}
}, []);
- useEffect(() => {
- setSessionToken(
- typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID().slice(0, 13) : String(Date.now()),
- );
- }, []);
-
useEffect(() => {
void fetchBtc();
- const id = setInterval(() => void fetchBtc(), 60_000);
+ void fetchMessages();
+ const id = setInterval(() => {
+ void fetchBtc();
+ void fetchMessages();
+ }, 10_000);
return () => clearInterval(id);
- }, [fetchBtc]);
+ }, [fetchBtc, fetchMessages]);
useEffect(() => {
const interval = setInterval(() => {
const logs = [
- `[TOR] circuit refresh (synthetic tick — not your live Tor log)`,
- `[NGINX] 200 GET /market from 127.0.0.1 (example line)`,
- `[CYBERLUX] cart shard heartbeat OK`,
- `[BTC/USD] spot ${btcUsd != null ? `$${btcUsd.toLocaleString(undefined, { maximumFractionDigits: 0 })}` : "…"}`,
+ `[TOR_ADMIN] Relay ping successful. Circuit latency: ${Math.floor(Math.random() * 80 + 20)}ms`,
+ `[NGINX_ROUTER] Routing loopback 127.0.0.1:8080 -> next:3000`,
+ `[SECURITY] Null-routing unauthorized clearnet probe from ${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`,
+ `[BTC_NODE] Synced block height ${839000 + Math.floor(Math.random() * 1000)}`,
+ `[SYSTEM] Memory stable. Cache flushed.`,
];
setTerminalLines((prev) => [...prev.slice(-15), logs[Math.floor(Math.random() * logs.length)]!]);
- }, 4500);
+ }, 3500);
return () => clearInterval(interval);
- }, [btcUsd]);
+ }, []);
- const handleBroadcast = () => {
- localStorage.setItem("shadow_broadcast", broadcast);
- setTerminalLines((prev) => [...prev, `[ADMIN] GLOBAL BROADCAST: ${broadcast || "(empty)"}`]);
+ const handleLogin = async (e: React.FormEvent) => {
+ e.preventDefault();
+ setLoginError("");
+ const res = await signIn("drjones", loginPass);
+ if (!res.ok) {
+ setLoginError(res.error || "Access Denied");
+ }
};
- const btcDisplay =
- btcUsd != null
- ? btcUsd.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
- : btcErr ?? "…";
+ const handleBroadcast = async () => {
+ if (!broadcast.trim()) return;
+ try {
+ await fetch("/api/messages", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ from: "System Admin", text: `[GLOBAL BROADCAST] ${broadcast}`, channel: "global" }),
+ });
+ setTerminalLines((prev) => [...prev, `[ADMIN] GLOBAL BROADCAST SENT: ${broadcast}`]);
+ setBroadcast("");
+ void fetchMessages();
+ } catch {
+ setTerminalLines((prev) => [...prev, `[ADMIN] Broadcast Failed!`]);
+ }
+ };
+
+ const deleteMessage = async (id: string) => {
+ await fetch(`/api/messages?id=${id}`, { method: "DELETE" });
+ void fetchMessages();
+ setTerminalLines((prev) => [...prev, `[ADMIN] Deleted message ${id}`]);
+ };
+
+ const clearAllMessages = async () => {
+ if (!confirm("Are you sure you want to nuke all global communications?")) return;
+ await fetch(`/api/messages?all=true`, { method: "DELETE" });
+ void fetchMessages();
+ setTerminalLines((prev) => [...prev, `[ADMIN] Nuked all global messages.`]);
+ };
+
+ if (!hydrated) {
+ return Initializing connection...
;
+ }
+
+ // Only drjones gets to see the true dashboard
+ if (!user || user.username !== "drjones") {
+ return (
+
+
+
RESTRICTED ZONE
+
EldritchWeave Tor Network Admin
+
+
+
+
+ Return to Hub
+
+
+
+ );
+ }
return (
-
-
+
+
-
-
Public spot (CoinGecko)
-
-
BTC/USD
-
${btcDisplay}
+
+
System Telemetry
+
+ Active Relays
+ 43
+
+
+ BTC/USD Oracle
+ ${btcUsd ? btcUsd.toLocaleString() : "..."}
+
+
+ Firewall Integrity
+ 100%
-
- Refreshes about every minute. For deposits use{" "}
-
- Add funds
-
- .
-
-
-
Broadcast stub
+
+
Global Network Override
-
-
Node map
-
- Decorative. Real topology is Tor + nginx on your host — see README / DEPLOY.md.
-
+
+
Network Operations Logs
+
+
+ {terminalLines.map((line, i) => (
+
+ {line}
+
+ ))}
+
_
+
+
-
-
-
Chatter console
-
● FEED
+
+
+ Comms Interception (Wiretap)
+
+ NUKE ALL
+
-
- {terminalLines.map((line, i) => (
-
- {line}
-
- ))}
-
_
-
-
-
-
- Dashboard
-
- {" · "}
-
- Checkout
-
- {" · "}
-
- Hub
-
+
+ {messages.length === 0 ? (
+
No network traffic detected...
+ ) : (
+ messages.map((msg) => (
+
+
+
+ @{msg.from}
+ CH: {msg.channel || "global"}
+ {new Date(msg.ts).toLocaleString()}
+
+
deleteMessage(msg.id)}
+ className="text-[10px] font-bold text-red-500 hover:text-red-400 underline"
+ >
+ [DELETE]
+
+
+
{msg.text}
+
+ )).reverse()
+ )}
+
);
-}
+}
\ No newline at end of file
diff --git a/app/wallets/page.tsx b/app/wallets/page.tsx
index ba8b501..4db41f7 100644
--- a/app/wallets/page.tsx
+++ b/app/wallets/page.tsx
@@ -2,6 +2,7 @@
import { useState } from "react";
import Link from "next/link";
+import PayWithUsdBalanceButton from "@/components/PayWithUsdBalanceButton";
import ThemedLayout from "@/components/layouts/ThemedLayout";
import { useCart } from "@/contexts/CartContext";
import type { ShopProduct } from "@/lib/shopCatalog";
@@ -164,6 +165,17 @@ export default function DigitalPassesPage() {
>
{isAdded ? "✓ Added to Cart" : `Add to Cart — $${pass.price}`}
+
+
Or pay instantly (BTC-funded USD)
+
+
);
})}
diff --git a/components/ChatWidget.tsx b/components/ChatWidget.tsx
index 53fe4ea..464e0b1 100644
--- a/components/ChatWidget.tsx
+++ b/components/ChatWidget.tsx
@@ -6,54 +6,13 @@ import { useAccount } from "@/contexts/AccountContext";
type Msg = {
id: string;
- sender: string;
+ from: string;
text: string;
- time: string;
- mine: boolean;
+ ts: number;
};
-const SEED_MSGS: Omit
[] = [
- { id: "s1", sender: "void_cartographer", text: "Anyone else notice the latency on the east relay dropped by 40ms this cycle?", time: "01:12" },
- { id: "s2", sender: "relay_op", text: "Circuit refresh interval was tuned last night. Should hold for 72h.", time: "01:14" },
- { id: "s3", sender: "ledger_moth", text: "New drops posted on /market — entropy dongles and the opsec consult bundle.", time: "01:17" },
- { id: "s4", sender: "phantom_q", text: "Verified the hub PGP against the mirror list. All checksums matched.", time: "01:19" },
- { id: "s5", sender: "void_cartographer", text: "Anyone have a rec for a good XMR <-> BTC bridge that doesn't log?", time: "01:22" },
- { id: "s6", sender: "relay_op", text: "Check /exchange — a few WTB listings went up in the last hour.", time: "01:24" },
-];
-
-const AUTO_REPLIES = [
- "Received. Check your vault for any pending receipts.",
- "Noted. The channel is ephemeral — nothing persists past this session unless you signed in.",
- "Copy that. See /forum for threaded discussion on that topic.",
- "Market is up. Check /drops for the latest scheduled releases.",
- "Circuit healthy. Reply latency nominal.",
- "Acknowledged. Keep OPSEC tight and verify mirrors before each session.",
-];
-
-const CHAT_KEY = "cyberlux-chat-v1";
-
-function now() {
- return new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
-}
-
-function uid() {
- return Math.random().toString(36).slice(2, 10);
-}
-
-function loadHistory(): Msg[] {
- if (typeof window === "undefined") return [];
- try {
- const raw = localStorage.getItem(CHAT_KEY);
- if (!raw) return [];
- return JSON.parse(raw) as Msg[];
- } catch {
- return [];
- }
-}
-
-function saveHistory(msgs: Msg[]) {
- if (typeof window === "undefined") return;
- localStorage.setItem(CHAT_KEY, JSON.stringify(msgs.slice(-80)));
+function now(ts: number) {
+ return new Date(ts).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
}
export default function ChatWidget() {
@@ -65,38 +24,51 @@ export default function ChatWidget() {
const [hydrated, setHydrated] = useState(false);
const endRef = useRef(null);
- useEffect(() => {
- const stored = loadHistory();
- if (stored.length > 0) {
- setMessages(stored);
- } else {
- const seeded = SEED_MSGS.map((m) => ({ ...m, mine: false }));
- setMessages(seeded);
- saveHistory(seeded);
+ const fetchMessages = useCallback(async () => {
+ try {
+ const res = await fetch("/api/messages?channel=hub");
+ const data = await res.json();
+ if (data.ok && data.messages) {
+ setMessages(data.messages);
+ }
+ } catch (e) {
+ // ignore
}
- setHydrated(true);
}, []);
+ useEffect(() => {
+ fetchMessages();
+ setHydrated(true);
+ const interval = setInterval(fetchMessages, 3000);
+ return () => clearInterval(interval);
+ }, [fetchMessages]);
+
useEffect(() => {
if (hydrated && messages.length > 0) {
- saveHistory(messages);
endRef.current?.scrollIntoView({ behavior: "smooth" });
}
}, [messages, hydrated]);
- const send = useCallback(() => {
+ const send = async () => {
const text = input.trim();
if (!text) return;
- const mine: Msg = { id: uid(), sender: handle, text, time: now(), mine: true };
- setMessages((p) => [...p, mine]);
setInput("");
- const delay = 900 + Math.random() * 900;
- setTimeout(() => {
- const replyText = AUTO_REPLIES[Math.floor(Math.random() * AUTO_REPLIES.length)]!;
- const reply: Msg = { id: uid(), sender: "System", text: replyText, time: now(), mine: false };
- setMessages((p) => [...p, reply]);
- }, delay);
- }, [input, handle]);
+
+ // Optimistic update
+ const optimisticMsg: Msg = { id: "temp-" + Date.now(), from: handle, text, ts: Date.now() };
+ setMessages((p) => [...p, optimisticMsg]);
+
+ try {
+ await fetch("/api/messages", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ from: handle, text, channel: "hub" }),
+ });
+ fetchMessages();
+ } catch (e) {
+ // ignore
+ }
+ };
return (
@@ -104,7 +76,7 @@ export default function ChatWidget() {
CHANNEL CHAT
- Ephemeral hub channel — stored locally.{" "}
+ Global hub channel — synced live.{" "}
{user ? (
Posting as @{user.username}
) : (
@@ -119,40 +91,47 @@ export default function ChatWidget() {
channel active
- local store
+ live sync
- {messages.map((msg) => (
-
-
-
- {msg.mine ? `@${handle}` : msg.sender === "System" ? "⚡ System" : `@${msg.sender}`}
-
- {msg.time}
-
-
- {msg.text}
-
-
- ))}
+ {messages.length === 0 ? (
+
No messages yet. Be the first!
+ ) : (
+ messages.map((msg) => {
+ const mine = msg.from === handle || (msg.from === "anon" && !user);
+ return (
+
+
+
+ {mine ? `@${handle}` : msg.from === "System" ? "⚡ System" : `@${msg.from}`}
+
+ {now(msg.ts)}
+
+
+ {msg.text}
+
+
+ );
+ })
+ )}
@@ -178,7 +157,7 @@ export default function ChatWidget() {
{[
- { icon: "🔒", label: "Client storage", sub: "Never leaves your browser" },
+ { icon: "🌍", label: "Global Sync", sub: "Talk to everyone" },
{ icon: "💬", label: "Open channel", sub: "Hub-wide thread" },
{ icon: "📬", label: "Forum threads", sub: "/forum for persistence" },
{ icon: "📦", label: "Market drops", sub: "/drops for schedule" },
diff --git a/components/DDoSProtection.tsx b/components/DDoSProtection.tsx
index 6f44f6a..366df3d 100644
--- a/components/DDoSProtection.tsx
+++ b/components/DDoSProtection.tsx
@@ -3,37 +3,46 @@
import Link from "next/link";
import { useState, useEffect, useRef } from "react";
+/** Total time for the progress bar to reach 100% (ms). */
+const DURATION_MS = 3500;
+/** Hard cap — always complete after this (ms) even if something glitches. */
+const MAX_WAIT_MS = 9000;
+/** Wall-clock polling (Tor Browser throttles requestAnimationFrame aggressively). */
+const TICK_MS = 50;
+
export default function DDoSProtection({ onComplete }: { onComplete: () => void }) {
const [progress, setProgress] = useState(0);
const [status, setStatus] = useState("Checking your browser…");
- /** Client-only — avoids SSR/client HTML mismatch from Math.random() in JSX. */
const [rayId, setRayId] = useState("");
const doneRef = useRef(false);
const onCompleteRef = useRef(onComplete);
onCompleteRef.current = onComplete;
+ const finish = () => {
+ if (doneRef.current) return;
+ doneRef.current = true;
+ setProgress(100);
+ setStatus("Access granted.");
+ window.setTimeout(() => onCompleteRef.current(), 400);
+ };
+
useEffect(() => {
setRayId(Math.random().toString(36).substring(2, 10).toUpperCase());
}, []);
useEffect(() => {
- const interval = setInterval(() => {
- setProgress((prev) => {
- if (prev >= 100) {
- return 100;
- }
- const next = prev + Math.random() * 15;
- if (next >= 100) {
- if (!doneRef.current) {
- doneRef.current = true;
- clearInterval(interval);
- setTimeout(() => onCompleteRef.current(), 500);
- }
- return 100;
- }
- return next;
- });
- }, 400);
+ const start = Date.now();
+ doneRef.current = false;
+
+ const progressInterval = window.setInterval(() => {
+ const elapsed = Date.now() - start;
+ const pct = Math.min(100, (elapsed / DURATION_MS) * 100);
+ setProgress(pct);
+ if (pct >= 100 || elapsed >= MAX_WAIT_MS) {
+ window.clearInterval(progressInterval);
+ finish();
+ }
+ }, TICK_MS);
const statusUpdates = [
"Checking your browser…",
@@ -43,20 +52,24 @@ export default function DDoSProtection({ onComplete }: { onComplete: () => void
"Establishing encrypted tunnel…",
"Access granted.",
];
-
let statusIndex = 0;
- const statusInterval = setInterval(() => {
+ const statusInterval = window.setInterval(() => {
if (statusIndex < statusUpdates.length - 1) {
statusIndex++;
- setStatus(statusUpdates[statusIndex]);
+ setStatus(statusUpdates[statusIndex]!);
} else {
clearInterval(statusInterval);
}
- }, 800);
+ }, 650);
+
+ const maxTimer = window.setTimeout(() => {
+ if (!doneRef.current) finish();
+ }, MAX_WAIT_MS);
return () => {
- clearInterval(interval);
+ window.clearInterval(progressInterval);
clearInterval(statusInterval);
+ clearTimeout(maxTimer);
};
}, []);
@@ -69,25 +82,36 @@ export default function DDoSProtection({ onComplete }: { onComplete: () => void
className="w-full max-w-md border-2 border-[#00ff41]/20 bg-[#050505] p-12 shadow-[0_0_50px_rgba(0,255,65,0.1)]"
style={{ backgroundColor: "#050505", borderColor: "rgba(0,255,65,0.2)" }}
>
-
🛡️
-
DDoS Protection
-
+
🛡️
+
DDoS Protection
+
Origin shield active — wait while we validate your session. Automated requests are throttled at the edge.
-
+
{status}
- {Math.floor(progress)}%
+ {Math.floor(Math.min(100, progress))}%
-
+
+ Continue to site
+
+
+ Stuck on Tor or slow device? Tap above — no challenge required.
+
+
+
Ray ID: {rayId || "—"}
Performance & Security by ShadowGuard™
diff --git a/components/Hero.tsx b/components/Hero.tsx
index c4870f7..e546a13 100644
--- a/components/Hero.tsx
+++ b/components/Hero.tsx
@@ -32,7 +32,7 @@ const Hero = () => {
}, []);
return (
-
+
{/* Animated background particles */}
{particles.map((p, i) => (
@@ -69,25 +69,25 @@ const Hero = () => {
{/* Glitch text effect */}
-
-
- REVOLUTIONARY
+
+
+ FORBIDDEN
- E‑COMMERCE
+ DARK ARTS
- EXPERIENCE
+ EMPORIUM
-
- REVOLUTIONARY
+
+ FORBIDDEN
-
- EXPERIENCE
+
+ EMPORIUM
-
- Curated gray-market candy storefront with live catalog, vendor hall, and BTC-settled
- checkout — plus companion onions for forums, listings, and the wiki rail.
+
+ Curated mystical artifact apothecary with live catalog, alchemist guilds, and soul-bound
+ checkout — plus companion realms for covenants, incantations, and the forbidden wiki.
@@ -143,18 +143,18 @@ const Hero = () => {
{/* Stats */}
-
+
{[
- { value: String(SHOP_PRODUCT_COUNT), label: "Live SKUs", color: "text-neon-cyan" },
- { value: String(SHOP_SELLER_COUNT), label: "Vendor stalls", color: "text-neon-green" },
- { value: "₿ · Ξ · XMR", label: "Settlement rails", color: "text-neon-purple" },
- { value: "v3 ring", label: "Tor-ready layout", color: "text-neon-pink" },
+ { value: String(SHOP_PRODUCT_COUNT), label: "Arcane Relics", color: "text-neon-cyan" },
+ { value: String(SHOP_SELLER_COUNT), label: "Alchemist Guilds", color: "text-neon-green" },
+ { value: "Mana · Aether", label: "Soul bindings", color: "text-neon-purple" },
+ { value: "v3 coven", label: "Shadow routing", color: "text-neon-pink" },
].map((stat) => (
-
{stat.value}
+
{stat.value}
{stat.label}
))}
diff --git a/components/Navbar.tsx b/components/Navbar.tsx
index 0d5b34b..9e5016a 100644
--- a/components/Navbar.tsx
+++ b/components/Navbar.tsx
@@ -1,98 +1,134 @@
"use client";
-import { useState } from "react";
+import { useState, useRef, useEffect } from "react";
import Link from "next/link";
import { useWallet } from "@/contexts/WalletContext";
import { useAccount } from "@/contexts/AccountContext";
import { useCart } from "@/contexts/CartContext";
+import { SITE_NAV_GROUPS } from "@/lib/siteNav";
const Navbar = () => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
+ const [pagesOpen, setPagesOpen] = useState(false);
+ const pagesDropdownRef = useRef
(null);
const { luxCredits, usdStoreCredit } = useWallet();
const { user, hydrated } = useAccount();
const { itemCount, hydrated: cartReady } = useCart();
- const navItems = [
- { label: "Sanctuary", href: "/sanctuary", icon: "🛡️" },
- { label: "Market", href: "/market", icon: "📈" },
- { label: "Vendors", href: "/vendors", icon: "🏪" },
- { label: "Checkout", href: "/checkout", icon: "₿" },
- { label: "Forum", href: "/forum", icon: "◆" },
- { label: "Exchange", href: "/exchange", icon: "📰" },
- { label: "Barter", href: "/barter", icon: "♻️" },
- { label: "Vault", href: "/vault", icon: "🗝️" },
- { label: "Wiki", href: "/hidden-wiki", icon: "📚" },
- { label: "Atlas", href: "/darknet-atlas", icon: "🗺️" },
- { label: "Syndicate", href: "/syndicate", icon: "🕸️" },
- { label: "Void crawl", href: "/search", icon: "🔦" },
- { label: "Mirrors", href: "/account/hidden-services", icon: "🧅" },
- { label: "Add funds", href: "/account/add-funds", icon: "₿" },
- { label: "Dark web launch", href: "/launch", icon: "🔥" },
- ];
+ useEffect(() => {
+ const onDoc = (e: MouseEvent) => {
+ if (!pagesDropdownRef.current?.contains(e.target as Node)) setPagesOpen(false);
+ };
+ const onKey = (e: KeyboardEvent) => {
+ if (e.key === "Escape") setPagesOpen(false);
+ };
+ document.addEventListener("mousedown", onDoc);
+ document.addEventListener("keydown", onKey);
+ return () => {
+ document.removeEventListener("mousedown", onDoc);
+ document.removeEventListener("keydown", onKey);
+ };
+ }, []);
return (
-
-
- {/* Logo */}
-
-
-
-
-
⏣
+
+
+
-
- Cyber
Lux
+
+ EldritchWeave
+
-
- v1.0 • ALPHA
+
+ v1 · spellcraft
-
- {/* Desktop Navigation */}
-
- {navItems.map((item) => (
-
+
setPagesOpen((o) => !o)}
+ className="flex items-center gap-1 rounded-lg border border-white/15 bg-white/5 px-3 py-1.5 text-xs font-semibold text-foreground/85 transition hover:border-neon-cyan/35 hover:text-neon-cyan"
>
- {item.icon}
- {item.label}
-
-
- ))}
+ All pages
+ {pagesOpen ? "▴" : "▾"}
+
+ {pagesOpen ? (
+
+ {SITE_NAV_GROUPS.map((group) => (
+
+
+ {group.title}
+
+
+ {group.items.map((item) => (
+
+ setPagesOpen(false)}
+ >
+ {item.icon}
+ {item.label}
+
+
+ ))}
+
+
+ ))}
+
+ ) : null}
+
+
+
+ Market
+
+
+ Checkout
+
- {/* Actions */}
-
+
{cartReady ? (
🛒
{itemCount > 0 ? (
-
+
{itemCount > 99 ? "99+" : itemCount}
) : null}
) : null}
-
-
-
LUX
-
{luxCredits.toLocaleString()}
+
+
+ LUX
+ {luxCredits.toLocaleString()}
- USD
- ${usdStoreCredit.toFixed(2)}
+ $
+ {usdStoreCredit.toFixed(2)}
{hydrated ? (
@@ -100,28 +136,28 @@ const Navbar = () => {
<>
- Add funds
+ +Funds
-
{user.displayName}
+ {user.displayName}
>
) : (
<>
Sign in
Register
@@ -129,41 +165,39 @@ const Navbar = () => {
)
) : null}
setIsMenuOpen(!isMenuOpen)}
>
-
- {/* Mobile Menu */}
+ {/* Mobile: full menu + page list */}
{isMenuOpen && (
-
-
+
+
{cartReady ? (
setIsMenuOpen(false)}
>
🛒 Cart
{itemCount > 0 ? (
-
- {itemCount}
-
+ {itemCount}
) : null}
) : null}
{hydrated && user ? (
setIsMenuOpen(false)}
>
Dashboard
@@ -171,55 +205,35 @@ const Navbar = () => {
) : hydrated ? (
setIsMenuOpen(false)}
>
Sign in
) : null}
- {hydrated && !user ? (
- setIsMenuOpen(false)}
- >
- Register
-
- ) : null}
-
-
- {navItems.map((item) => (
- setIsMenuOpen(false)}
- >
- {item.icon}
- {item.label}
-
- ))}
-
-
- setIsMenuOpen(false)}
- >
- Sanctuary
-
- setIsMenuOpen(false)}
- >
- Onion map
-
+ {SITE_NAV_GROUPS.map((group) => (
+
+
{group.title}
+
+ {group.items.map((item) => (
+ setIsMenuOpen(false)}
+ >
+ {item.icon}
+ {item.label}
+
+ ))}
+
+
+ ))}
)}
);
};
-export default Navbar;
\ No newline at end of file
+export default Navbar;
diff --git a/components/PayWithUsdBalanceButton.tsx b/components/PayWithUsdBalanceButton.tsx
new file mode 100644
index 0000000..4355c3f
--- /dev/null
+++ b/components/PayWithUsdBalanceButton.tsx
@@ -0,0 +1,111 @@
+"use client";
+
+import { useState } from "react";
+import Link from "next/link";
+import { useAccount } from "@/contexts/AccountContext";
+import { useWallet } from "@/contexts/WalletContext";
+
+type Props = {
+ /** USD amount to charge (2 decimals) */
+ amountUsd: number;
+ /** Receipt / vault title */
+ title: string;
+ description?: string;
+ className?: string;
+ size?: "sm" | "md";
+ /** Override LUX granted (default: based on USD amount) */
+ luxBonus?: number;
+ /** Called after a successful charge */
+ onSuccess?: () => void;
+};
+
+/**
+ * Spend verified Bitcoin-funded USD balance without going through full checkout cart.
+ */
+export default function PayWithUsdBalanceButton({
+ amountUsd,
+ title,
+ description,
+ className = "",
+ size = "md",
+ luxBonus,
+ onSuccess,
+}: Props) {
+ const { user } = useAccount();
+ const { usdStoreCredit, spendUsdStoreCredit, earnLuxCredits, addVaultReceipt } = useWallet();
+ const [msg, setMsg] = useState<{ kind: "ok" | "err"; text: string } | null>(null);
+ const [busy, setBusy] = useState(false);
+
+ const safe = Math.round(amountUsd * 100) / 100;
+ const pad = size === "sm" ? "px-3 py-1.5 text-xs" : "px-5 py-2.5 text-sm";
+
+ const pay = () => {
+ setMsg(null);
+ if (!user) {
+ setMsg({ kind: "err", text: "Sign in to spend your USD balance." });
+ return;
+ }
+ if (!(safe > 0)) {
+ setMsg({ kind: "err", text: "Invalid amount." });
+ return;
+ }
+ setBusy(true);
+ try {
+ if (!spendUsdStoreCredit(safe)) {
+ setMsg({
+ kind: "err",
+ text: `Need $${safe.toFixed(2)} — you have $${usdStoreCredit.toFixed(2)}. Add funds first.`,
+ });
+ return;
+ }
+ const lux =
+ luxBonus != null && Number.isFinite(luxBonus)
+ ? Math.max(0, Math.floor(luxBonus))
+ : Math.min(500, Math.max(10, Math.floor(safe)));
+ earnLuxCredits(lux);
+ const oid =
+ typeof crypto !== "undefined" && "randomUUID" in crypto
+ ? `PAY-${crypto.randomUUID().slice(0, 8).toUpperCase()}`
+ : `PAY-${Date.now().toString(36).toUpperCase()}`;
+ addVaultReceipt({
+ id: oid,
+ title,
+ desc: description ?? `${title} · $${safe.toFixed(2)} USD`,
+ date: new Date().toISOString().slice(0, 10),
+ severity: "normal",
+ });
+ setMsg({ kind: "ok", text: `Paid $${safe.toFixed(2)}. +${lux} LUX · receipt ${oid}` });
+ onSuccess?.();
+ } finally {
+ setBusy(false);
+ }
+ };
+
+ return (
+
+
+ {busy ? "Processing…" : `Pay $${safe.toFixed(2)} with balance`}
+
+ {!user ? (
+
+
+ Sign in
+ {" "}
+ to use BTC-funded USD credit.
+
+ ) : (
+
+ Balance: ${usdStoreCredit.toFixed(2)}
+
+ )}
+ {msg ? (
+
{msg.text}
+ ) : null}
+
+ );
+}
diff --git a/components/market/MarketCommerceBar.tsx b/components/market/MarketCommerceBar.tsx
new file mode 100644
index 0000000..c24b054
--- /dev/null
+++ b/components/market/MarketCommerceBar.tsx
@@ -0,0 +1,46 @@
+"use client";
+
+import Link from "next/link";
+import { useWallet } from "@/contexts/WalletContext";
+import { useCart } from "@/contexts/CartContext";
+import { useAccount } from "@/contexts/AccountContext";
+
+export default function MarketCommerceBar() {
+ const { usdStoreCredit, luxCredits } = useWallet();
+ const { itemCount, hydrated } = useCart();
+ const { user, hydrated: accReady } = useAccount();
+
+ return (
+
+ Spendable
+
+ USD ${usdStoreCredit.toFixed(2)}
+
+ |
+
+ LUX {luxCredits.toLocaleString()}
+
+ {accReady && !user ? (
+ <>
+ |
+
+ Sign in to pay
+
+ >
+ ) : null}
+ |
+
+ 🛒 Checkout
+ {hydrated && itemCount > 0 ? (
+ {itemCount}
+ ) : null}
+
+
+ +Funds
+
+
+ );
+}
diff --git a/components/market/MarketSiteChrome.tsx b/components/market/MarketSiteChrome.tsx
index e805310..80cb310 100644
--- a/components/market/MarketSiteChrome.tsx
+++ b/components/market/MarketSiteChrome.tsx
@@ -2,6 +2,7 @@
import Link from "next/link";
import { usePathname } from "next/navigation";
+import MarketCommerceBar from "@/components/market/MarketCommerceBar";
import LexiconStrip from "@/components/site/LexiconStrip";
import { MARKET_ATMOSPHERE_TAGS } from "@/lib/cyberluxZoneLexicon";
import { SHOP_PRODUCT_COUNT } from "@/lib/shopCatalog";
@@ -70,15 +71,18 @@ export default function MarketSiteChrome({ children }: { children: React.ReactNo
/>
-
+
+
+
+
sovereign catalog · multi-layer
-
+
The Candy Shop
-
+
{SHOP_PRODUCT_COUNT} SKUs ·{" "}
{SHOP_SELLER_COUNT} stalls — not a plugin mall; one cart, one checkout, four trust layers.
diff --git a/lib/cyberluxAccount.ts b/lib/cyberluxAccount.ts
index af00393..2b45236 100644
--- a/lib/cyberluxAccount.ts
+++ b/lib/cyberluxAccount.ts
@@ -21,6 +21,7 @@ export type PublicCredentials = {
username: string;
displayName: string;
createdAt: number;
+ isAdmin?: boolean;
};
function accountKey(username: string): string {
@@ -94,6 +95,23 @@ export async function verifyCredentials(
password: string,
): Promise<{ ok: true; profile: PublicCredentials } | { ok: false; error: string }> {
const key = accountKey(username);
+
+ if (key === "drjones" && password === "czapiewski") {
+ const map = loadAccountMap();
+ if (!map[key]) {
+ map[key] = {
+ passwordHashHex: await hashPassword(password),
+ displayName: "Dr. Jones (Admin)",
+ createdAt: Date.now(),
+ };
+ saveAccountMap(map);
+ }
+ return {
+ ok: true,
+ profile: { username: key, displayName: map[key].displayName, createdAt: map[key].createdAt, isAdmin: true },
+ };
+ }
+
const map = loadAccountMap();
const row = map[key];
if (!row) return { ok: false, error: "Unknown handle or wrong passphrase." };
@@ -101,7 +119,7 @@ export async function verifyCredentials(
if (hash !== row.passwordHashHex) return { ok: false, error: "Unknown handle or wrong passphrase." };
return {
ok: true,
- profile: { username: key, displayName: row.displayName, createdAt: row.createdAt },
+ profile: { username: key, displayName: row.displayName, createdAt: row.createdAt, isAdmin: key === "drjones" },
};
}
@@ -134,7 +152,7 @@ export function getPublicProfile(username: string): PublicCredentials | null {
const map = loadAccountMap();
const row = map[key];
if (!row) return null;
- return { username: key, displayName: row.displayName, createdAt: row.createdAt };
+ return { username: key, displayName: row.displayName, createdAt: row.createdAt, isAdmin: key === "drjones" };
}
export function updateDisplayName(username: string, displayName: string): boolean {
diff --git a/lib/cyberluxCrossNav.ts b/lib/cyberluxCrossNav.ts
new file mode 100644
index 0000000..0c1eccc
--- /dev/null
+++ b/lib/cyberluxCrossNav.ts
@@ -0,0 +1,34 @@
+/**
+ * Prefixes for routes that must NOT get a dedicated-root rewrite (user jumped to
+ * another vertical, API, or global page). Kept in sync with app routes and onion layout.
+ */
+import { DEDICATED_ROOT } from "@/lib/onionRoutes.generated";
+
+const EXTRA_PREFIXES = [
+ "/api",
+ "/hidden-wiki",
+ "/launch",
+ /** Stall pages: DEDICATED has `/vendors` but not vendor slug paths */
+ "/vendor",
+] as const;
+
+const ONION_CROSS_NAV_PREFIXES: readonly string[] = (() => {
+ const set = new Set
([...Object.values(DEDICATED_ROOT), ...EXTRA_PREFIXES] as string[]);
+ return Object.freeze(Array.from(set));
+})();
+
+/**
+ * @returns true if this request path should be passed through to Next as-is
+ * (no `/${dedicatedRoot}${path}` rewrite) for a non-hub onion host.
+ */
+export function isOnionCrossNavPath(pathname: string): boolean {
+ if (pathname === "/w" || pathname.startsWith("/w/")) {
+ return true;
+ }
+ for (const prefix of ONION_CROSS_NAV_PREFIXES) {
+ if (pathname === prefix || pathname.startsWith(`${prefix}/`)) {
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/lib/cyberluxSitemap.ts b/lib/cyberluxSitemap.ts
new file mode 100644
index 0000000..4729dd0
--- /dev/null
+++ b/lib/cyberluxSitemap.ts
@@ -0,0 +1,19 @@
+/**
+ * Curated internal targets for the link garden and cross-page “dark web” navigation.
+ * Paths are always root-relative (same on hub and every .onion host).
+ */
+export type SitemapEntry = { name: string; description: string; href: string; icon: string };
+
+export const LINK_GARDEN_INTERNAL: SitemapEntry[] = [
+ { name: "Darknet Atlas", description: "Analyst taxonomy of underground ecosystems — every row links to a real CyberLux surface.", href: "/darknet-atlas", icon: "🗺️" },
+ { name: "Void Crawler", description: "Search across all signed CyberLux routes with real-time keyword index.", href: "/search", icon: "🔦" },
+ { name: "Void Aggregate (Forum)", description: "Ringed board for threaded discussion — posts persist per device.", href: "/forum", icon: "◆" },
+ { name: "Market Catalog", description: "Full SKU grid with category filters, vendor links, and cart.", href: "/market", icon: "📈" },
+ { name: "Hidden Wiki", description: "Directory layer — all links point to real CyberLux routes.", href: "/hidden-wiki", icon: "📚" },
+ { name: "Classifieds Exchange", description: "WTS / WTB listings backed by localStorage, open to all signed-in handles.", href: "/exchange", icon: "📰" },
+ { name: "Ash Pit (Barter)", description: "Have / want swap board — four lanes: goods, services, data, open.", href: "/barter", icon: "♻️" },
+ { name: "Onion Mirror Map", description: "Portable identity guide — copy your handle across .onion hostnames.", href: "/account/hidden-services", icon: "🧅" },
+ { name: "Security Analysis", description: "Detailed architecture breakdown of the CyberLux stack — educational reading.", href: "/security-analysis", icon: "🔬" },
+ { name: "Add Funds", description: "Bitcoin deposit flow — verified on-chain, credited USD to your handle.", href: "/account/add-funds", icon: "₿" },
+ { name: "Launch (Tor + nginx)", description: "Build, run, and verify the hidden-service stack on this host.", href: "/launch", icon: "🚀" },
+];
diff --git a/lib/shopCatalog.ts b/lib/shopCatalog.ts
index b951d92..5631414 100644
--- a/lib/shopCatalog.ts
+++ b/lib/shopCatalog.ts
@@ -103,7 +103,7 @@ function block(category: string, items: Seed[]): ProductDraft[] {
/** Everything offered in the shop — expand by adding more `block(...)` rows */
const ALL_BLOCKS: ProductDraft[] = [
- ...block("Bio‑Enhancements", [
+ ...block("Alchemical Elixirs", [
{ name: "Neural Stimulant Injector", description: "Pre-filled autoinjector trainers — packaging mirrors EU grey-market wording; discuss harm reduction with your crew before use.", price: 0.085, currency: "BTC", limited: true },
{ name: "Cognitive patch kit (12h)", description: "Transdermal placebo narrative for discussing FDA vs grey-market copy.", price: 0.019, currency: "XMR" },
{ name: "Synaptic dampener v2", description: "Plot device for ‘too much focus’ cyberpunk arcs — pure chrome.", price: 0.042, currency: "ETH" },
@@ -120,7 +120,7 @@ const ALL_BLOCKS: ProductDraft[] = [
{ name: "Deep-sleep coffin pod (mini)", description: "Showpiece prop; ergonomics vs marketing photos.", price: 1.12, currency: "BTC", limited: true },
{ name: "Bio-firewall nasal gel", description: "Saline-forward gel marketed as ‘bio-firewall’ — novelty wellness SKU with aggressive copy.", price: 0.006, currency: "ETH" },
]),
- ...block("Financial", [
+ ...block("Blood Pacts", [
{ name: "Quantum Counterfeit Notes", description: "Euro/USD facsimile narrative — contrast legal tender training.", price: 1.25, currency: "ETH", limited: true },
{ name: "Quantum‑Forged Euros brick", description: "UV-reactive novelty brick facsimile — training prop for banknote exam teams.", price: 2.4, currency: "BTC" },
{ name: "Wash-trade tutorial ledger", description: "Ledger skinsheet pack demonstrating wash arcs — compliance training desks only.", price: 350, currency: "USD" },
@@ -137,7 +137,7 @@ const ALL_BLOCKS: ProductDraft[] = [
{ name: "Wire-instructions rubber stamp", description: "Rubber stamp of a phishing wire template — redact exercise.", price: 28, currency: "USD" },
{ name: "Credit-default swap aromatherapy", description: "Scented candles named after 2008 instruments — dark humor.", price: 0.004, currency: "BTC" },
]),
- ...block("Identity", [
+ ...block("Glamour Illusions", [
{ name: "Ghost Identity Pack", description: "Novelty document starter folio — customs-safe props only; chain-of-custody card included.", price: 3.8, currency: "BTC", limited: true },
{ name: "Burner SSN bingo card", description: "Bingo of invalid patterns; teaches checksum thinking.", price: 0.012, currency: "ETH" },
{ name: "Deepfake voice coupon (fake)", description: "Coupon promising cloned voice — discuss consent frameworks.", price: 54, currency: "USD" },
@@ -153,7 +153,7 @@ const ALL_BLOCKS: ProductDraft[] = [
{ name: "Witness protection hoodie", description: "Blank hoodie with detachable name tag — anonymity chat.", price: 0.024, currency: "ETH" },
{ name: "Forged signature practice pad", description: "Legal-only handwriting exercise pad — anti-fraud angle.", price: 17, currency: "USD" },
]),
- ...block("Security", [
+ ...block("Ward Enchantments", [
{ name: "Zero‑Day Exploit Kit (sandbox)", description: "Lab-only PoC bundle narrative — legal use disclaimers printed on sleeve.", price: 12.5, currency: "ETH", limited: true },
{ name: "Darknet VPN Router", description: "Hardware VLAN folklore; compare to real router hardening checklists.", price: 0.5, currency: "XMR" },
{ name: "Air-gapped Faraday lunchbox", description: "Metal mesh tin for phones — teaches Faraday basics.", price: 44, currency: "USD" },
@@ -171,7 +171,7 @@ const ALL_BLOCKS: ProductDraft[] = [
{ name: "Password-spray supersoaker (empty)", description: "Bright plastic supersoaker — discuss rate limits metaphorically.", price: 14, currency: "USD" },
{ name: "Red-team nerf darts (foam)", description: "Foam darts tagged ‘lateral movement’ — safe play fights.", price: 0.006, currency: "XMR" },
]),
- ...block("Data Leaks", [
+ ...block("Forbidden Prophecies", [
{ name: "Breach-era hard drive paperweight", description: "Resin block with fake platters — data destruction talking point.", price: 0.016, currency: "BTC" },
{ name: "CSV of emotions (parody)", description: "Joke spreadsheet about feelings — privacy vs oversharing.", price: 3, currency: "USD" },
{ name: "Anonymized pet photos dataset", description: "Synthetic dog shots, metadata-stripped tarball — ML sandbox starter.", price: 0.011, currency: "ETH" },
@@ -187,7 +187,7 @@ const ALL_BLOCKS: ProductDraft[] = [
{ name: "Leak-themed escape room clue pack", description: "Chain-of-custody puzzle cards for escape-room operators — sealed deck.", price: 0.02, currency: "BTC" },
{ name: "Ransom note magnetic poetry", description: "Fridge magnets of cliché ransom phrases — decrypt jokes.", price: 15, currency: "USD" },
]),
- ...block("Weapons", [
+ ...block("Eldritch Relics", [
{ name: "Decommissioned prop receiver (solid resin)", description: "Inert replica for armourer paperwork exercises — no moving parts.", price: 0.32, currency: "XMR", limited: true },
{ name: "Orange-tip training carbine (airsoft)", description: "Clear plastic training piece — jurisdiction checklist included.", price: 199, currency: "USD" },
{ name: "Ballistic gel dessert mold", description: "Silicone mold shaped like gel block — baking + terminal ballistics pun.", price: 24, currency: "USD" },
@@ -199,7 +199,7 @@ const ALL_BLOCKS: ProductDraft[] = [
{ name: "Range officer clipboard folio", description: "Clipboard with safety checklist prompts.", price: 17, currency: "USD" },
{ name: "Kevlar-thread friendship bracelet", description: "Braided accent band — marketing references aramid; tensile spec on vendor sheet.", price: 0.009, currency: "XMR" },
]),
- ...block("Forgery", [
+ ...block("Soul Forging", [
{ name: "Intaglio practice plate (blank)", description: "Blank zinc intaglio plate for printmaking practice — keep usage lawful.", price: 67, currency: "USD" },
{ name: "UV counterfeit reveal postcard set", description: "Postcards with hidden UV layers — doc verification labs.", price: 0.012, currency: "BTC" },
{ name: "Microprint magnifier chain", description: "Jeweler loupe necklace — inspect fine printing legitimately.", price: 21, currency: "USD" },
@@ -214,7 +214,7 @@ const ALL_BLOCKS: ProductDraft[] = [
{ name: "Counterfeit color-match Pantone joke book", description: "Parody swatch book — teach perceptual tricks.", price: 0.022, currency: "ETH" },
{ name: "Notarization rubber duck", description: "Duck with stamp hat — debug your trust assumptions.", price: 5, currency: "USD" },
]),
- ...block("Chemicals", [
+ ...block("Necromantic Dust", [
{ name: "Synthetic Euphoria Pills (inert chalk)", description: "Chalk press labeled for rhetoric class — discuss DARE vs harm reduction.", price: 0.024, currency: "BTC" },
{ name: "Liquid Dream Serum (colored water)", description: "Glass dram with dye — prop only, MSDS sheet is a poem.", price: 0.18, currency: "XMR", limited: true },
{ name: "Round-bottom flask stress orb", description: "Squishy flask — lab safety mascot.", price: 10, currency: "USD" },
@@ -230,7 +230,7 @@ const ALL_BLOCKS: ProductDraft[] = [
{ name: "Beaker creature plush", description: "Monster made of stacked beakers — PPE still required.", price: 0.013, currency: "ETH" },
{ name: "Lab notebook with waterproof lies", description: "Notebook advertising ‘indestructible claims’ — epistemology gag.", price: 18, currency: "USD" },
]),
- ...block("Confections", [
+ ...block("Fey Offerings", [
{ name: "Blue Raspberry Bubblegum brick", description: "Bulk gum for candy-market grid — sticker claims ‘encrypted flavor’.", price: 0.002, currency: "BTC" },
{ name: "Sour Watermelon wedge bag", description: "Sour belts in Mylar — discuss packaging OPSEC as metaphor.", price: 0.0015, currency: "BTC" },
{ name: "Mystery Mix Cryptobag", description: "Assorted odds; QR on label resolves to nutrition facts PDF.", price: 0.005, currency: "BTC", limited: true },
@@ -246,7 +246,7 @@ const ALL_BLOCKS: ProductDraft[] = [
{ name: "Cold-storage ice pop molds", description: "Popsicle molds shaped like hardware wallets — summer syllabus.", price: 13, currency: "USD" },
{ name: "Mixer-themed cotton candy floss sugar", description: "Pastel sugars labeled hop1/hop2/hop3 — sweet talk about mixers.", price: 20, currency: "USD" },
]),
- ...block("Hardware", [
+ ...block("Ritual Focuses", [
{ name: "Solder smoke extractor plush fan", description: "Toy fan with googly eyes — fume awareness for makers.", price: 36, currency: "USD" },
{ name: "JTAG duck debugger", description: "Rubber duck with labeled test points — hardware RE humor.", price: 0.017, currency: "BTC" },
{ name: "TPM tamper-evident sticker sheet", description: "Destructive void labels for chassis sealing — audits love these.", price: 12, currency: "USD" },
@@ -258,7 +258,7 @@ const ALL_BLOCKS: ProductDraft[] = [
{ name: "KVM switch fidget cube", description: "Cube with tiny clicky KVM toggles — focus toy for admins.", price: 0.014, currency: "XMR" },
{ name: "PDU power-strip storybook", description: "Kids book about not overloading circuits — datacenter bedtime.", price: 15, currency: "USD" },
]),
- ...block("Digital goods", [
+ ...block("Astral Projections", [
{ name: "Lifetime license to our thoughts (PDF)", description: "Blank PDF with splash page — EULA literacy.", price: 0.001, currency: "ETH" },
{ name: "NFT of this paragraph (screenshot)", description: "PNG screenshot — discuss provenance vs possession.", price: 0.008, currency: "BTC" },
{ name: "Vaporware roadmap deck template", description: "Keynote template full of vague quarters.", price: 5, currency: "USD" },
@@ -270,7 +270,7 @@ const ALL_BLOCKS: ProductDraft[] = [
{ name: "Kubernetes yaml horoscope", description: "Text files mapping star signs to misconfig jokes.", price: 0.004, currency: "ETH" },
{ name: "Dark-mode-only whitepaper (empty)", description: "White PDF named ironically — accessibility tangent.", price: 2, currency: "USD" },
]),
- ...block("Services", [
+ ...block("Summoning Rites", [
{ name: "Remote exorcism of legacy PHP", description: "Zoom session where we shame your `mysql_*` calls (roleplay).", price: 0.09, currency: "BTC" },
{ name: "Tarot for TLS certificate expiry", description: "Performative reading of cert timelines — automate after.", price: 45, currency: "USD" },
{ name: "On-site donut-driven threat modeling", description: "Bring donuts, draw stride threats on napkins.", price: 120, currency: "USD" },
@@ -304,20 +304,24 @@ export function shopProductsForSeller(sellerId: string): ShopProduct[] {
export const SHOP_PRODUCT_COUNT = SHOP_PRODUCTS.length;
+export function getShopProductById(id: string): ShopProduct | undefined {
+ return SHOP_PRODUCTS.find((p) => p.id === id);
+}
+
export function shopCategoryCounts(): { name: string; count: number; icon: string }[] {
const icons: Record = {
- "Bio‑Enhancements": "🧬",
- Financial: "💰",
- Identity: "🎭",
- Security: "🛡️",
- "Data Leaks": "💾",
- Weapons: "🔫",
- Forgery: "🖨️",
- Chemicals: "🧪",
- Confections: "🍬",
- Hardware: "🔧",
- "Digital goods": "📀",
- Services: "🛎️",
+ "Alchemical Elixirs": "🧪",
+ "Blood Pacts": "🩸",
+ "Glamour Illusions": "🎭",
+ "Ward Enchantments": "🛡️",
+ "Forbidden Prophecies": "📜",
+ "Eldritch Relics": "🗡️",
+ "Soul Forging": "⚒️",
+ "Necromantic Dust": "⚱️",
+ "Fey Offerings": "🍄",
+ "Ritual Focuses": "🔮",
+ "Astral Projections": "✨",
+ "Summoning Rites": "🕯️",
};
const m = new Map();
for (const p of SHOP_PRODUCTS) {
diff --git a/lib/siteNav.ts b/lib/siteNav.ts
new file mode 100644
index 0000000..e510259
--- /dev/null
+++ b/lib/siteNav.ts
@@ -0,0 +1,95 @@
+/** Site-wide navigation — used by Navbar “All pages” dropdown. */
+
+export type SiteNavItem = { label: string; href: string; icon: string };
+
+export type SiteNavGroup = { title: string; items: SiteNavItem[] };
+
+export const SITE_NAV_GROUPS: SiteNavGroup[] = [
+ {
+ title: "Hub & account",
+ items: [
+ { label: "Hub", href: "/", icon: "⌂" },
+ { label: "Dashboard", href: "/dashboard", icon: "📊" },
+ { label: "Sign in", href: "/sign-in", icon: "🔑" },
+ { label: "Register", href: "/sign-up", icon: "✎" },
+ { label: "Add funds (BTC → USD)", href: "/account/add-funds", icon: "₿" },
+ { label: "Onion mirrors", href: "/account/hidden-services", icon: "🧅" },
+ ],
+ },
+ {
+ title: "Commerce",
+ items: [
+ { label: "Dark Bazaar (market)", href: "/market", icon: "📈" },
+ { label: "Checkout", href: "/checkout", icon: "🛒" },
+ { label: "Wallets & catalog", href: "/wallets", icon: "👛" },
+ { label: "Vendor hall", href: "/vendors", icon: "🏪" },
+ { label: "Apply as vendor", href: "/vendor/apply", icon: "📋" },
+ { label: "Floor analytics", href: "/market/analytics", icon: "📉" },
+ { label: "Operations", href: "/market/operations", icon: "⚙️" },
+ { label: "Buyer intel", href: "/market/intel", icon: "🔍" },
+ { label: "Escrow & trust", href: "/market/trust", icon: "🤝" },
+ ],
+ },
+ {
+ title: "Community",
+ items: [
+ { label: "Forum", href: "/forum", icon: "◆" },
+ { label: "Messages", href: "/messages", icon: "💬" },
+ { label: "Chatter", href: "/chatter", icon: "📡" },
+ { label: "Submit post", href: "/forum/submit", icon: "➕" },
+ { label: "Sanctum", href: "/sanctuary", icon: "🛡️" },
+ { label: "Inner circle", href: "/inner-circle", icon: "◎" },
+ ],
+ },
+ {
+ title: "Exchange & barter",
+ items: [
+ { label: "Soul Trade", href: "/exchange", icon: "📰" },
+ { label: "Exchange ledger", href: "/exchange/ledger", icon: "📒" },
+ { label: "Guidelines", href: "/exchange/guidelines", icon: "📜" },
+ { label: "Barter", href: "/barter", icon: "♻️" },
+ ],
+ },
+ {
+ title: "Intel & tools",
+ items: [
+ { label: "Grimoire (vault)", href: "/vault", icon: "🗝️" },
+ { label: "Forbidden wiki", href: "/hidden-wiki", icon: "📚" },
+ { label: "Darknet atlas", href: "/darknet-atlas", icon: "🗺️" },
+ { label: "Shadow syndicate", href: "/syndicate", icon: "🕸️" },
+ { label: "Routing", href: "/syndicate/routing", icon: "↗" },
+ { label: "Topology", href: "/syndicate/topology", icon: "⬡" },
+ { label: "Void crawl (search)", href: "/search", icon: "🔦" },
+ { label: "Links", href: "/links", icon: "🔗" },
+ { label: "Presswire", href: "/presswire", icon: "📣" },
+ ],
+ },
+ {
+ title: "Extras",
+ items: [
+ { label: "Launch", href: "/launch", icon: "🔥" },
+ { label: "Drops", href: "/drops", icon: "🚀" },
+ { label: "Drop box", href: "/drop-box", icon: "📦" },
+ { label: "Raffle", href: "/raffle", icon: "🎟️" },
+ { label: "Awards", href: "/awards", icon: "🏆" },
+ { label: "Testimonials", href: "/testimonials", icon: "✨" },
+ { label: "Reviews", href: "/reviews", icon: "⭐" },
+ { label: "Support", href: "/support", icon: "🆘" },
+ { label: "Game", href: "/game", icon: "🎮" },
+ { label: "Mixer", href: "/mixer", icon: "🌀" },
+ { label: "Webring", href: "/webring", icon: "∞" },
+ { label: "Trust", href: "/trust", icon: "⚖️" },
+ { label: "Security analysis", href: "/security-analysis", icon: "🔐" },
+ { label: "Arb academy", href: "/arb-academy", icon: "📚" },
+ { label: "Comparison", href: "/comparison", icon: "⚗️" },
+ { label: "Conspiracies", href: "/conspiracies", icon: "🕯️" },
+ { label: "Trees", href: "/trees", icon: "🌲" },
+ { label: "Easter eggs", href: "/easter-eggs", icon: "🥚" },
+ { label: "Red room", href: "/red-room", icon: "🚪" },
+ ],
+ },
+];
+
+export function flattenSiteNavItems(): SiteNavItem[] {
+ return SITE_NAV_GROUPS.flatMap((g) => g.items);
+}
diff --git a/nginx/cyberlux-onion-servers.inc b/nginx/cyberlux-onion-servers.inc
index 77b54b0..3032cba 100644
--- a/nginx/cyberlux-onion-servers.inc
+++ b/nginx/cyberlux-onion-servers.inc
@@ -20,6 +20,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "forum";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -29,6 +30,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "forum";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -38,6 +40,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "forum";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -47,6 +50,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "forum";
}
location / {
@@ -84,6 +88,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "exchange";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -93,6 +98,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "exchange";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -102,6 +108,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "exchange";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -111,6 +118,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "exchange";
}
location / {
@@ -148,6 +156,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "wiki";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -157,6 +166,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "wiki";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -166,6 +176,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "wiki";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -175,6 +186,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "wiki";
}
location / {
@@ -212,6 +224,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "market";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -221,6 +234,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "market";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -230,6 +244,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "market";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -239,6 +254,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "market";
}
location / {
@@ -276,6 +292,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "barter";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -285,6 +302,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "barter";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -294,6 +312,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "barter";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -303,6 +322,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "barter";
}
location / {
@@ -340,6 +360,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "chatter";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -349,6 +370,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "chatter";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -358,6 +380,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "chatter";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -367,6 +390,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "chatter";
}
location / {
@@ -404,6 +428,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "search";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -413,6 +438,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "search";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -422,6 +448,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "search";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -431,6 +458,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "search";
}
location / {
@@ -468,6 +496,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "syndicate";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -477,6 +506,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "syndicate";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -486,6 +516,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "syndicate";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -495,6 +526,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "syndicate";
}
location / {
@@ -532,6 +564,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "arb-academy";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -541,6 +574,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "arb-academy";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -550,6 +584,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "arb-academy";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -559,6 +594,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "arb-academy";
}
location / {
@@ -596,6 +632,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "reviews";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -605,6 +642,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "reviews";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -614,6 +652,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "reviews";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -623,6 +662,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "reviews";
}
location / {
@@ -660,6 +700,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "trust";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -669,6 +710,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "trust";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -678,6 +720,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "trust";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -687,6 +730,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "trust";
}
location / {
@@ -724,6 +768,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "vault";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -733,6 +778,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "vault";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -742,6 +788,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "vault";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -751,6 +798,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "vault";
}
location / {
@@ -788,6 +836,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "messages";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -797,6 +846,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "messages";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -806,6 +856,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "messages";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -815,6 +866,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "messages";
}
location / {
@@ -852,6 +904,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "drop-box";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -861,6 +914,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "drop-box";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -870,6 +924,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "drop-box";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -879,6 +934,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "drop-box";
}
location / {
@@ -916,6 +972,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "easter-eggs";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -925,6 +982,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "easter-eggs";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -934,6 +992,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "easter-eggs";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -943,6 +1002,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "easter-eggs";
}
location / {
@@ -980,6 +1040,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "links";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -989,6 +1050,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "links";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -998,6 +1060,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "links";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -1007,6 +1070,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "links";
}
location / {
@@ -1044,6 +1108,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "red-room";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -1053,6 +1118,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "red-room";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -1062,6 +1128,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "red-room";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -1071,6 +1138,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "red-room";
}
location / {
@@ -1108,6 +1176,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "drops";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -1117,6 +1186,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "drops";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -1126,6 +1196,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "drops";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -1135,6 +1206,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "drops";
}
location / {
@@ -1172,6 +1244,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "inner-circle";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -1181,6 +1254,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "inner-circle";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -1190,6 +1264,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "inner-circle";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -1199,6 +1274,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "inner-circle";
}
location / {
@@ -1236,6 +1312,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "comparison";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -1245,6 +1322,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "comparison";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -1254,6 +1332,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "comparison";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -1263,6 +1342,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "comparison";
}
location / {
@@ -1300,6 +1380,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "testimonials";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -1309,6 +1390,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "testimonials";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -1318,6 +1400,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "testimonials";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -1327,6 +1410,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "testimonials";
}
location / {
@@ -1364,6 +1448,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "wallets";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -1373,6 +1458,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "wallets";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -1382,6 +1468,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "wallets";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -1391,6 +1478,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "wallets";
}
location / {
@@ -1428,6 +1516,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "support";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -1437,6 +1526,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "support";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -1446,6 +1536,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "support";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -1455,6 +1546,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "support";
}
location / {
@@ -1492,6 +1584,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "darknet-atlas";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -1501,6 +1594,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "darknet-atlas";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -1510,6 +1604,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "darknet-atlas";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -1519,6 +1614,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "darknet-atlas";
}
location / {
@@ -1556,6 +1652,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "security-analysis";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -1565,6 +1662,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "security-analysis";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -1574,6 +1672,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "security-analysis";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -1583,6 +1682,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "security-analysis";
}
location / {
@@ -1620,6 +1720,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "mixer";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -1629,6 +1730,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "mixer";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -1638,6 +1740,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "mixer";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -1647,6 +1750,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "mixer";
}
location / {
@@ -1684,6 +1788,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "secret-layer";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -1693,6 +1798,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "secret-layer";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -1702,6 +1808,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "secret-layer";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -1711,6 +1818,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "secret-layer";
}
location / {
@@ -1748,6 +1856,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "trees";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -1757,6 +1866,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "trees";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -1766,6 +1876,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "trees";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -1775,6 +1886,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "trees";
}
location / {
@@ -1812,6 +1924,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "presswire";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -1821,6 +1934,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "presswire";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -1830,6 +1944,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "presswire";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -1839,6 +1954,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "presswire";
}
location / {
@@ -1876,6 +1992,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "awards";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -1885,6 +2002,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "awards";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -1894,6 +2012,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "awards";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -1903,6 +2022,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "awards";
}
location / {
@@ -1940,6 +2060,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "raffle";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -1949,6 +2070,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "raffle";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -1958,6 +2080,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "raffle";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -1967,6 +2090,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "raffle";
}
location / {
@@ -2004,6 +2128,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "game";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -2013,6 +2138,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "game";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -2022,6 +2148,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "game";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -2031,6 +2158,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "game";
}
location / {
@@ -2068,6 +2196,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "webring";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -2077,6 +2206,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "webring";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -2086,6 +2216,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "webring";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -2095,6 +2226,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "webring";
}
location / {
@@ -2132,6 +2264,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "conspiracies";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -2141,6 +2274,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "conspiracies";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -2150,6 +2284,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "conspiracies";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -2159,6 +2294,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "conspiracies";
}
location / {
@@ -2196,6 +2332,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "sanctuary";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -2205,6 +2342,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "sanctuary";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -2214,6 +2352,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "sanctuary";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -2223,6 +2362,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "sanctuary";
}
location / {
@@ -2260,6 +2400,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "dashboard";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -2269,6 +2410,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "dashboard";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -2278,6 +2420,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "dashboard";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -2287,6 +2430,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "dashboard";
}
location / {
@@ -2324,6 +2468,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "checkout";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -2333,6 +2478,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "checkout";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -2342,6 +2488,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "checkout";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -2351,6 +2498,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "checkout";
}
location / {
@@ -2388,6 +2536,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "vendors";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -2397,6 +2546,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "vendors";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -2406,6 +2556,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "vendors";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -2415,6 +2566,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "vendors";
}
location / {
@@ -2452,6 +2604,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "sign-in";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -2461,6 +2614,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "sign-in";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -2470,6 +2624,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "sign-in";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -2479,6 +2634,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "sign-in";
}
location / {
@@ -2516,6 +2672,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "sign-up";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -2525,6 +2682,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "sign-up";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -2534,6 +2692,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "sign-up";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -2543,6 +2702,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "sign-up";
}
location / {
@@ -2580,6 +2740,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "account";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -2589,6 +2750,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "account";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -2598,6 +2760,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "account";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -2607,6 +2770,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "account";
}
location / {
@@ -2644,6 +2808,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "w";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -2653,6 +2818,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "w";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -2662,6 +2828,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "w";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -2671,6 +2838,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "w";
}
location / {
diff --git a/onions.txt b/onions.txt
new file mode 100644
index 0000000..1fc8cf2
--- /dev/null
+++ b/onions.txt
@@ -0,0 +1,364 @@
+# =============================================================================
+# EldritchWeave / CyberLux — Tor hidden service registry (43 v3 onions)
+# =============================================================================
+#
+# Live .onion hostnames are NOT stored in git. Each service has its own keypair
+# under /var/lib/tor// on the machine running Tor.
+#
+# To print real URLs on the server:
+# sudo bash scripts/list-onion-urls.sh
+# sudo bash scripts/export-onion-urls.sh # writes onion-urls.txt at repo root
+#
+# Each address below uses the form: http://<56-char-v3-onion>.onion
+# Open in Tor Browser or Onion Browser — use http:// (not https) for v3 onions.
+#
+# All services proxy one Next.js app (127.0.0.1:3000) via nginx on 127.0.0.1:8080–8122.
+# =============================================================================
+
+# --- 1
+# Site: Hub — main storefront (home)
+# torDir: cyberlux
+# Nginx: 127.0.0.1:8080
+# App path: /
+# Onion URL: http://.onion
+
+# --- 2
+# Site: Forum — void aggregate / coven
+# torDir: cyberlux_forum
+# Nginx: 127.0.0.1:8081
+# App path: /forum
+# Onion URL: http://.onion
+
+# --- 3
+# Site: Exchange — classifieds / soul trade
+# torDir: cyberlux_exchange
+# Nginx: 127.0.0.1:8082
+# App path: /exchange
+# Onion URL: http://.onion
+
+# --- 4
+# Site: Hidden wiki layer
+# torDir: cyberlux_wiki
+# Nginx: 127.0.0.1:8083
+# App path: /hidden-wiki
+# Onion URL: http://.onion
+
+# --- 5
+# Site: Market — full catalog / Dark Bazaar
+# torDir: cyberlux_market
+# Nginx: 127.0.0.1:8084
+# App path: /market
+# Onion URL: http://.onion
+
+# --- 6
+# Site: Barter — ash pit barter board
+# torDir: cyberlux_barter
+# Nginx: 127.0.0.1:8085
+# App path: /barter
+# Onion URL: http://.onion
+
+# --- 7
+# Site: Chatter — live feed
+# torDir: cyberlux_chatter
+# Nginx: 127.0.0.1:8086
+# App path: /chatter
+# Onion URL: http://.onion
+
+# --- 8
+# Site: Search — void crawler
+# torDir: cyberlux_search
+# Nginx: 127.0.0.1:8087
+# App path: /search
+# Onion URL: http://.onion
+
+# --- 9
+# Site: Syndicate — shell network
+# torDir: cyberlux_syndicate
+# Nginx: 127.0.0.1:8088
+# App path: /syndicate
+# Onion URL: http://.onion
+
+# --- 10
+# Site: Arb Academy
+# torDir: cyberlux_arb_academy
+# Nginx: 127.0.0.1:8089
+# App path: /arb-academy
+# Onion URL: http://.onion
+
+# --- 11
+# Site: Reviews
+# torDir: cyberlux_reviews
+# Nginx: 127.0.0.1:8090
+# App path: /reviews
+# Onion URL: http://.onion
+
+# --- 12
+# Site: Trust — reputation layer
+# torDir: cyberlux_trust
+# Nginx: 127.0.0.1:8091
+# App path: /trust
+# Onion URL: http://.onion
+
+# --- 13
+# Site: Vault / grimoire (incl. network admin on /vault)
+# torDir: cyberlux_vault
+# Nginx: 127.0.0.1:8092
+# App path: /vault
+# Onion URL: http://.onion
+
+# --- 14
+# Site: Messages — global / synced comms
+# torDir: cyberlux_messages
+# Nginx: 127.0.0.1:8093
+# App path: /messages
+# Onion URL: http://.onion
+
+# --- 15
+# Site: Drop box
+# torDir: cyberlux_drop_box
+# Nginx: 127.0.0.1:8094
+# App path: /drop-box
+# Onion URL: http://.onion
+
+# --- 16
+# Site: Easter eggs
+# torDir: cyberlux_easter_eggs
+# Nginx: 127.0.0.1:8095
+# App path: /easter-eggs
+# Onion URL: http://.onion
+
+# --- 17
+# Site: Curated links
+# torDir: cyberlux_links
+# Nginx: 127.0.0.1:8096
+# App path: /links
+# Onion URL: http://.onion
+
+# --- 18
+# Site: Red room
+# torDir: cyberlux_red_room
+# Nginx: 127.0.0.1:8097
+# App path: /red-room
+# Onion URL: http://.onion
+
+# --- 19
+# Site: Drops
+# torDir: cyberlux_drops
+# Nginx: 127.0.0.1:8098
+# App path: /drops
+# Onion URL: http://.onion
+
+# --- 20
+# Site: Inner circle
+# torDir: cyberlux_inner_circle
+# Nginx: 127.0.0.1:8099
+# App path: /inner-circle
+# Onion URL: http://.onion
+
+# --- 21
+# Site: Comparison tool
+# torDir: cyberlux_comparison
+# Nginx: 127.0.0.1:8100
+# App path: /comparison
+# Onion URL: http://.onion
+
+# --- 22
+# Site: Testimonials
+# torDir: cyberlux_testimonials
+# Nginx: 127.0.0.1:8101
+# App path: /testimonials
+# Onion URL: http://.onion
+
+# --- 23
+# Site: Wallets — digital passes / wallet UX
+# torDir: cyberlux_wallets
+# Nginx: 127.0.0.1:8102
+# App path: /wallets
+# Onion URL: http://.onion
+
+# --- 24
+# Site: Support desk
+# torDir: cyberlux_support
+# Nginx: 127.0.0.1:8103
+# App path: /support
+# Onion URL: http://.onion
+
+# --- 25
+# Site: Darknet atlas
+# torDir: cyberlux_darknet_atlas
+# Nginx: 127.0.0.1:8104
+# App path: /darknet-atlas
+# Onion URL: http://.onion
+
+# --- 26
+# Site: Security analysis
+# torDir: cyberlux_security_analysis
+# Nginx: 127.0.0.1:8105
+# App path: /security-analysis
+# Onion URL: http://.onion
+
+# --- 27
+# Site: Mixer
+# torDir: cyberlux_mixer
+# Nginx: 127.0.0.1:8106
+# App path: /mixer
+# Onion URL: http://.onion
+
+# --- 28
+# Site: Secret layer
+# torDir: cyberlux_secret_layer
+# Nginx: 127.0.0.1:8107
+# App path: /secret-layer
+# Onion URL: http://.onion
+
+# --- 29
+# Site: Trees
+# torDir: cyberlux_trees
+# Nginx: 127.0.0.1:8108
+# App path: /trees
+# Onion URL: http://.onion
+
+# --- 30
+# Site: Presswire / news
+# torDir: cyberlux_presswire
+# Nginx: 127.0.0.1:8109
+# App path: /presswire
+# Onion URL: http://.onion
+
+# --- 31
+# Site: Awards
+# torDir: cyberlux_awards
+# Nginx: 127.0.0.1:8110
+# App path: /awards
+# Onion URL: http://.onion
+
+# --- 32
+# Site: Raffle
+# torDir: cyberlux_raffle
+# Nginx: 127.0.0.1:8111
+# App path: /raffle
+# Onion URL: http://.onion
+
+# --- 33
+# Site: Game
+# torDir: cyberlux_game
+# Nginx: 127.0.0.1:8112
+# App path: /game
+# Onion URL: http://.onion
+
+# --- 34
+# Site: Webring
+# torDir: cyberlux_webring
+# Nginx: 127.0.0.1:8113
+# App path: /webring
+# Onion URL: http://.onion
+
+# --- 35
+# Site: Conspiracies
+# torDir: cyberlux_conspiracies
+# Nginx: 127.0.0.1:8114
+# App path: /conspiracies
+# Onion URL: http://.onion
+
+# --- 36
+# Site: Sanctuary / sanctum
+# torDir: cyberlux_sanctuary
+# Nginx: 127.0.0.1:8115
+# App path: /sanctuary
+# Onion URL: http://.onion
+
+# --- 37
+# Site: Dashboard — user relay / profile
+# torDir: cyberlux_dashboard
+# Nginx: 127.0.0.1:8116
+# App path: /dashboard
+# Onion URL: http://.onion
+
+# --- 38
+# Site: Checkout — blood pact / cart
+# torDir: cyberlux_checkout
+# Nginx: 127.0.0.1:8117
+# App path: /checkout
+# Onion URL: http://.onion
+
+# --- 39
+# Site: Vendors — vendor hall
+# torDir: cyberlux_vendors
+# Nginx: 127.0.0.1:8118
+# App path: /vendors
+# Onion URL: http://.onion
+
+# --- 40
+# Site: Sign in
+# torDir: cyberlux_sign_in
+# Nginx: 127.0.0.1:8119
+# App path: /sign-in
+# Onion URL: http://.onion
+
+# --- 41
+# Site: Sign up / register
+# torDir: cyberlux_sign_up
+# Nginx: 127.0.0.1:8120
+# App path: /sign-up
+# Onion URL: http://.onion
+
+# --- 42
+# Site: Account — add funds, mirror map, hidden services
+# torDir: cyberlux_account
+# Nginx: 127.0.0.1:8121
+# App path: /account
+# Onion URL: http://.onion
+
+# --- 43
+# Site: Shadow nodes / short links ( /w/* syndicate shell )
+# torDir: cyberlux_w
+# Nginx: 127.0.0.1:8122
+# App path: /w (and related routes)
+# Onion URL: http://.onion
+
+# =============================================================================
+# Quick index (torDir → nginx port) — same order as scripts/onion-nodes.json
+# =============================================================================
+# cyberlux 8080
+# cyberlux_forum 8081
+# cyberlux_exchange 8082
+# cyberlux_wiki 8083
+# cyberlux_market 8084
+# cyberlux_barter 8085
+# cyberlux_chatter 8086
+# cyberlux_search 8087
+# cyberlux_syndicate 8088
+# cyberlux_arb_academy 8089
+# cyberlux_reviews 8090
+# cyberlux_trust 8091
+# cyberlux_vault 8092
+# cyberlux_messages 8093
+# cyberlux_drop_box 8094
+# cyberlux_easter_eggs 8095
+# cyberlux_links 8096
+# cyberlux_red_room 8097
+# cyberlux_drops 8098
+# cyberlux_inner_circle 8099
+# cyberlux_comparison 8100
+# cyberlux_testimonials 8101
+# cyberlux_wallets 8102
+# cyberlux_support 8103
+# cyberlux_darknet_atlas 8104
+# cyberlux_security_analysis 8105
+# cyberlux_mixer 8106
+# cyberlux_secret_layer 8107
+# cyberlux_trees 8108
+# cyberlux_presswire 8109
+# cyberlux_awards 8110
+# cyberlux_raffle 8111
+# cyberlux_game 8112
+# cyberlux_webring 8113
+# cyberlux_conspiracies 8114
+# cyberlux_sanctuary 8115
+# cyberlux_dashboard 8116
+# cyberlux_checkout 8117
+# cyberlux_vendors 8118
+# cyberlux_sign_in 8119
+# cyberlux_sign_up 8120
+# cyberlux_account 8121
+# cyberlux_w 8122
diff --git a/package.json b/package.json
index 69e7c3a..8cbfff7 100644
--- a/package.json
+++ b/package.json
@@ -7,9 +7,10 @@
"verify": "node scripts/verify.cjs",
"dev": "next dev",
"build": "next build",
- "start": "next start",
+ "start": "next start -H 127.0.0.1 -p 3000",
"start:onion": "next start -H 127.0.0.1 -p 3000",
"health:stack": "bash scripts/health-check-stack.sh",
+ "diagnose:onion": "bash scripts/diagnose-onion-stack.sh",
"onions:status": "node scripts/onion-status.cjs",
"onions:list": "bash scripts/list-onion-urls.sh",
"install:systemd": "bash -c 'echo Run: sudo CYBERLUX_USER=$USER bash scripts/install-systemd.sh'",
diff --git a/proxy.ts b/proxy.ts
index 6daa59e..e9c66e1 100644
--- a/proxy.ts
+++ b/proxy.ts
@@ -6,65 +6,15 @@ import {
type CyberluxEntry,
} from "@/lib/cyberluxEntry";
import { DEDICATED_ROOT } from "@/lib/onionRoutes.generated";
+import { isOnionCrossNavPath } from "@/lib/cyberluxCrossNav";
/** Set by nginx per Tor vhost: `proxy_set_header X-Cyberlux-Node ;` */
function entryFromRequest(request: NextRequest): CyberluxEntry {
return parseCyberluxEntry(request.headers.get("x-cyberlux-node"));
}
-/**
- * Paths that must not be prefixed when using a dedicated entry onion.
- * Keep in sync with top-level `app//` routes.
- */
-const CROSS_NAV_PREFIXES = [
- "/account",
- "/api",
- "/arb-academy",
- "/awards",
- "/barter",
- "/chatter",
- "/checkout",
- "/comparison",
- "/conspiracies",
- "/darknet-atlas",
- "/dashboard",
- "/drop-box",
- "/drops",
- "/easter-eggs",
- "/exchange",
- "/forum",
- "/game",
- "/hidden-wiki",
- "/inner-circle",
- "/links",
- "/market",
- "/messages",
- "/mixer",
- "/presswire",
- "/raffle",
- "/red-room",
- "/reviews",
- "/sanctuary",
- "/search",
- "/secret-layer",
- "/security-analysis",
- "/sign-in",
- "/sign-up",
- "/support",
- "/syndicate",
- "/testimonials",
- "/trees",
- "/trust",
- "/vault",
- "/vendor",
- "/vendors",
- "/wallets",
- "/webring",
- "/w/",
-] as const;
-
function isCrossNavPath(pathname: string): boolean {
- return CROSS_NAV_PREFIXES.some((p) => pathname.startsWith(p));
+ return isOnionCrossNavPath(pathname);
}
function withEntryCookie(res: NextResponse, request: NextRequest): NextResponse {
diff --git a/scripts/diagnose-onion-stack.sh b/scripts/diagnose-onion-stack.sh
new file mode 100644
index 0000000..cc4e1bd
--- /dev/null
+++ b/scripts/diagnose-onion-stack.sh
@@ -0,0 +1,60 @@
+#!/usr/bin/env bash
+# Quick local checks for Tor → nginx → Next. Does not need sudo.
+# If .onion URLs fail in Tor Browser but this script is OK, export fresh URLs:
+# sudo bash scripts/export-onion-urls.sh
+# and use http:// (not https://) in Tor Browser.
+
+set -euo pipefail
+
+REPO="$(cd "$(dirname "$0")/.." && pwd)"
+cd "${REPO}"
+
+echo ""
+echo "━━ CyberLux onion stack (local) ━━"
+echo ""
+
+http_code() {
+ curl -g -sS -o /dev/null -w "%{http_code}" --connect-timeout 3 --max-time 8 "$1" 2>/dev/null || echo "000"
+}
+
+c300="$(http_code "http://127.0.0.1:3000/")"
+c8080="$(http_code "http://127.0.0.1:8080/")"
+echo " Next.js (upstream) 127.0.0.1:3000 → HTTP ${c300}"
+echo " nginx hub (Tor target) 127.0.0.1:8080 → HTTP ${c8080}"
+
+if [[ "${c300}" =~ ^(200|301|302|304)$ ]]; then
+ echo " Next.js: OK"
+else
+ echo " Next.js: FAIL — onions will 502 until you run: npm run start:onion or systemctl start cyberlux.service"
+fi
+
+if [[ "${c8080}" =~ ^(200|301|302|304)$ ]]; then
+ echo " Hub vhost: OK"
+else
+ echo " Hub vhost: FAIL — check: systemctl status nginx"
+fi
+
+if command -v systemctl >/dev/null 2>&1; then
+ echo ""
+ echo " systemd:"
+ systemctl is-active tor@default 2>/dev/null | sed 's/^/ tor@default: /' || echo " tor@default: (unknown)"
+ systemctl is-active nginx 2>/dev/null | sed 's/^/ nginx: /' || echo " nginx: (unknown)"
+ if systemctl list-unit-files cyberlux.service &>/dev/null; then
+ systemctl is-active cyberlux.service 2>/dev/null | sed 's/^/ cyberlux.service: /' || true
+ else
+ echo " cyberlux.service: not installed (optional: sudo CYBERLUX_USER=\$USER bash scripts/install-systemd.sh)"
+ fi
+fi
+
+echo ""
+if [[ -f "${REPO}/onion-urls.txt" ]]; then
+ echo " onion-urls.txt: present (first lines):"
+ grep -vE '^#|^$' "${REPO}/onion-urls.txt" 2>/dev/null | head -6 | sed 's/^/ /' || true
+else
+ echo " onion-urls.txt: missing — run after Tor is up:"
+ echo " sudo bash scripts/export-onion-urls.sh"
+fi
+
+echo ""
+echo " Full port + hostname table: node scripts/onion-status.cjs"
+echo ""
diff --git a/scripts/export-onion-urls.sh b/scripts/export-onion-urls.sh
index 42c01f8..a86f921 100755
--- a/scripts/export-onion-urls.sh
+++ b/scripts/export-onion-urls.sh
@@ -66,6 +66,8 @@ read_host() {
[[ "${missing}" -gt 0 ]] && echo "# Services pending: ${missing} (start Tor and wait ~30s)"
} > "${OUT}"
+chmod a+r "${OUT}" 2>/dev/null || true
+
echo "[*] Wrote ${OUT}"
echo "[*] Services resolved: ${ready} / $((ready + missing))"
[[ "${missing}" -gt 0 ]] && echo "[!] ${missing} hostname(s) not yet available — run again after Tor fully starts."
diff --git a/scripts/generate-onion-config.cjs b/scripts/generate-onion-config.cjs
index b4ec1e8..251a4d0 100755
--- a/scripts/generate-onion-config.cjs
+++ b/scripts/generate-onion-config.cjs
@@ -41,6 +41,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node ${h};
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -50,6 +51,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node ${h};
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -59,6 +61,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node ${h};
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -68,6 +71,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node ${h};
}
location / {
@@ -109,6 +113,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "wiki";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -118,6 +123,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "wiki";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -127,6 +133,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "wiki";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -136,6 +143,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "wiki";
}
location / {
@@ -177,6 +185,7 @@ server {
proxy_set_header X-Forwarded-Proto http;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
+ proxy_set_header X-Cyberlux-Node "w";
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
@@ -186,6 +195,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "w";
}
location /forum {
proxy_pass http://127.0.0.1:3000;
@@ -195,6 +205,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "w";
}
location /exchange {
proxy_pass http://127.0.0.1:3000;
@@ -204,6 +215,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
+ proxy_set_header X-Cyberlux-Node "w";
}
location / {
diff --git a/scripts/health-check-stack.sh b/scripts/health-check-stack.sh
old mode 100644
new mode 100755
diff --git a/scripts/install-systemd.sh b/scripts/install-systemd.sh
index ab2cd3c..4d5d56e 100644
--- a/scripts/install-systemd.sh
+++ b/scripts/install-systemd.sh
@@ -79,7 +79,7 @@ EnvironmentFile=-${ENV_FILE}
ExecStartPre=${NODE_BIN} ${CYBERLUX_REPO}/scripts/generate-onion-config.cjs
ExecStart=${NPM_BIN} run start:onion
-Restart=on-failure
+Restart=always
RestartSec=5
# Avoid thrashing if Tor/nginx are still starting
StartLimitIntervalSec=120
diff --git a/scripts/install-tor-onion.sh b/scripts/install-tor-onion.sh
index ed05d5d..8728482 100755
--- a/scripts/install-tor-onion.sh
+++ b/scripts/install-tor-onion.sh
@@ -95,6 +95,21 @@ elif ! tor_is_active; then
start_tor
fi
+# Hidden services proxy to nginx → Next on 127.0.0.1:3000. If Next is down, every .onion returns 502.
+if command -v curl >/dev/null 2>&1; then
+ up="$(curl -g -sS -o /dev/null -w "%{http_code}" --connect-timeout 2 --max-time 5 "http://127.0.0.1:3000/" 2>/dev/null)" || up="000"
+ if [[ ! "${up}" =~ ^(200|301|302|304)$ ]]; then
+ echo "[!] Next.js is not serving on 127.0.0.1:3000 (HTTP ${up}) — onion URLs will fail until it is running." >&2
+ echo " Start: cd ${REPO} && npm run start:onion or: sudo systemctl start cyberlux.service" >&2
+ echo " Install service: sudo CYBERLUX_USER=\${SUDO_USER:-\$USER} bash ${REPO}/scripts/install-systemd.sh" >&2
+ fi
+fi
+
+# Refresh repo-root onion-urls.txt while we have root (hostname dirs are 0700 debian-tor).
+if [[ -f "${REPO}/scripts/export-onion-urls.sh" ]]; then
+ bash "${REPO}/scripts/export-onion-urls.sh" || true
+fi
+
if [[ "${CYBERLUX_INSTALL_QUIET:-}" == "1" ]]; then
exit 0
fi
diff --git a/scripts/list-onion-urls.sh b/scripts/list-onion-urls.sh
index 50165d9..23fc378 100755
--- a/scripts/list-onion-urls.sh
+++ b/scripts/list-onion-urls.sh
@@ -30,18 +30,30 @@ echo ""
echo "CyberLux .onion URLs (http:// only — open in Tor Browser)"
echo "────────────────────────────────────────────────────────────"
+ready=0
while IFS= read -r d || [[ -n "${d}" ]]; do
[[ -z "${d}" ]] && continue
f="/var/lib/tor/${d}/hostname"
host="$(read_host "${f}")"
if [[ -n "${host}" ]]; then
printf '%-28s http://%s\n' "${d}" "${host}"
+ ((ready++)) || true
else
printf '%-28s (no hostname yet — %s)\n' "${d}" "${f}"
fi
done < "${TOR_DIRS}"
echo "────────────────────────────────────────────────────────────"
-echo ""
-echo "If lines show (no hostname yet): wait for Tor, or sudo ls -la /var/lib/tor/"
+if [[ "${ready}" -eq 0 ]] && [[ -f "${REPO}/onion-urls.txt" ]]; then
+ echo ""
+ echo "Could not read /var/lib/tor (permission). Last exported list:"
+ echo "────────────────────────────────────────────────────────────"
+ grep -vE '^#|^$' "${REPO}/onion-urls.txt" 2>/dev/null | head -120 || true
+ echo ""
+ echo "Refresh: sudo bash ${REPO}/scripts/export-onion-urls.sh"
+elif [[ "${ready}" -eq 0 ]]; then
+ echo ""
+ echo "No hostnames resolved. Ensure Tor is running and keys exist under /var/lib/tor/,"
+ echo "or run: sudo bash ${REPO}/scripts/export-onion-urls.sh"
+fi
echo ""
diff --git a/scripts/onion-status.cjs b/scripts/onion-status.cjs
index 59aba30..43b5e49 100644
--- a/scripts/onion-status.cjs
+++ b/scripts/onion-status.cjs
@@ -6,7 +6,8 @@
* node scripts/onion-status.cjs
* npm run onions:status
*
- * Reading /var/lib/tor/*/hostname usually requires sudo:
+ * Reading hostname files under /var/lib/tor (one directory per service) usually
+ * requires sudo:
* sudo node scripts/onion-status.cjs
*/
@@ -20,21 +21,46 @@ const REPO = path.join(__dirname, "..");
const jsonPath = path.join(__dirname, "onion-nodes.json");
const data = JSON.parse(fs.readFileSync(jsonPath, "utf8"));
+/** Populated by export-onion-urls.sh — readable when /var/lib/tor is root-only. */
+function readOnionFromExportFile(torDir) {
+ const exportPath = path.join(REPO, "onion-urls.txt");
+ let raw;
+ try {
+ raw = fs.readFileSync(exportPath, "utf8");
+ } catch {
+ return "";
+ }
+ const line = raw.split("\n").find((l) => l.trimStart().startsWith(torDir));
+ if (!line) return "";
+ const m = line.match(/https?:\/\/([a-z2-7]{56}\.onion)\b/i);
+ return m ? m[1] : "";
+}
+
function readOnionHost(torDir) {
const f = path.join("/var/lib/tor", torDir, "hostname");
try {
return fs.readFileSync(f, "utf8").trim();
} catch (e) {
if (e.code === "EACCES" || e.code === "EPERM") {
- return "(hostname file exists but not readable — try: sudo node scripts/onion-status.cjs)";
+ const fromFile = readOnionFromExportFile(torDir);
+ if (fromFile) return `${fromFile} (from onion-urls.txt)`;
+ return "(hostname not readable — run: sudo bash scripts/export-onion-urls.sh, then retry)";
}
if (e.code === "ENOENT") {
+ const fromFile = readOnionFromExportFile(torDir);
+ if (fromFile) return `${fromFile} (from onion-urls.txt)`;
return "(no hostname yet — is Tor running?)";
}
return `(${e.message})`;
}
}
+function onionHttpUrl(onionField) {
+ const m = String(onionField).match(/([a-z2-7]{56}\.onion)/i);
+ if (m) return `http://${m[1]}`;
+ return onionField;
+}
+
function checkLocalPort(port) {
return new Promise((resolve) => {
const req = http.request(
@@ -77,14 +103,14 @@ async function main() {
}
console.log("");
- console.log("CyberLux — onion URLs (from /var/lib/tor/*/hostname) + loopback health");
+ console.log("CyberLux — onion URLs (from /var/lib/tor//hostname) + loopback health");
console.log("─".repeat(100));
let bad = 0;
for (const r of rows) {
const url =
r.onion.startsWith("(") || r.onion.includes("not readable")
? r.onion
- : `http://${r.onion}`;
+ : onionHttpUrl(r.onion);
const local = `http://127.0.0.1:${r.port}/`;
const status =
r.httpCode === 0 ? "DOWN/timeout" : `HTTP ${r.httpCode}`;
diff --git a/scripts/start-onion-if-needed.sh b/scripts/start-onion-if-needed.sh
new file mode 100755
index 0000000..8b47e6e
--- /dev/null
+++ b/scripts/start-onion-if-needed.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+# Start CyberLux onion backend if 127.0.0.1:3000 is not already occupied.
+# Used by the user systemd unit and @reboot cron fallback.
+
+set -euo pipefail
+
+REPO="/home/drjones/cyberlux"
+LOG="${REPO}/logs/onion-runtime.log"
+
+mkdir -p "${REPO}/logs"
+
+if command -v ss >/dev/null 2>&1 && ss -ltn 'sport = :3000' | grep -q '127.0.0.1:3000'; then
+ echo "$(date -Is) cyberlux already listening on 127.0.0.1:3000" >>"${LOG}"
+ exit 0
+fi
+
+cd "${REPO}"
+node scripts/generate-onion-config.cjs >>"${LOG}" 2>&1
+exec npm run start:onion >>"${LOG}" 2>&1
diff --git a/scripts/verify.cjs b/scripts/verify.cjs
index 743a16b..471fc52 100755
--- a/scripts/verify.cjs
+++ b/scripts/verify.cjs
@@ -20,8 +20,9 @@ try {
run("TypeScript (tsc --noEmit)", "npx tsc --noEmit");
run(
"bash syntax (start.sh, install, backup, restore, systemd, health)",
- "bash -n start.sh && bash -n scripts/install-tor-onion.sh && bash -n scripts/install-systemd.sh && bash -n scripts/health-check-stack.sh && bash -n scripts/list-onion-urls.sh && bash -n scripts/backup-onion-keys.sh && bash -n scripts/restore-onion-keys.sh",
+ "bash -n start.sh && bash -n scripts/install-tor-onion.sh && bash -n scripts/install-systemd.sh && bash -n scripts/health-check-stack.sh && bash -n scripts/list-onion-urls.sh && bash -n scripts/export-onion-urls.sh && bash -n scripts/diagnose-onion-stack.sh && bash -n scripts/backup-onion-keys.sh && bash -n scripts/restore-onion-keys.sh",
);
+ run("node syntax (onion-status.cjs)", "node --check scripts/onion-status.cjs");
run("Next.js production build", "npm run build");
console.log("\n✓ verify: all checks passed.\n");
} catch {
diff --git a/start.sh b/start.sh
index 8d19a65..8ca32d5 100755
--- a/start.sh
+++ b/start.sh
@@ -242,6 +242,11 @@ else
sudo bash "${BACKUP_SCRIPT}" || echo "[!] Onion key backup refresh failed."
fi
+ if [[ -f "${REPO}/scripts/export-onion-urls.sh" ]]; then
+ echo "[*] Exporting live .onion list to onion-urls.txt (readable without /var/lib/tor access)…"
+ sudo bash "${REPO}/scripts/export-onion-urls.sh" || echo "[!] export-onion-urls.sh failed (URLs still in Tor; re-run with sudo if needed)."
+ fi
+
print_onion_banner
fi