86 lines
3.0 KiB
TypeScript
86 lines
3.0 KiB
TypeScript
import { mkdir } from 'fs/promises'
|
|
import { existsSync } from 'fs'
|
|
import { join } from 'path'
|
|
import { keycloakClient } from '~/server/utils/keycloak-client'
|
|
|
|
let isAppReady = false
|
|
|
|
export default defineNitroPlugin(async (nitroApp) => {
|
|
console.log('[STARTUP] Server-side initialization starting...')
|
|
|
|
try {
|
|
// Ensure data directories exist
|
|
const dataDir = './data'
|
|
const oidcSessionsDir = './data/oidc-sessions'
|
|
const sessionsDir = './data/sessions'
|
|
|
|
console.log('[STARTUP] Checking storage directories...')
|
|
|
|
// Create directories if they don't exist
|
|
const dirs = [dataDir, oidcSessionsDir, sessionsDir]
|
|
for (const dir of dirs) {
|
|
if (!existsSync(dir)) {
|
|
console.log(`[STARTUP] Creating directory: ${dir}`)
|
|
await mkdir(dir, { recursive: true })
|
|
console.log(`[STARTUP] Successfully created: ${dir}`)
|
|
} else {
|
|
console.log(`[STARTUP] Directory exists: ${dir}`)
|
|
}
|
|
}
|
|
|
|
// Check environment variables
|
|
console.log('[STARTUP] Checking authentication environment variables...')
|
|
const requiredEnvVars = [
|
|
'KEYCLOAK_CLIENT_SECRET',
|
|
'COOKIE_DOMAIN'
|
|
]
|
|
|
|
let envVarsOk = true
|
|
for (const envVar of requiredEnvVars) {
|
|
const value = process.env[envVar]
|
|
if (value) {
|
|
console.log(`[STARTUP] ✅ ${envVar}: present (length: ${value.length})`)
|
|
} else {
|
|
console.error(`[STARTUP] ❌ ${envVar}: MISSING`)
|
|
envVarsOk = false
|
|
}
|
|
}
|
|
|
|
if (!envVarsOk) {
|
|
console.error('[STARTUP] ❌ Required environment variables missing - authentication may fail')
|
|
}
|
|
|
|
// Warm up Keycloak connections
|
|
console.log('[STARTUP] Warming up Keycloak connections...')
|
|
try {
|
|
// Test the circuit breaker status endpoint (doesn't require auth)
|
|
const circuitStatus = keycloakClient.getCircuitBreakerStatus()
|
|
console.log('[STARTUP] ✅ Keycloak client initialized:', circuitStatus)
|
|
|
|
// Optionally test connectivity (uncomment if needed)
|
|
// const testUrl = 'https://auth.portnimara.dev/realms/client-portal/.well-known/openid-configuration'
|
|
// await keycloakClient.fetch(testUrl, {}, { timeout: 5000, retries: 1 })
|
|
// console.log('[STARTUP] ✅ Keycloak connectivity verified')
|
|
|
|
} catch (error) {
|
|
console.error('[STARTUP] ⚠️ Keycloak warmup failed:', error)
|
|
// Continue anyway - circuit breaker will handle runtime failures
|
|
}
|
|
|
|
// Mark app as ready
|
|
isAppReady = true
|
|
console.log('[STARTUP] ✅ Server-side initialization complete - app ready')
|
|
|
|
} catch (error) {
|
|
console.error('[STARTUP] ❌ Server-side initialization error:', error)
|
|
// Don't throw - let the app continue with fallback behavior
|
|
isAppReady = true // Allow app to start even with initialization errors
|
|
}
|
|
})
|
|
|
|
// Export readiness check for health endpoint
|
|
export const getAppReadiness = () => ({
|
|
ready: isAppReady,
|
|
keycloakCircuitBreaker: keycloakClient.getCircuitBreakerStatus()
|
|
})
|