Clean up authentication troubleshooting artifacts
All checks were successful
Build And Push Image / docker (push) Successful in 3m1s

- Remove debug files: debug-login.js, LOGIN_FIX_SUMMARY.md, CUSTOM_LOGIN_IMPLEMENTATION.md
- Remove sequential-thinking directory (temporary MCP setup)
- Clean up verbose console logging in auth middleware
- Reduce debug output in direct login API while keeping essential logs
- Streamline session management logging
- Update .gitignore to prevent future debug file commits
- Maintain essential error logging and security logs

All authentication functionality remains intact and working.
This commit is contained in:
2025-08-07 15:14:02 +02:00
parent 99772ab62c
commit 91cbffe189
12 changed files with 14 additions and 994 deletions

View File

@@ -83,18 +83,9 @@ const getClientIP = (event: any): string => {
};
export default defineEventHandler(async (event) => {
console.log('🔐 Direct login endpoint called at:', new Date().toISOString());
try {
const { username, password, rememberMe } = await readBody(event);
const clientIP = getClientIP(event) || 'unknown';
console.log('📝 Login attempt:', {
username: username ? 'present' : 'missing',
hasPassword: !!password,
rememberMe,
ip: clientIP
});
// Input validation
const validationErrors = validateLoginInput(username, password);
@@ -127,11 +118,6 @@ export default defineEventHandler(async (event) => {
});
}
console.log('🔧 Using Keycloak config:', {
issuer: config.keycloak.issuer,
clientId: config.keycloak.clientId,
hasSecret: !!config.keycloak.clientSecret
});
// Direct authentication with Keycloak using Resource Owner Password Credentials flow
const tokenResponse = await fetch(`${config.keycloak.issuer}/protocol/openid-connect/token`, {
@@ -178,15 +164,13 @@ export default defineEventHandler(async (event) => {
}
const tokens = await tokenResponse.json();
console.log('✅ Token exchange successful');
// Decode the access token to see what's inside
// Decode the access token to extract user information
let tokenPayload = null;
try {
const tokenParts = tokens.access_token.split('.');
const payload = JSON.parse(Buffer.from(tokenParts[1], 'base64').toString());
tokenPayload = payload;
console.log('🔍 Access token payload:', JSON.stringify(payload, null, 2));
} catch (err) {
console.warn('⚠️ Could not decode access token:', err);
}
@@ -208,7 +192,6 @@ export default defineEventHandler(async (event) => {
}
const userInfo = await userResponse.json();
console.log('✅ User info retrieved:', JSON.stringify(userInfo, null, 2));
// Extract groups/roles from multiple possible locations
const extractGroups = (tokenPayload: any, userInfo: any): string[] => {
@@ -217,19 +200,16 @@ export default defineEventHandler(async (event) => {
// Check userInfo for groups (from userinfo endpoint)
if (userInfo.groups && Array.isArray(userInfo.groups)) {
allGroups.push(...userInfo.groups);
console.log('📋 Found groups in userInfo.groups:', userInfo.groups);
}
// Check userInfo for roles
if (userInfo.roles && Array.isArray(userInfo.roles)) {
allGroups.push(...userInfo.roles);
console.log('📋 Found roles in userInfo.roles:', userInfo.roles);
}
// Check token payload for realm_access.roles
if (tokenPayload?.realm_access?.roles && Array.isArray(tokenPayload.realm_access.roles)) {
allGroups.push(...tokenPayload.realm_access.roles);
console.log('📋 Found roles in token realm_access.roles:', tokenPayload.realm_access.roles);
}
// Check token payload for resource_access roles
@@ -238,7 +218,6 @@ export default defineEventHandler(async (event) => {
const clientRoles = tokenPayload.resource_access[clientId]?.roles;
if (clientRoles && Array.isArray(clientRoles)) {
allGroups.push(...clientRoles);
console.log(`📋 Found roles in token resource_access.${clientId}.roles:`, clientRoles);
}
});
}
@@ -246,7 +225,6 @@ export default defineEventHandler(async (event) => {
// Check token payload for groups claim
if (tokenPayload?.groups && Array.isArray(tokenPayload.groups)) {
allGroups.push(...tokenPayload.groups);
console.log('📋 Found groups in token.groups:', tokenPayload.groups);
}
// Remove duplicates and filter out default Keycloak roles
@@ -254,22 +232,17 @@ export default defineEventHandler(async (event) => {
!['default-roles-monacousa', 'offline_access', 'uma_authorization'].includes(group)
);
console.log('📋 Final extracted groups:', uniqueGroups);
return uniqueGroups;
};
// Tier determination logic - admin > board > user priority
const determineTier = (groups: string[]): 'user' | 'board' | 'admin' => {
console.log('🎯 Determining tier from groups:', groups);
if (groups.includes('admin')) {
console.log('🎯 User has admin tier');
return 'admin';
}
if (groups.includes('board')) {
console.log('🎯 User has board tier');
return 'board';
}
console.log('🎯 User has default user tier');
return 'user'; // Default tier
};
@@ -301,12 +274,6 @@ 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 server-side storage
const sessionManager = createSessionManager();
@@ -318,9 +285,6 @@ export default defineEventHandler(async (event) => {
const cookieParts = cookieString.split(';')[0].split('=');
const sessionId = cookieParts[1];
console.log(`🍪 Setting session cookie (Remember Me: ${!!rememberMe}), session ID: ${sessionId.substring(0, 8)}...`);
console.log(`📏 Cookie size: ${sessionId.length} chars (much smaller!)`);
// Set the cookie using Nuxt's setCookie helper
const maxAge = !!rememberMe ? 60 * 60 * 24 * 30 : 60 * 60 * 24 * 7; // 30 days vs 7 days
setCookie(event, 'monacousa-session', sessionId, {
@@ -331,8 +295,6 @@ export default defineEventHandler(async (event) => {
path: '/',
});
console.log('✅ Session cookie set successfully');
} catch (cookieError) {
console.error('❌ Failed to set session cookie:', cookieError);
throw createError({
@@ -345,8 +307,6 @@ export default defineEventHandler(async (event) => {
clearFailedAttempts(clientIP);
console.log('✅ Login successful for user:', userInfo.email);
console.log('🎯 User tier assigned:', userTier);
console.log('📋 User groups assigned:', userGroups);
// Add a small delay to ensure cookie is set
await new Promise(resolve => setTimeout(resolve, 100));
@@ -355,8 +315,6 @@ export default defineEventHandler(async (event) => {
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,

View File

@@ -12,12 +12,16 @@ const sessionStore = new Map<string, {
// Cleanup expired sessions every 5 minutes
setInterval(() => {
const now = Date.now();
let cleanedCount = 0;
for (const [sessionId, session] of sessionStore.entries()) {
if (now > session.expiresAt) {
sessionStore.delete(sessionId);
console.log('🧹 Cleaned up expired session:', sessionId.substring(0, 8) + '...');
cleanedCount++;
}
}
if (cleanedCount > 0) {
console.log(`🧹 Cleaned up ${cleanedCount} expired sessions`);
}
}, 5 * 60 * 1000);
export class SessionManager {
@@ -43,9 +47,6 @@ export class SessionManager {
rememberMe
});
console.log(`🍪 Creating session cookie (Remember Me: ${rememberMe}) with session ID: ${sessionId.substring(0, 8)}...`);
console.log(`📊 Session store size: ${sessionStore.size} sessions`);
return serialize(this.cookieName, sessionId, {
httpOnly: true,
secure: true,
@@ -57,7 +58,6 @@ export class SessionManager {
getSession(cookieHeader?: string): SessionData | null {
if (!cookieHeader) {
console.log('❌ No cookie header provided');
return null;
}
@@ -65,21 +65,16 @@ export class SessionManager {
const sessionId = cookies[this.cookieName];
if (!sessionId) {
console.log('❌ No session cookie found');
return null;
}
console.log(`🔍 Looking up session: ${sessionId.substring(0, 8)}...`);
const sessionEntry = sessionStore.get(sessionId);
if (!sessionEntry) {
console.log('❌ Session not found in store');
return null;
}
// Check if session is expired
if (Date.now() > sessionEntry.expiresAt) {
console.log('❌ Session expired, removing from store');
sessionStore.delete(sessionId);
return null;
}
@@ -87,7 +82,6 @@ export class SessionManager {
// Update last activity
sessionEntry.data.lastActivity = Date.now();
console.log('✅ Session found and valid for user:', sessionEntry.data.user.email);
return sessionEntry.data;
}