// server/api/auth/validate-session.post.ts export default defineEventHandler(async (event) => { const config = useRuntimeConfig() const sessionCookie = getCookie(event, 'user_session') console.log('🔍 Session validation endpoint called') console.log('🍪 Session cookie exists:', !!sessionCookie) if (!sessionCookie) { console.log('❌ No session cookie found') return { valid: false, reason: 'no_session' } } try { // Decode JWT-based session from cookie const sessionJson = Buffer.from(sessionCookie, 'base64').toString('utf-8'); const session = JSON.parse(sessionJson); if (!session) { console.log('❌ Session not found or invalid') deleteCookie(event, 'user_session') return { valid: false, reason: 'session_not_found' } } // Check local expiry if (Date.now() > session.expiresAt) { console.log('⏰ Session has expired locally') deleteCookie(event, 'user_session') return { valid: false, reason: 'session_expired' } } // Validate with Keycloak userinfo endpoint try { const userInfoUrl = `${config.keycloakIssuer}/protocol/openid-connect/userinfo` console.log('🔗 Validating with Keycloak:', userInfoUrl) const userInfo = await $fetch(userInfoUrl, { headers: { Authorization: `Bearer ${session.accessToken}` } }) console.log('✅ Session is valid with Keycloak') return { valid: true, user: { id: session.user.id, email: session.user.email, name: session.user.name } } } catch (keycloakError: any) { // If Keycloak returns 401, the session is invalid on their side if (keycloakError.status === 401 || keycloakError.statusCode === 401) { console.log('❌ Keycloak session has expired (401)') deleteCookie(event, 'user_session') return { valid: false, reason: 'keycloak_session_expired' } } // For other errors, log but don't invalidate the session console.warn('⚠️ Keycloak validation error (non-401):', keycloakError.message) throw keycloakError } } catch (error: any) { console.error('❌ Session validation error:', error) // On error, clear the session to be safe deleteCookie(event, 'user_session') return { valid: false, reason: 'validation_error', error: error.message } } })