/** * SessionGateway - Server-side session management * * Fetches session data from the API using server cookies. * Designed for 'use server' contexts. */ import type { NextRequest } from 'next/server'; import type { AuthSessionDTO } from '../types/generated/AuthSessionDTO'; /** * SessionGateway class for server-side session management * * Supports both middleware and server component contexts */ export class SessionGateway { /** * Get current authentication session from cookies * * @param cookieHeader - Raw cookie header string (for middleware) * @returns Promise - Session object or null if not authenticated/error */ async getSession(cookieHeader?: string): Promise { try { let cookieString: string; // Handle middleware context (cookieHeader provided) vs server component context if (cookieHeader !== undefined) { // Middleware context - use provided cookie header cookieString = cookieHeader; console.log(`[SESSION] Using provided cookie header, length:`, cookieString.length); } else { // Server component context - get cookies from next/headers try { const { cookies } = await import('next/headers'); const cookieStore = await cookies(); cookieString = cookieStore.toString(); console.log(`[SESSION] Using server component cookies, length:`, cookieString.length); } catch (error) { console.log(`[SESSION] Could not access cookies in server component context:`, error); return null; } } console.log(`[SESSION] Cookie string:`, cookieString.substring(0, 200) + (cookieString.length > 200 ? '...' : '')); // If no cookies, return null immediately if (!cookieString) { console.log(`[SESSION] No cookies found, returning null`); return null; } // Determine API base URL // In Docker/test: use API_BASE_URL env var or direct API URL // In production: use relative path which will be rewritten // The API is always at http://api:3000 in the Docker network const baseUrl = process.env.API_BASE_URL || 'http://localhost:3101'; const apiUrl = `${baseUrl}/auth/session`; console.log(`[SESSION] Fetching session from:`, apiUrl); // Fetch session from API with cookies forwarded const response = await fetch(apiUrl, { headers: { cookie: cookieString, }, cache: 'no-store', credentials: 'include', }); console.log(`[SESSION] Response status:`, response.status); console.log(`[SESSION] Response ok:`, response.ok); // Return null for non-2xx responses if (!response.ok) { console.log(`[SESSION] Non-2xx response, returning null`); return null; } // Parse and return session data const session = await response.json(); console.log(`[SESSION] Session parsed successfully:`, JSON.stringify(session, null, 2)); console.log(`[SESSION] Session user role:`, session?.user?.role); return session as AuthSessionDTO; } catch (error) { console.log(`[SESSION] Error occurred:`, error); // Return null on any error (network, parsing, etc.) return null; } } /** * Get session from NextRequest (for middleware use) */ async getSessionFromRequest(request: NextRequest): Promise { const cookieHeader = request.headers.get('cookie') || ''; console.log(`[SESSION] NextRequest cookie header length:`, cookieHeader.length); console.log(`[SESSION] NextRequest cookie header:`, cookieHeader.substring(0, 200) + (cookieHeader.length > 200 ? '...' : '')); return this.getSession(cookieHeader); } }