Files
tier-maker/backend/index.js

90 lines
2.8 KiB
JavaScript

const path = require('path')
const fs = require('fs')
const express = require('express')
const cors = require('cors')
const session = require('express-session')
const FileStoreFactory = require('session-file-store')
const { ensureData } = require('./src/db')
const authRoutes = require('./src/routes/auth')
const topicsRoutes = require('./src/routes/topics')
const tierListsRoutes = require('./src/routes/tierlists')
const adminRoutes = require('./src/routes/admin')
const app = express()
const PORT = process.env.PORT ? Number(process.env.PORT) : 5179
const SESSION_SECRET = process.env.SESSION_SECRET || 'dev-secret-change-me'
const SESSION_COOKIE_SECURE = process.env.SESSION_COOKIE_SECURE === 'true'
const SESSION_COOKIE_SAME_SITE = process.env.SESSION_COOKIE_SAME_SITE || 'lax'
const TRUST_PROXY = process.env.TRUST_PROXY ? Number(process.env.TRUST_PROXY) : 1
const allowedOrigins = (process.env.CORS_ORIGINS || '')
.split(',')
.map((origin) => origin.trim())
.filter(Boolean)
const FileStore = FileStoreFactory(session)
;['uploads/avatars', 'uploads/games', 'uploads/custom', 'uploads/tierlists', '.sessions'].forEach((relativePath) => {
fs.mkdirSync(path.join(__dirname, relativePath), { recursive: true })
})
app.set('trust proxy', TRUST_PROXY)
app.use(
cors({
origin: (origin, cb) => {
if (!origin) return cb(null, true)
if (allowedOrigins.includes(origin)) return cb(null, true)
if (/^http:\/\/localhost:517\d$/.test(origin)) return cb(null, true) // 5170~5179
if (/^https?:\/\/127\.0\.0\.1:517\d$/.test(origin)) return cb(null, true)
if (origin === 'http://localhost:5173') return cb(null, true)
cb(new Error('not_allowed_by_cors'))
},
credentials: true,
})
)
app.use(express.json({ limit: '10mb' }))
app.use(express.urlencoded({ extended: true }))
app.use(
session({
store: new FileStore({
path: path.join(__dirname, '.sessions'),
ttl: 60 * 60 * 24 * 30,
retries: 0,
}),
secret: SESSION_SECRET,
proxy: TRUST_PROXY > 0,
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true,
sameSite: SESSION_COOKIE_SAME_SITE,
secure: SESSION_COOKIE_SECURE,
maxAge: 1000 * 60 * 60 * 24 * 30,
},
})
)
app.use('/uploads', express.static(path.join(__dirname, 'uploads')))
app.get('/health', (req, res) => res.json({ ok: true }))
app.use(async (req, res, next) => {
try {
await ensureData()
next()
} catch (e) {
console.error('[backend] db init failed', e)
res.status(500).json({ error: 'db_init_failed' })
}
})
app.use('/api/auth', authRoutes)
app.use('/api/topics', topicsRoutes)
app.use('/api/tierlists', tierListsRoutes)
app.use('/api/admin', adminRoutes)
app.listen(PORT, () => {
console.log(`[backend] listening on http://localhost:${PORT}`)
})