Files
ProxMenux/AppImage/lib/api-config.ts

127 lines
3.6 KiB
TypeScript
Raw Normal View History

2025-11-03 18:35:16 +01:00
/**
* API Configuration for ProxMenux Monitor
* Handles API URL generation with automatic proxy detection
*/
2025-11-11 17:04:26 +01:00
/**
* 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
*/
2025-11-11 22:00:44 +01:00
export const API_PORT = process.env.NEXT_PUBLIC_API_PORT || "8008"
2025-11-11 17:04:26 +01:00
2025-11-03 18:35:16 +01:00
/**
* 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") {
2025-11-04 19:58:09 +01:00
console.log("[v0] getApiBaseUrl: Running on server (SSR)")
2025-11-03 18:35:16 +01:00
return ""
}
const { protocol, hostname, port } = window.location
2025-11-04 19:58:09 +01:00
console.log("[v0] getApiBaseUrl - protocol:", protocol, "hostname:", hostname, "port:", port)
2025-11-03 18:35:16 +01:00
// 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"
2025-11-04 19:58:09 +01:00
console.log("[v0] getApiBaseUrl - isStandardPort:", isStandardPort)
2025-11-03 18:35:16 +01:00
if (isStandardPort) {
// Behind a proxy - use relative URL
2025-11-04 19:58:09 +01:00
console.log("[v0] getApiBaseUrl: Detected proxy access, using relative URLs")
2025-11-03 18:35:16 +01:00
return ""
} else {
2025-11-11 17:04:26 +01:00
// Direct access - use explicit API port
const baseUrl = `${protocol}//${hostname}:${API_PORT}`
2025-11-04 19:58:09 +01:00
console.log("[v0] getApiBaseUrl: Direct access detected, using:", baseUrl)
return baseUrl
2025-11-03 18:35:16 +01:00
}
}
/**
* 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}`
}
2025-11-13 17:14:47 +01:00
/**
* 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
}
2025-11-13 17:20:31 +01:00
const token = localStorage.getItem("proxmenux-auth-token")
2025-11-13 17:25:51 +01:00
console.log(
"[v0] getAuthToken called:",
token ? `Token found (length: ${token.length})` : "No token found in localStorage",
)
2025-11-13 17:20:31 +01:00
return token
2025-11-13 17:14:47 +01:00
}
2025-11-03 18:35:16 +01:00
/**
* 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<T>(endpoint: string, options?: RequestInit): Promise<T> {
const url = getApiUrl(endpoint)
2025-11-13 17:14:47 +01:00
const token = getAuthToken()
const headers: Record<string, string> = {
"Content-Type": "application/json",
...(options?.headers as Record<string, string>),
}
if (token) {
headers["Authorization"] = `Bearer ${token}`
2025-11-13 17:25:51 +01:00
console.log("[v0] fetchApi:", endpoint, "- Authorization header ADDED")
2025-11-13 17:20:31 +01:00
} else {
2025-11-13 17:25:51 +01:00
console.log("[v0] fetchApi:", endpoint, "- NO TOKEN - Request will fail if endpoint is protected")
2025-11-13 17:14:47 +01:00
}
2025-11-13 17:25:51 +01:00
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
2025-11-03 18:35:16 +01:00
}
}