import { Request, Response, NextFunction } from 'express'; import { Pool } from 'pg'; // Helper utility to parse cookies manually without adding extra npm packages function parseCookieString(cookieHeader: string | undefined, name: string): string | null { if (!cookieHeader) return null; const match = cookieHeader.match(new RegExp('(^| )' + name + '=([^;]+)')); return match ? match[2] : null; } export function createAuthMiddleware(db: Pool) { return async (req: Request, res: Response, next: NextFunction): Promise => { try { const cookieHeader = req.headers.cookie; const token = parseCookieString(cookieHeader, 'session_token'); if (!token) { res.status(401).json({ success: false, error: 'Unauthorized. Session cookie missing.' }); return; } // Query the database to find an active session matching the token const query = ` SELECT user_id, expires_at FROM sessions WHERE id = $1; `; const result = await db.query(query, [token]); if (result.rows.length === 0) { res.status(401).json({ success: false, error: 'Unauthorized. Invalid session token.' }); return; } const session = result.rows[0]; const now = new Date(); // Validate expiration constraint if (new Date(session.expires_at) < now) { res.status(401).json({ success: false, error: 'Unauthorized. Session expired.' }); return; } // Inject the authenticated identity directly into the Request object for use in down-stream router handlers (req as any).userId = session.user_id; next(); // Execution matches, pass cleanly to route target } catch (error) { console.error('Auth middleware failure:', error); res.status(500).json({ success: false, error: 'Internal Server Error' }); } }; }