settings-site: phase 2 correctness fixes (proxy helper, /healthz, datetime-local min, health polling)

This commit is contained in:
2026-04-18 16:32:37 +00:00
parent 84c7a50cc3
commit 3e2bf919e9
2 changed files with 99 additions and 26 deletions

View File

@@ -115,8 +115,41 @@ async function callBot(method, apiPath, body) {
return res.json();
}
function proxy(method, botPath) {
return async (req, res) => {
try {
const data = await callBot(method, botPath, method === 'POST' ? req.body : undefined);
res.json(data);
} catch (e) {
res.status(502).json({ error: 'Bot unreachable' });
}
};
}
async function pingBot() {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 2000);
try {
const r = await fetch(`${INTERNAL_URL}/config`, {
method: 'GET',
headers: { 'x-internal-secret': SECRET },
signal: controller.signal
});
return r.ok;
} catch (_) {
return false;
} finally {
clearTimeout(timer);
}
}
app.use(express.static(path.join(__dirname, 'public'), { index: false }));
app.get('/healthz', async (req, res) => {
const bot = await pingBot();
res.json({ ok: true, bot });
});
app.get('/api/csrf-token', (req, res) => {
const csrfToken = generateCsrfToken(req, res);
res.json({ csrfToken });
@@ -145,30 +178,11 @@ app.get('/', requireAuth, (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
app.get('/api/config', apiLimiter, requireAuth, async (req, res) => {
try { res.json(await callBot('GET', '/config')); }
catch (e) { res.status(502).json({ error: 'Bot unreachable' }); }
});
app.post('/api/config', apiLimiter, 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', apiLimiter, 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', apiLimiter, 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', apiLimiter, requireAuth, async (req, res) => {
try { res.json(await callBot('GET', '/restart/status')); }
catch (e) { res.status(502).json({ error: 'Bot unreachable' }); }
});
app.get('/api/config', apiLimiter, requireAuth, proxy('GET', '/config'));
app.post('/api/config', apiLimiter, requireAuth, proxy('POST', '/config'));
app.get('/api/discord/guild', apiLimiter, requireAuth, proxy('GET', '/discord/guild'));
app.post('/api/restart', apiLimiter, requireAuth, proxy('POST', '/restart'));
app.get('/api/restart/status', apiLimiter, requireAuth, proxy('GET', '/restart/status'));
app.get('*', requireAuth, (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));