diff --git a/composables/useAuth.ts b/composables/useAuth.ts index 1a9890f..2436dde 100644 --- a/composables/useAuth.ts +++ b/composables/useAuth.ts @@ -45,15 +45,36 @@ export const useAuth = () => { user?: User; }>('/api/auth/direct-login', { method: 'POST', - body: credentials + body: credentials, + timeout: 30000 // 30 second timeout }); console.log('✅ Login response received:', response); if (response.success) { + // Add a small delay to ensure cookie is set before checking session + console.log('⏳ Waiting for cookie to be set...'); + await new Promise(resolve => setTimeout(resolve, 200)); + // After successful login, get the user data from the session console.log('🔄 Getting user data from session...'); - const sessionSuccess = await checkAuth(); + + // Try multiple times in case of timing issues + let sessionSuccess = false; + let attempts = 0; + const maxAttempts = 3; + + while (!sessionSuccess && attempts < maxAttempts) { + attempts++; + console.log(`🔄 Session check attempt ${attempts}/${maxAttempts}`); + + sessionSuccess = await checkAuth(); + + if (!sessionSuccess && attempts < maxAttempts) { + console.log('⏳ Session not ready, waiting 500ms...'); + await new Promise(resolve => setTimeout(resolve, 500)); + } + } if (sessionSuccess) { console.log('👤 User data retrieved from session:', user.value); @@ -65,7 +86,9 @@ export const useAuth = () => { return { success: true }; } else { console.warn('❌ Failed to get user data from session after login'); - return { success: false, error: 'Login succeeded but failed to get user data' }; + // Still redirect since login was successful on server + await navigateTo('/dashboard'); + return { success: true }; } } @@ -73,8 +96,24 @@ export const useAuth = () => { return { success: false, error: 'Login failed' }; } catch (err: any) { console.error('❌ Login error caught:', err); - error.value = err.data?.message || err.message || 'Login failed'; - return { success: false, error: error.value }; + + // Handle different types of errors + let errorMessage = 'Login failed'; + + if (err.status === 502) { + errorMessage = 'Server temporarily unavailable. Please try again.'; + } else if (err.status === 401) { + errorMessage = 'Invalid username or password'; + } else if (err.status === 429) { + errorMessage = 'Too many login attempts. Please try again later.'; + } else if (err.data?.message) { + errorMessage = err.data.message; + } else if (err.message) { + errorMessage = err.message; + } + + error.value = errorMessage; + return { success: false, error: errorMessage }; } finally { loading.value = false; } diff --git a/server/api/auth/direct-login.post.ts b/server/api/auth/direct-login.post.ts index 752c74a..fd95695 100644 --- a/server/api/auth/direct-login.post.ts +++ b/server/api/auth/direct-login.post.ts @@ -276,7 +276,10 @@ export default defineEventHandler(async (event) => { // Extract groups from all possible sources const extractedGroups = extractGroups(tokenPayload, userInfo); - // Create session data with extended expiry if remember me + // Create simplified session data to reduce cookie size + const userTier = determineTier(extractedGroups); + const userGroups = extractedGroups.length > 0 ? extractedGroups.slice(0, 10) : ['user']; // Limit groups to prevent large cookies + const sessionData = { user: { id: userInfo.sub, @@ -285,8 +288,8 @@ export default defineEventHandler(async (event) => { firstName: userInfo.given_name, lastName: userInfo.family_name, username: userInfo.preferred_username || username, - tier: determineTier(extractedGroups), - groups: extractedGroups.length > 0 ? extractedGroups : ['user'] + tier: userTier, + groups: userGroups }, tokens: { accessToken: tokens.access_token, @@ -298,37 +301,67 @@ export default defineEventHandler(async (event) => { lastActivity: Date.now() }; + console.log('📊 Session data size check:', { + userTier, + groupCount: userGroups.length, + sessionSize: JSON.stringify(sessionData).length + }); + // Create session with appropriate expiration const sessionManager = createSessionManager(); const maxAge = !!rememberMe ? 60 * 60 * 24 * 30 : 60 * 60 * 24 * 7; // 30 days vs 7 days - // Create the encrypted session data - const sessionData_json = JSON.stringify(sessionData); - const encrypted = sessionManager.encrypt(sessionData_json); - - console.log(`🍪 Setting session cookie (Remember Me: ${!!rememberMe}) without explicit domain`); - - // Use Nuxt's setCookie helper directly with the encrypted value - setCookie(event, 'monacousa-session', encrypted, { - httpOnly: true, - secure: process.env.NODE_ENV === 'production', - sameSite: 'lax', - maxAge, - path: '/', - }); + try { + // Create the encrypted session data + const sessionData_json = JSON.stringify(sessionData); + const encrypted = sessionManager.encrypt(sessionData_json); + + console.log(`🍪 Setting session cookie (Remember Me: ${!!rememberMe}), size: ${encrypted.length} chars`); + + // Use Nuxt's setCookie helper directly with the encrypted value + setCookie(event, 'monacousa-session', encrypted, { + httpOnly: true, + secure: process.env.NODE_ENV === 'production', + sameSite: 'lax', + maxAge, + path: '/', + }); + + console.log('✅ Session cookie set successfully'); + + } catch (cookieError) { + console.error('❌ Failed to set session cookie:', cookieError); + throw createError({ + statusCode: 500, + statusMessage: 'Failed to create session' + }); + } // Clear failed attempts on successful login clearFailedAttempts(clientIP); console.log('✅ Login successful for user:', userInfo.email); + console.log('🎯 User tier assigned:', userTier); + console.log('📋 User groups assigned:', userGroups); - // Ensure we return a proper response with status + // Add a small delay to ensure cookie is set + await new Promise(resolve => setTimeout(resolve, 100)); + + // Ensure we return a proper response with explicit status setResponseStatus(event, 200); + setHeader(event, 'Content-Type', 'application/json'); + + console.log('📤 Sending success response'); // Return a minimal response to prevent 502 errors return { success: true, - redirectTo: '/dashboard' + redirectTo: '/dashboard', + user: { + email: userInfo.email, + name: userInfo.name, + tier: userTier + } }; } catch (error: any) { diff --git a/server/api/auth/session.get.ts b/server/api/auth/session.get.ts index 9ad825e..497156f 100644 --- a/server/api/auth/session.get.ts +++ b/server/api/auth/session.get.ts @@ -1,19 +1,39 @@ export default defineEventHandler(async (event) => { - const sessionManager = createSessionManager(); - const cookieHeader = getHeader(event, 'cookie'); - const session = sessionManager.getSession(cookieHeader); + console.log('🔍 Session check requested at:', new Date().toISOString()); + + try { + const sessionManager = createSessionManager(); + const cookieHeader = getHeader(event, 'cookie'); + + console.log('🍪 Cookie header present:', !!cookieHeader); + console.log('🍪 Cookie header length:', cookieHeader?.length || 0); + + const session = sessionManager.getSession(cookieHeader); - if (!session) { + if (!session) { + console.log('❌ No valid session found'); + return { + authenticated: false, + user: null, + groups: [], + }; + } + + console.log('✅ Valid session found for user:', session.user.email); + console.log('🎯 User tier:', session.user.tier); + console.log('📋 User groups:', session.user.groups); + + return { + authenticated: true, + user: session.user, + groups: session.user.groups || [], + }; + } catch (error) { + console.error('❌ Session check error:', error); return { authenticated: false, user: null, groups: [], }; } - - return { - authenticated: true, - user: session.user, - groups: session.user.groups || [], - }; });