This commit is contained in:
Iliyan Angelov
2025-11-25 20:18:23 +02:00
parent 8823edc8b3
commit e639736187
16 changed files with 190 additions and 61 deletions

View File

@@ -45,7 +45,52 @@ export const API_BASE_URL = isServer
// Internal API key for server-side requests (must match backend INTERNAL_API_KEY)
// This is only used when calling backend directly (build time or internal requests)
export const INTERNAL_API_KEY = process.env.INTERNAL_API_KEY || '9hZtPwyScigoBAl59Uvcz_9VztSRC6Zt_6L1B2xTM2M';
// SECURITY: Never hardcode API keys in production - always use environment variables
const getInternalApiKey = (): string => {
const apiKey = process.env.INTERNAL_API_KEY;
// Check if we're in build phase (Next.js build context)
// During build, NEXT_RUNTIME is typically not set
// Also check for specific build phases
const isBuildTime =
!process.env.NEXT_RUNTIME || // Most reliable indicator - not set during build
process.env.NEXT_PHASE === 'phase-production-build' ||
process.env.NEXT_PHASE === 'phase-production-compile' ||
process.env.NEXT_PHASE === 'phase-development-build';
if (!apiKey) {
// During build time, be lenient - allow build to proceed
// The key will be validated when actually used (in getApiHeaders)
if (isBuildTime) {
// Build time: allow fallback (will be validated when actually used)
return 'build-time-fallback-key';
}
// Runtime production: require the key (but only validate when actually used)
if (isProduction) {
// Don't throw here - validate lazily in getApiHeaders when actually needed
// This allows the build to complete even if key is missing
return 'runtime-requires-key';
}
// Development fallback (only for local development)
return 'dev-key-not-for-production';
}
return apiKey;
};
// Lazy getter - only evaluates when accessed
let _internalApiKey: string | null = null;
export const getInternalApiKeyLazy = (): string => {
if (_internalApiKey === null) {
_internalApiKey = getInternalApiKey();
}
return _internalApiKey;
};
// For backward compatibility - evaluates at module load but uses lenient validation
export const INTERNAL_API_KEY = getInternalApiKeyLazy();
// Helper to get headers for API requests
// Adds API key header when calling internal backend directly
@@ -55,9 +100,25 @@ export const getApiHeaders = (): Record<string, string> => {
};
// If we're calling the internal backend directly (not through nginx),
// add the API key header
// add the API key header (lazy evaluation - only when actually needed)
if (isServer && API_BASE_URL.includes('127.0.0.1:1086')) {
headers['X-Internal-API-Key'] = INTERNAL_API_KEY;
const apiKey = getInternalApiKeyLazy();
// Validate API key when actually used (not at module load time)
if (apiKey === 'runtime-requires-key' && isProduction) {
const actualKey = process.env.INTERNAL_API_KEY;
if (!actualKey) {
throw new Error(
'INTERNAL_API_KEY environment variable is required in production runtime. ' +
'Set it in your .env.production file or environment variables.'
);
}
// Update cached value
_internalApiKey = actualKey;
headers['X-Internal-API-Key'] = actualKey;
} else {
headers['X-Internal-API-Key'] = apiKey;
}
}
return headers;