111 lines
3.3 KiB
TypeScript
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'
|
|
})
|
|
}
|
|
})
|