FEAT: Implement Keycloak client with circuit breaker and retry logic for improved authentication resilience
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
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...')
|
||||
@@ -26,27 +29,57 @@ export default defineNitroPlugin(async (nitroApp) => {
|
||||
}
|
||||
|
||||
// Check environment variables
|
||||
console.log('[STARTUP] Checking OIDC environment variables...')
|
||||
console.log('[STARTUP] Checking authentication environment variables...')
|
||||
const requiredEnvVars = [
|
||||
'NUXT_OIDC_TOKEN_KEY',
|
||||
'NUXT_OIDC_SESSION_SECRET',
|
||||
'NUXT_OIDC_AUTH_SESSION_SECRET',
|
||||
'NUXT_OIDC_PROVIDERS_KEYCLOAK_CLIENT_SECRET'
|
||||
'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
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[STARTUP] Server-side initialization complete')
|
||||
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)
|
||||
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()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user