Update market, account, and onion operations
Capture the current CyberLux UI, commerce, messaging, and Tor ops updates so local main can be pushed to the remote. Made-with: Cursor
This commit is contained in:
60
scripts/diagnose-onion-stack.sh
Normal file
60
scripts/diagnose-onion-stack.sh
Normal file
@@ -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 ""
|
||||
@@ -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."
|
||||
|
||||
@@ -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 / {
|
||||
|
||||
0
scripts/health-check-stack.sh
Normal file → Executable file
0
scripts/health-check-stack.sh
Normal file → Executable file
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ""
|
||||
|
||||
@@ -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/<service>/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}`;
|
||||
|
||||
19
scripts/start-onion-if-needed.sh
Executable file
19
scripts/start-onion-if-needed.sh
Executable file
@@ -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
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user