Files
gridpilot.gg/apps/website/lib/gateways/SessionGateway.ts
2026-01-08 15:34:51 +01:00

102 lines
3.7 KiB
TypeScript

/**
* 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<AuthSessionDTO | null> - Session object or null if not authenticated/error
*/
async getSession(cookieHeader?: string): Promise<AuthSessionDTO | null> {
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<AuthSessionDTO | null> {
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);
}
}