huge changes
This commit is contained in:
98
settings-site/server.js
Normal file
98
settings-site/server.js
Normal file
@@ -0,0 +1,98 @@
|
||||
require('dotenv').config({ path: process.env.ENV_FILE || '../.env' });
|
||||
const express = require('express');
|
||||
const session = require('express-session');
|
||||
const path = require('path');
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
const app = express();
|
||||
const PORT = parseInt(process.env.SETTINGS_PORT) || 12752;
|
||||
const INTERNAL_URL = `http://127.0.0.1:${process.env.INTERNAL_API_PORT || 12753}/internal`;
|
||||
const SECRET = process.env.INTERNAL_API_SECRET;
|
||||
const ADMIN_PASSWORD = process.env.SETTINGS_ADMIN_PASSWORD;
|
||||
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
app.use(express.static(path.join(__dirname, 'public')));
|
||||
app.use(session({
|
||||
secret: SECRET || 'fallback-secret-change-me',
|
||||
resave: false,
|
||||
saveUninitialized: false,
|
||||
cookie: {
|
||||
httpOnly: true,
|
||||
secure: false, // set true if behind HTTPS proxy
|
||||
maxAge: 8 * 60 * 60 * 1000 // 8 hours
|
||||
}
|
||||
}));
|
||||
|
||||
// Auth middleware
|
||||
function requireAuth(req, res, next) {
|
||||
if (req.session?.authed) return next();
|
||||
res.redirect('/login');
|
||||
}
|
||||
|
||||
// Internal API proxy helper
|
||||
async function callBot(method, apiPath, body) {
|
||||
const res = await fetch(`${INTERNAL_URL}${apiPath}`, {
|
||||
method,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'x-internal-secret': SECRET
|
||||
},
|
||||
body: body ? JSON.stringify(body) : undefined
|
||||
});
|
||||
return res.json();
|
||||
}
|
||||
|
||||
// Routes
|
||||
app.get('/login', (req, res) => {
|
||||
if (req.session?.authed) return res.redirect('/');
|
||||
res.sendFile(path.join(__dirname, 'public', 'login.html'));
|
||||
});
|
||||
|
||||
app.post('/login', (req, res) => {
|
||||
if (!ADMIN_PASSWORD) return res.status(503).json({ error: 'SETTINGS_ADMIN_PASSWORD not set' });
|
||||
if (req.body.password === ADMIN_PASSWORD) {
|
||||
req.session.authed = true;
|
||||
return res.json({ ok: true });
|
||||
}
|
||||
res.status(401).json({ error: 'Invalid password' });
|
||||
});
|
||||
|
||||
app.post('/logout', (req, res) => {
|
||||
req.session.destroy();
|
||||
res.redirect('/login');
|
||||
});
|
||||
|
||||
app.get('/', requireAuth, (req, res) => {
|
||||
res.sendFile(path.join(__dirname, 'public', 'index.html'));
|
||||
});
|
||||
|
||||
// Proxy to bot internal API
|
||||
app.get('/api/config', requireAuth, async (req, res) => {
|
||||
try { res.json(await callBot('GET', '/config')); }
|
||||
catch (e) { res.status(502).json({ error: 'Bot unreachable' }); }
|
||||
});
|
||||
|
||||
app.post('/api/config', requireAuth, async (req, res) => {
|
||||
try { res.json(await callBot('POST', '/config', req.body)); }
|
||||
catch (e) { res.status(502).json({ error: 'Bot unreachable' }); }
|
||||
});
|
||||
|
||||
app.get('/api/discord/guild', requireAuth, async (req, res) => {
|
||||
try { res.json(await callBot('GET', '/discord/guild')); }
|
||||
catch (e) { res.status(502).json({ error: 'Bot unreachable' }); }
|
||||
});
|
||||
|
||||
app.post('/api/restart', requireAuth, async (req, res) => {
|
||||
try { res.json(await callBot('POST', '/restart', req.body)); }
|
||||
catch (e) { res.status(502).json({ error: 'Bot unreachable' }); }
|
||||
});
|
||||
|
||||
app.get('/api/restart/status', requireAuth, async (req, res) => {
|
||||
try { res.json(await callBot('GET', '/restart/status')); }
|
||||
catch (e) { res.status(502).json({ error: 'Bot unreachable' }); }
|
||||
});
|
||||
|
||||
app.listen(PORT, '0.0.0.0', () => {
|
||||
console.log(`[settings] running on port ${PORT}`);
|
||||
});
|
||||
Reference in New Issue
Block a user