/** * API Configuration for ProxMenux Monitor * Handles API URL generation with automatic proxy detection */ /** * API Server Port Configuration * Default: 8008 (production) * Can be changed to 8009 for beta testing * This can also be set via NEXT_PUBLIC_API_PORT environment variable */ export const API_PORT = process.env.NEXT_PUBLIC_API_PORT || "8008" /** * Gets the base URL for API calls * Automatically detects if running behind a proxy by checking if we're on a standard port * * @returns Base URL for API endpoints */ export function getApiBaseUrl(): string { if (typeof window === "undefined") { console.log("[v0] getApiBaseUrl: Running on server (SSR)") return "" } const { protocol, hostname, port } = window.location console.log("[v0] getApiBaseUrl - protocol:", protocol, "hostname:", hostname, "port:", port) // If accessing via standard ports (80/443) or no port, assume we're behind a proxy // In this case, use relative URLs so the proxy handles routing const isStandardPort = port === "" || port === "80" || port === "443" console.log("[v0] getApiBaseUrl - isStandardPort:", isStandardPort) if (isStandardPort) { // Behind a proxy - use relative URL console.log("[v0] getApiBaseUrl: Detected proxy access, using relative URLs") return "" } else { // Direct access - use explicit API port const baseUrl = `${protocol}//${hostname}:${API_PORT}` console.log("[v0] getApiBaseUrl: Direct access detected, using:", baseUrl) return baseUrl } } /** * Constructs a full API URL * * @param endpoint - API endpoint path (e.g., '/api/system') * @returns Full API URL */ export function getApiUrl(endpoint: string): string { const baseUrl = getApiBaseUrl() // Ensure endpoint starts with / const normalizedEndpoint = endpoint.startsWith("/") ? endpoint : `/${endpoint}` return `${baseUrl}${normalizedEndpoint}` } /** * Gets the JWT token from localStorage * * @returns JWT token or null if not authenticated */ export function getAuthToken(): string | null { if (typeof window === "undefined") { return null } const token = localStorage.getItem("proxmenux-auth-token") console.log( "[v0] getAuthToken called:", token ? `Token found (length: ${token.length})` : "No token found in localStorage", ) return token } /** * Fetches data from an API endpoint with error handling * * @param endpoint - API endpoint path * @param options - Fetch options * @returns Promise with the response data */ export async function fetchApi(endpoint: string, options?: RequestInit): Promise { const url = getApiUrl(endpoint) const token = getAuthToken() const headers: Record = { "Content-Type": "application/json", ...(options?.headers as Record), } if (token) { headers["Authorization"] = `Bearer ${token}` console.log("[v0] fetchApi:", endpoint, "- Authorization header ADDED") } else { console.log("[v0] fetchApi:", endpoint, "- NO TOKEN - Request will fail if endpoint is protected") } try { const response = await fetch(url, { ...options, headers, cache: "no-store", }) console.log("[v0] fetchApi:", endpoint, "- Response status:", response.status) if (!response.ok) { if (response.status === 401) { console.error("[v0] fetchApi: 401 UNAUTHORIZED -", endpoint, "- Token present:", !!token) throw new Error(`Unauthorized: ${endpoint}`) } throw new Error(`API request failed: ${response.status} ${response.statusText}`) } return response.json() } catch (error) { console.error("[v0] fetchApi error for", endpoint, ":", error) throw error } }