import 'dotenv/config'; import express from 'express'; import cors from 'cors'; import session from 'express-session'; import ConnectPgSimple from 'connect-pg-simple'; import pool from './db/pool.js'; import { errorHandler } from './middleware/errors.js'; import { requireAuth } from './middleware/auth.js'; // Routes import authRouter from './routes/auth.js'; import assetsRouter from './routes/assets.js'; import projectsRouter from './routes/projects.js'; import binsRouter from './routes/bins.js'; import jobsRouter from './routes/jobs.js'; import captureRouter from './routes/capture.js'; import uploadRouter from './routes/upload.js'; import recordersRouter from './routes/recorders.js'; import settingsRouter from './routes/settings.js'; import amppRouter from './routes/ampp.js'; import usersRouter from './routes/users.js'; import groupsRouter from './routes/groups.js'; import tokensRouter from './routes/tokens.js'; const app = express(); const PORT = process.env.PORT || 3000; // ── Middleware ───────────────────────────────────────────────────────────────── app.use(cors({ origin: true, credentials: true })); app.use(express.json({ limit: '50mb' })); const PgSession = ConnectPgSimple(session); app.use(session({ store: new PgSession({ pool, tableName: 'sessions', pruneSessionInterval: 3600, }), secret: process.env.SESSION_SECRET || 'change-me-in-production', resave: false, saveUninitialized: false, cookie: { secure: process.env.NODE_ENV === 'production', httpOnly: true, maxAge: 1000 * 60 * 60 * 24, // 24 h }, })); // ── Health (no auth) ────────────────────────────────────────────────────────── app.get('/health', (_req, res) => res.json({ status: 'ok' })); // ── Auth routes (always open) ───────────────────────────────────────────────── app.use('/api/v1/auth', authRouter); // ── Protected routes (requireAuth is a no-op unless AUTH_ENABLED=true) ──────── app.use('/api/v1/assets', requireAuth, assetsRouter); app.use('/api/v1/projects', requireAuth, projectsRouter); app.use('/api/v1/bins', requireAuth, binsRouter); app.use('/api/v1/jobs', requireAuth, jobsRouter); app.use('/api/v1/capture', requireAuth, captureRouter); app.use('/api/v1/upload', requireAuth, uploadRouter); app.use('/api/v1/recorders', requireAuth, recordersRouter); app.use('/api/v1/settings', requireAuth, settingsRouter); app.use('/api/v1/ampp', requireAuth, amppRouter); // ── Admin routes (requireAuth + requireAdmin applied inside each router) ─────── app.use('/api/v1/users', usersRouter); app.use('/api/v1/groups', groupsRouter); // ── Personal token management ───────────────────────────────────────────────── app.use('/api/v1/tokens', requireAuth, tokensRouter); // ── Error handler ───────────────────────────────────────────────────────────── app.use(errorHandler); // ── Start ───────────────────────────────────────────────────────────────────── app.listen(PORT, () => { const authMode = process.env.AUTH_ENABLED === 'true' ? 'ENABLED' : 'DISABLED (set AUTH_ENABLED=true to require login)'; console.log(`MAM API listening on port ${PORT}`); console.log(`Authentication: ${authMode}`); });