port-nimara-client-portal/server/api/auth/refresh.ts

105 lines
3.2 KiB
TypeScript
Raw Normal View History

import { keycloakClient } from '~/server/utils/keycloak-client'
export default defineEventHandler(async (event) => {
const startTime = Date.now()
console.log('[REFRESH] Processing token refresh request')
try {
// Get current session
const oidcSession = getCookie(event, 'nuxt-oidc-auth')
if (!oidcSession) {
console.error('[REFRESH] No session found')
throw createError({
statusCode: 401,
statusMessage: 'No session found'
})
}
let sessionData
try {
sessionData = JSON.parse(oidcSession)
} catch (parseError) {
console.error('[REFRESH] Failed to parse session:', parseError)
throw createError({
statusCode: 401,
statusMessage: 'Invalid session format'
})
}
// Check if we have a refresh token
if (!sessionData.refreshToken) {
console.error('[REFRESH] No refresh token available')
throw createError({
statusCode: 401,
statusMessage: 'No refresh token available'
})
}
// Validate environment variables
const clientSecret = process.env.KEYCLOAK_CLIENT_SECRET
if (!clientSecret) {
console.error('[REFRESH] KEYCLOAK_CLIENT_SECRET not configured')
throw createError({
statusCode: 500,
statusMessage: 'Authentication service misconfigured'
})
}
// Use refresh token to get new access token with retry logic
console.log('[REFRESH] Using Keycloak client for token refresh...')
const tokenResponse = await keycloakClient.refreshAccessToken(sessionData.refreshToken)
const refreshDuration = Date.now() - startTime
console.log(`[REFRESH] Token refresh successful in ${refreshDuration}ms:`, {
hasAccessToken: !!tokenResponse.access_token,
hasRefreshToken: !!tokenResponse.refresh_token,
expiresIn: tokenResponse.expires_in
})
// Update session with new tokens
const updatedSessionData = {
...sessionData,
accessToken: tokenResponse.access_token,
refreshToken: tokenResponse.refresh_token || sessionData.refreshToken, // Keep old refresh token if new one not provided
expiresAt: Date.now() + (tokenResponse.expires_in * 1000),
refreshedAt: Date.now()
}
// Set updated session cookie with proper session duration
const sessionDuration = 8 * 60 * 60; // 8 hours in seconds
const cookieDomain = process.env.COOKIE_DOMAIN || '.portnimara.dev';
setCookie(event, 'nuxt-oidc-auth', JSON.stringify(updatedSessionData), {
httpOnly: true,
secure: true,
sameSite: 'lax',
maxAge: sessionDuration,
domain: cookieDomain,
path: '/'
})
console.log('[REFRESH] Session updated successfully')
return {
success: true,
expiresAt: updatedSessionData.expiresAt
}
} catch (error: any) {
console.error('[REFRESH] Token refresh failed:', error)
// Clear invalid session
const cookieDomain = process.env.COOKIE_DOMAIN || '.portnimara.dev';
deleteCookie(event, 'nuxt-oidc-auth', {
domain: cookieDomain,
path: '/'
})
throw createError({
statusCode: 401,
statusMessage: 'Token refresh failed - please login again'
})
}
})