diff --git a/services/mam-api/src/routes/auth.js b/services/mam-api/src/routes/auth.js index 6ca4885..3c8d862 100644 --- a/services/mam-api/src/routes/auth.js +++ b/services/mam-api/src/routes/auth.js @@ -127,10 +127,11 @@ router.post('/login', async (req, res, next) => { // Successful login — clear any accumulated failed attempts clearAttempts(req, username); - // Regenerate session ID to prevent fixation attacks. - // Explicit save() + log on success/failure so a broken session store - // (missing table, PG read-only, etc.) doesn't silently 200 with no - // persisted session — the symptom that caused the redirect loop. + // Regenerate session ID to prevent fixation attacks, then let + // express-session write Set-Cookie on its own res.end() hook. + // Do NOT call session.save() manually — that writes the store but + // bypasses the middleware's header-writing path, which is why the + // Set-Cookie header was missing even though the session row existed. req.session.regenerate((err) => { if (err) { console.error('[auth] session.regenerate failed:', err); @@ -139,18 +140,12 @@ router.post('/login', async (req, res, next) => { req.session.userId = user.id; req.session.username = user.username; req.session.role = user.role; - req.session.save((saveErr) => { - if (saveErr) { - console.error('[auth] session.save failed:', saveErr); - return next(saveErr); - } - console.log(`[auth] login ok user=${user.username} sid=${req.sessionID?.slice(0,8) || '?'} secure=${req.secure} proto=${req.protocol}`); - res.json({ - id: user.id, - username: user.username, - display_name: user.display_name, - role: user.role, - }); + console.log(`[auth] login ok user=${user.username} sid=${req.sessionID?.slice(0,8) || '?'} secure=${req.secure} proto=${req.protocol}`); + res.json({ + id: user.id, + username: user.username, + display_name: user.display_name, + role: user.role, }); }); } catch (err) {