Remove admin panel: strip admin startup, dependencies, and docs; keep minimal placeholder file

This commit is contained in:
shwzss
2026-09-02 22:29:07 -05:00
parent 8213b3d98c
commit e3b5c38d0a
5 changed files with 22 additions and 70 deletions
-5
View File
@@ -2,7 +2,6 @@
# Port the server listens on (client must connect to this)
PORT=5055
ADMIN_PORT=5056
# Logging: error, warn, info, verbose, debug, silly
LOG_LEVEL=info
@@ -13,7 +12,3 @@ RECNET_VERIFY_URL=
# SQLite DB file
SQLITE_FILE=./helium.db
# Admin basic auth (optional)
ADMIN_USER=admin
ADMIN_PASS=changeme
+1 -5
View File
@@ -7,28 +7,24 @@ What I added in this commit:
- Protocol stub (src/protocol.js) — where Rec Room / Photon packet parsing should be implemented
- Auth helpers (src/auth.js) for Steam/RecNet token verification (placeholders that call configured endpoints)
- SQLite persistence (src/storage.js)
- Admin console (src/admin.js) with basic auth and endpoints to list connections and broadcast messages
- Logger and test client
- package.json with dependencies
Environment variables (set in .env):
- PORT (default 5055) — WebSocket server port
- ADMIN_PORT (default 5056) — Admin HTTP server port
- LOG_LEVEL — winston log level (info/debug/...)
- STEAM_WEB_API_KEY — Steam Web API key (if you plan to use Steam verification)
- RECNET_VERIFY_URL — RecNet verification endpoint to POST { token }
- SQLITE_FILE — path for the SQLite DB file (default ./helium.db)
- ADMIN_USER / ADMIN_PASS — optional Basic auth for admin console
How to run:
1. Copy `.env.example` to `.env` and fill in the variables you need.
2. npm install
3. npm start
4. Admin console: http://localhost:5056 (use basic auth if ADMIN_USER/ADMIN_PASS set)
Notes about Photon & Rec Room:
- The client uses Photon; this skeleton provides a WebSocket entry point you can use for reverse engineering and testing. Photon traffic is binary and has its own framing — you'll need to implement Photon protocol handling inside src/protocol.js (or add a UDP/TCP transport if Photon expects that).
- You said you can replace Photon keys and localhost yourself — good. Put the Photon server host/port to point to this process and replace any required AppId/AppVersion in the client.
- You said you can replace Photon keys & localhost yourself — point the client at this process and replace any required AppId/AppVersion in the client.
Next steps I can take after you confirm:
- Implement Photon framing and basic handshake to accept a 2023 Rec Room client (requires packet captures or protocol docs).
+2 -5
View File
@@ -5,16 +5,13 @@
"main": "src/index.js",
"scripts": {
"start": "node src/index.js",
"dev": "nodemon src/index.js",
"admin": "node src/admin.js"
"dev": "nodemon src/index.js"
},
"dependencies": {
"ws": "^8.13.0",
"dotenv": "^16.0.0",
"winston": "^3.8.0",
"express": "^4.18.2",
"axios": "^1.4.0",
"sqlite3": "^5.1.6",
"basic-auth": "^2.0.1"
"sqlite3": "^5.1.6"
}
}
+4 -49
View File
@@ -1,50 +1,5 @@
const express = require('express');
const basicAuth = require('basic-auth');
const logger = require('./logger');
// The admin console was intentionally removed from the project per repository owner request.
// If you need to restore it later, re-add an admin HTTP server (e.g., using express) and
// provide ADMIN_USER / ADMIN_PASS environment variables for basic auth.
let serverInstance;
function ensureAuth(req, res, next) {
if (!process.env.ADMIN_USER || !process.env.ADMIN_PASS) return next();
const user = basicAuth(req);
if (!user || user.name !== process.env.ADMIN_USER || user.pass !== process.env.ADMIN_PASS) {
res.set('WWW-Authenticate', 'Basic realm="HeliumRecAdmin"');
return res.status(401).send('Authentication required');
}
return next();
}
function start({ port = 5056, getConnections }) {
const app = express();
app.use(express.json());
app.get('/health', (req, res) => res.json({ ok: true }));
app.use(ensureAuth);
app.get('/connections', (req, res) => {
const conns = [];
const map = getConnections();
map.forEach((v, k) => {
conns.push({ id: k, user: v.user, connectedAt: v.connectedAt, remote: v.ws?._meta?.remote });
});
res.json(conns);
});
app.post('/broadcast', (req, res) => {
const { message } = req.body || {};
if (!message) return res.status(400).json({ error: 'message required' });
const map = getConnections();
let sent = 0;
map.forEach((v) => {
try { v.ws.send(typeof message === 'string' ? message : JSON.stringify(message)); sent++; } catch (e) { logger.warn('broadcast failed', e.message); }
});
res.json({ sent });
});
serverInstance = app.listen(port, () => logger.info(`Admin console listening on http://0.0.0.0:${port}`));
}
function stop() { if (serverInstance) serverInstance.close(); }
module.exports = { start, stop };
module.exports = {};
+15 -6
View File
@@ -8,16 +8,28 @@ const logger = require('./logger');
const protocol = require('./protocol');
const auth = require('./auth');
const storage = require('./storage');
const admin = require('./admin');
const PORT = process.env.PORT || 5055;
const ADMIN_PORT = process.env.ADMIN_PORT || 5056;
(async () => {
await storage.init();
// Start WebSocket server on its own HTTP server so we can inspect req.url
const server = http.createServer();
const server = http.createServer((req, res) => {
// Provide a minimal informational page for HTTP GETs so browsers don't see "Cannot GET /"
if (req.method === 'GET' && (req.url === '/' || req.url === '/index.html')) {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(`<html><body>
<h1>HeliumRecServer</h1>
<p>This port is a WebSocket endpoint. Connect using a WebSocket client.</p>
<p>Server listens on ws://0.0.0.0:${PORT}</p>
</body></html>`);
return;
}
// leave other requests to return 404
res.writeHead(404); res.end('Not Found');
});
const wss = new WebSocket.Server({ noServer: true });
const connections = new Map(); // key -> { ws, user }
@@ -79,7 +91,4 @@ const ADMIN_PORT = process.env.ADMIN_PORT || 5056;
});
server.listen(PORT, () => logger.info(`HeliumRecServer WebSocket listening on ws://0.0.0.0:${PORT}`));
// Start admin console (HTTP) bound to ADMIN_PORT
admin.start({ port: ADMIN_PORT, getConnections: () => connections });
})();