feat(mam-api): wire users, groups, and tokens routes into main app

This commit is contained in:
Zac Gaetano 2026-05-18 12:51:14 -04:00
parent 1e4c92c2df
commit 28a4b24911

View file

@ -5,6 +5,7 @@ import session from 'express-session';
import ConnectPgSimple from 'connect-pg-simple'; import ConnectPgSimple from 'connect-pg-simple';
import pool from './db/pool.js'; import pool from './db/pool.js';
import { errorHandler } from './middleware/errors.js'; import { errorHandler } from './middleware/errors.js';
import { requireAuth } from './middleware/auth.js';
// Routes // Routes
import authRouter from './routes/auth.js'; import authRouter from './routes/auth.js';
@ -17,22 +18,22 @@ import uploadRouter from './routes/upload.js';
import recordersRouter from './routes/recorders.js'; import recordersRouter from './routes/recorders.js';
import settingsRouter from './routes/settings.js'; import settingsRouter from './routes/settings.js';
import amppRouter from './routes/ampp.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 app = express();
const PORT = process.env.PORT || 3000; const PORT = process.env.PORT || 3000;
// ── Middleware ──────────────────────────────────────────────────────────────── // ── Middleware ────────────────────────────────────────────────────────────────
app.use(cors({ origin: true, credentials: true })); app.use(cors({ origin: true, credentials: true }));
app.use(express.json({ limit: '50mb' })); app.use(express.json({ limit: '50mb' }));
const PgSession = ConnectPgSimple(session); const PgSession = ConnectPgSimple(session);
app.use(session({
app.use(
session({
store: new PgSession({ store: new PgSession({
pool, pool,
tableName: 'sessions', tableName: 'sessions',
// Prune expired sessions every hour
pruneSessionInterval: 3600, pruneSessionInterval: 3600,
}), }),
secret: process.env.SESSION_SECRET || 'change-me-in-production', secret: process.env.SESSION_SECRET || 'change-me-in-production',
@ -43,33 +44,40 @@ app.use(
httpOnly: true, httpOnly: true,
maxAge: 1000 * 60 * 60 * 24, // 24 h maxAge: 1000 * 60 * 60 * 24, // 24 h
}, },
}) }));
);
// ── Health (no auth) ────────────────────────────────────────────────────────── // ── Health (no auth) ──────────────────────────────────────────────────────────
app.get('/health', (_req, res) => res.json({ status: 'ok' })); app.get('/health', (_req, res) => res.json({ status: 'ok' }));
// ── API Routes ──────────────────────────────────────────────────────────────── // ── Auth routes (always open) ─────────────────────────────────────────────────
// Auth routes are always open (login/logout don't require a session)
app.use('/api/v1/auth', authRouter); app.use('/api/v1/auth', authRouter);
// All other routes are gated by requireAuth (no-op unless AUTH_ENABLED=true) // ── Protected routes (requireAuth is a no-op unless AUTH_ENABLED=true) ────────
app.use('/api/v1/assets', assetsRouter); app.use('/api/v1/assets', requireAuth, assetsRouter);
app.use('/api/v1/projects', projectsRouter); app.use('/api/v1/projects', requireAuth, projectsRouter);
app.use('/api/v1/bins', binsRouter); app.use('/api/v1/bins', requireAuth, binsRouter);
app.use('/api/v1/jobs', jobsRouter); app.use('/api/v1/jobs', requireAuth, jobsRouter);
app.use('/api/v1/capture', captureRouter); app.use('/api/v1/capture', requireAuth, captureRouter);
app.use('/api/v1/upload', uploadRouter); app.use('/api/v1/upload', requireAuth, uploadRouter);
app.use('/api/v1/recorders', recordersRouter); app.use('/api/v1/recorders', requireAuth, recordersRouter);
app.use('/api/v1/settings', settingsRouter); app.use('/api/v1/settings', requireAuth, settingsRouter);
app.use('/api/v1/ampp', amppRouter); 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 ───────────────────────────────────────────────────────────── // ── Error handler ─────────────────────────────────────────────────────────────
app.use(errorHandler); app.use(errorHandler);
// ── Start ──────────────────────────────────────────────────────────────────── // ── Start ────────────────────────────────────────────────────────────────────
app.listen(PORT, () => { app.listen(PORT, () => {
const authMode = process.env.AUTH_ENABLED === 'true' ? 'ENABLED' : 'DISABLED (set AUTH_ENABLED=true for production)'; 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(`MAM API listening on port ${PORT}`);
console.log(`Authentication: ${authMode}`); console.log(`Authentication: ${authMode}`);
}); });