Add external server stats API

This commit is contained in:
DUCK JIN
2026-08-12 17:48:34 +09:00
parent 26baef8448
commit db375a25ed
8 changed files with 155 additions and 2 deletions

View File

@@ -5,6 +5,7 @@ const express = require('express')
const cors = require('cors')
const session = require('express-session')
const FileStoreFactory = require('session-file-store')
const crypto = require('crypto')
function loadEnvFileIfExists(fileName) {
const envPath = path.join(__dirname, '..', fileName)
@@ -23,7 +24,7 @@ if (nodeEnv === 'production') {
if (!loadedLocal) loadEnvFileIfExists('.env.production')
}
const { ensureData } = require('./src/db')
const { ensureData, getServerStats } = require('./src/db')
const authRoutes = require('./src/routes/auth')
const topicsRoutes = require('./src/routes/topics')
const tierListsRoutes = require('./src/routes/tierlists')
@@ -42,9 +43,30 @@ const allowedOrigins = (process.env.CORS_ORIGINS || '')
.split(',')
.map((origin) => origin.trim())
.filter(Boolean)
const SERVER_STATS_TOKEN = String(process.env.SERVER_STATS_TOKEN || '').trim()
const FileStore = FileStoreFactory(session)
function getBearerToken(req) {
const authorization = String(req.headers.authorization || '')
const match = authorization.match(/^Bearer\s+(.+)$/i)
if (match) return match[1].trim()
return String(req.query.token || '').trim()
}
function isEqualSecret(a, b) {
const left = Buffer.from(String(a || ''))
const right = Buffer.from(String(b || ''))
return left.length === right.length && crypto.timingSafeEqual(left, right)
}
function requireServerStatsToken(req, res, next) {
if (!SERVER_STATS_TOKEN) return res.status(503).json({ error: 'server_stats_token_not_configured' })
const token = getBearerToken(req)
if (!token || !isEqualSecret(token, SERVER_STATS_TOKEN)) return res.status(401).json({ error: 'unauthorized' })
next()
}
;['uploads/avatars', 'uploads/topics', 'uploads/custom', 'uploads/tierlists', '.sessions'].forEach((relativePath) => {
fs.mkdirSync(path.join(__dirname, relativePath), { recursive: true })
})
@@ -101,6 +123,10 @@ app.use(async (req, res, next) => {
})
app.use('/api/auth', authRoutes)
app.get('/api/server-stats', requireServerStatsToken, async (req, res) => {
const stats = await getServerStats()
res.json(stats)
})
app.use('/api/topics', topicsRoutes)
app.use('/api/tierlists', tierListsRoutes)
app.use('/api/comments', commentsRoutes)