export default defineEventHandler(async (event) => { console.log('[api/members/[id]/keycloak-groups.get] ========================='); console.log('[api/members/[id]/keycloak-groups.get] GET /api/members/:id/keycloak-groups - Get member Keycloak groups'); try { // Validate session and require admin privileges const sessionManager = createSessionManager(); const cookieHeader = getCookie(event, 'monacousa-session') ? getHeader(event, 'cookie') : undefined; const session = sessionManager.getSession(cookieHeader); if (!session?.user) { throw createError({ statusCode: 401, statusMessage: 'Authentication required' }); } // Require admin privileges for group management if (session.user.tier !== 'admin') { throw createError({ statusCode: 403, statusMessage: 'Admin privileges required' }); } console.log('[api/members/[id]/keycloak-groups.get] Authorized admin user:', session.user.email); // Get member ID from route parameter const memberId = getRouterParam(event, 'id'); if (!memberId) { throw createError({ statusCode: 400, statusMessage: 'Member ID is required' }); } console.log('[api/members/[id]/keycloak-groups.get] Processing member ID:', memberId); // 1. Get member data const { getMemberById } = await import('~/server/utils/nocodb'); const member = await getMemberById(memberId); if (!member) { throw createError({ statusCode: 404, statusMessage: 'Member not found' }); } // 2. Check if member has portal account if (!member.keycloak_id) { console.log('[api/members/[id]/keycloak-groups.get] Member has no portal account'); throw createError({ statusCode: 404, statusMessage: 'Member has no portal account' }); } console.log('[api/members/[id]/keycloak-groups.get] Found member with Keycloak ID:', member.keycloak_id); // 3. Get user's current groups from Keycloak const { createKeycloakAdminClient } = await import('~/server/utils/keycloak-admin'); const keycloakAdmin = createKeycloakAdminClient(); console.log('[api/members/[id]/keycloak-groups.get] Fetching user groups from Keycloak...'); const userGroups = await keycloakAdmin.getUserGroups(member.keycloak_id); // 4. Determine primary group (user/board/admin) const primaryGroups = userGroups.filter(g => ['user', 'board', 'admin'].includes(g.name || '')); const primaryGroup = primaryGroups.length > 0 ? primaryGroups[0].name : 'user'; console.log('[api/members/[id]/keycloak-groups.get] Primary group determined:', primaryGroup); console.log('[api/members/[id]/keycloak-groups.get] Total groups:', userGroups.length); // 5. Compare with database portal_group field const databaseGroup = member.portal_group || 'user'; const groupsInSync = primaryGroup === databaseGroup; console.log('[api/members/[id]/keycloak-groups.get] ✅ Successfully retrieved group information'); return { success: true, data: { member_id: memberId, keycloak_id: member.keycloak_id, primary_group: primaryGroup, database_group: databaseGroup, groups_in_sync: groupsInSync, all_groups: userGroups.map(g => ({ id: g.id, name: g.name, path: g.path })), primary_groups: primaryGroups.map(g => ({ id: g.id, name: g.name, path: g.path })) } }; } catch (error: any) { console.error('[api/members/[id]/keycloak-groups.get] ❌ Failed to get member groups:', error); // If it's already an HTTP error, re-throw it if (error.statusCode) { throw error; } // Handle specific Keycloak errors if (error.message?.includes('Failed to get user groups')) { throw createError({ statusCode: 500, statusMessage: 'Failed to retrieve user groups from Keycloak. Check service account permissions.' }); } // Otherwise, wrap it in a generic error throw createError({ statusCode: 500, statusMessage: error.message || 'Failed to get member Keycloak groups' }); } });