From 858b252a7e4ad96260ec0d00075f8c93ba24b1f9 Mon Sep 17 00:00:00 2001 From: Matt Date: Thu, 7 Aug 2025 03:17:25 +0200 Subject: [PATCH] Add debug logging and cookie domain configuration to auth flow - Add comprehensive logging to login and callback endpoints for debugging - Configure cookie domain from environment variable for cross-subdomain support - Update cookie security settings based on NODE_ENV - Add Keycloak configuration validation with detailed error logging --- server/api/auth/callback.get.ts | 8 +++++ server/api/auth/login.get.ts | 52 ++++++++++++++++++++++++++------- server/utils/session.ts | 6 +++- 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/server/api/auth/callback.get.ts b/server/api/auth/callback.get.ts index 718638e..c6dd902 100644 --- a/server/api/auth/callback.get.ts +++ b/server/api/auth/callback.get.ts @@ -1,6 +1,14 @@ export default defineEventHandler(async (event) => { + console.log('🔄 Callback endpoint called at:', new Date().toISOString()); + const query = getQuery(event); const { code, state } = query; + + console.log('📝 Callback query params:', { + hasCode: !!code, + hasState: !!state, + state: state ? 'present' : 'missing' + }); if (!code || !state) { throw createError({ diff --git a/server/api/auth/login.get.ts b/server/api/auth/login.get.ts index cf6216b..0ff8566 100644 --- a/server/api/auth/login.get.ts +++ b/server/api/auth/login.get.ts @@ -1,17 +1,47 @@ import { randomBytes } from 'crypto'; export default defineEventHandler(async (event) => { - const keycloak = createKeycloakClient(); - const state = randomBytes(32).toString('hex'); + console.log('🔐 Login endpoint called at:', new Date().toISOString()); - // Store state in session for verification - setCookie(event, 'oauth-state', state, { - httpOnly: true, - secure: true, - maxAge: 600, // 10 minutes - }); + try { + const config = useRuntimeConfig(); + console.log('🔧 Keycloak config:', { + issuer: config.keycloak?.issuer || 'NOT SET', + clientId: config.keycloak?.clientId || 'NOT SET', + callbackUrl: config.keycloak?.callbackUrl || 'NOT SET', + hasSecret: !!config.keycloak?.clientSecret + }); - const authUrl = keycloak.getAuthUrl(state); - - return sendRedirect(event, authUrl); + if (!config.keycloak?.issuer || !config.keycloak?.clientId || !config.keycloak?.clientSecret) { + console.error('❌ Missing Keycloak configuration'); + throw createError({ + statusCode: 500, + statusMessage: 'Keycloak configuration is incomplete' + }); + } + + const keycloak = createKeycloakClient(); + const state = randomBytes(32).toString('hex'); + + // Get cookie domain from environment + const cookieDomain = process.env.COOKIE_DOMAIN || undefined; + console.log('🍪 Cookie domain:', cookieDomain); + + // Store state in session for verification + setCookie(event, 'oauth-state', state, { + httpOnly: true, + secure: process.env.NODE_ENV === 'production', + sameSite: 'lax', + domain: cookieDomain, + maxAge: 600, // 10 minutes + }); + + const authUrl = keycloak.getAuthUrl(state); + console.log('🔗 Redirecting to Keycloak:', authUrl); + + return sendRedirect(event, authUrl); + } catch (error) { + console.error('❌ Login error:', error); + throw error; + } }); diff --git a/server/utils/session.ts b/server/utils/session.ts index a6b5fef..7355495 100644 --- a/server/utils/session.ts +++ b/server/utils/session.ts @@ -31,10 +31,14 @@ export class SessionManager { const data = JSON.stringify(sessionData); const encrypted = this.encrypt(data); + const cookieDomain = process.env.COOKIE_DOMAIN || undefined; + console.log('🍪 Creating session cookie with domain:', cookieDomain); + return serialize(this.cookieName, encrypted, { httpOnly: true, - secure: true, + secure: process.env.NODE_ENV === 'production', sameSite: 'lax', + domain: cookieDomain, maxAge: 60 * 60 * 24 * 7, // 7 days path: '/', });