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

111 lines
3.3 KiB
TypeScript

export default defineEventHandler(async (event) => {
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
const tokenResponse = await $fetch('https://auth.portnimara.dev/realms/client-portal/protocol/openid-connect/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'refresh_token',
client_id: 'client-portal',
client_secret: clientSecret,
refresh_token: sessionData.refreshToken
}).toString()
}) as any
console.log('[REFRESH] Token refresh successful:', {
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'
})
}
})