monacousa-portal/server/api/members/[id]/keycloak-groups.get.ts

125 lines
4.2 KiB
TypeScript

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'
});
}
});