feat: improve login process with enhanced session handling and error management
Build And Push Image / docker (push) Successful in 2m55s Details

This commit is contained in:
Matt 2025-08-07 13:51:13 +02:00
parent 1b2ce79919
commit 98ef466022
3 changed files with 126 additions and 34 deletions

View File

@ -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;
}

View File

@ -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) {

View File

@ -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 || [],
};
});