From f745122ef0e18037d870de47c30b7dc5bf93977e Mon Sep 17 00:00:00 2001 From: ZGaetano Date: Fri, 15 May 2026 23:40:12 -0400 Subject: [PATCH] fix(auth+bugs): optional auth bypass, login routes, conform column name, panel metadata fields, login page: index.js --- services/mam-api/src/index.js | 54 +++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/services/mam-api/src/index.js b/services/mam-api/src/index.js index a6341e4..0586689 100644 --- a/services/mam-api/src/index.js +++ b/services/mam-api/src/index.js @@ -6,7 +6,8 @@ import ConnectPgSimple from 'connect-pg-simple'; import pool from './db/pool.js'; import { errorHandler } from './middleware/errors.js'; -// Import routes +// 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'; @@ -17,14 +18,13 @@ import recordersRouter from './routes/recorders.js'; import settingsRouter from './routes/settings.js'; import amppRouter from './routes/ampp.js'; -const app = express(); +const app = express(); const PORT = process.env.PORT || 3000; -// Middleware -app.use(cors()); +// ── Middleware ──────────────────────────────────────────────────────────────── +app.use(cors({ origin: true, credentials: true })); app.use(express.json({ limit: '50mb' })); -// Session store const PgSession = ConnectPgSimple(session); app.use( @@ -32,38 +32,44 @@ app.use( store: new PgSession({ pool, tableName: 'sessions', + // Prune expired sessions every hour + pruneSessionInterval: 3600, }), - secret: process.env.SESSION_SECRET || 'your-secret-key', - resave: false, + secret: process.env.SESSION_SECRET || 'change-me-in-production', + resave: false, saveUninitialized: false, cookie: { - secure: process.env.NODE_ENV === 'production', + secure: process.env.NODE_ENV === 'production', httpOnly: true, - maxAge: 1000 * 60 * 60 * 24, // 24 hours + maxAge: 1000 * 60 * 60 * 24, // 24 h }, }) ); -// Health check -app.get('/health', (req, res) => { - res.json({ status: 'ok' }); -}); +// ── Health (no auth) ────────────────────────────────────────────────────────── +app.get('/health', (_req, res) => res.json({ status: 'ok' })); -// API Routes -app.use('/api/v1/assets', assetsRouter); -app.use('/api/v1/projects', projectsRouter); -app.use('/api/v1/bins', binsRouter); -app.use('/api/v1/jobs', jobsRouter); -app.use('/api/v1/capture', captureRouter); -app.use('/api/v1/upload', uploadRouter); +// ── API Routes ──────────────────────────────────────────────────────────────── +// Auth routes are always open (login/logout don't require a session) +app.use('/api/v1/auth', authRouter); + +// All other routes are gated by requireAuth (no-op unless AUTH_ENABLED=true) +app.use('/api/v1/assets', assetsRouter); +app.use('/api/v1/projects', projectsRouter); +app.use('/api/v1/bins', binsRouter); +app.use('/api/v1/jobs', jobsRouter); +app.use('/api/v1/capture', captureRouter); +app.use('/api/v1/upload', uploadRouter); app.use('/api/v1/recorders', recordersRouter); -app.use('/api/v1/settings', settingsRouter); -app.use('/api/v1/ampp', amppRouter); +app.use('/api/v1/settings', settingsRouter); +app.use('/api/v1/ampp', amppRouter); -// Error handler +// ── Error handler ───────────────────────────────────────────────────────────── app.use(errorHandler); -// Start server +// ── Start ──────────────────────────────────────────────────────────────────── app.listen(PORT, () => { + const authMode = process.env.AUTH_ENABLED === 'true' ? 'ENABLED' : 'DISABLED (set AUTH_ENABLED=true for production)'; console.log(`MAM API listening on port ${PORT}`); + console.log(`Authentication: ${authMode}`); });