75 lines
2.4 KiB
TypeScript
75 lines
2.4 KiB
TypeScript
// 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
|
|
}
|
|
}
|
|
})
|