import KcAdminClient from '@keycloak/keycloak-admin-client'; import { Credentials } from '@keycloak/keycloak-admin-client/lib/utils/auth'; // Cache the admin client to avoid creating a new one for each request let adminClient: KcAdminClient | null = null; /** * Get a Keycloak admin client instance * @returns KcAdminClient instance */ export async function getKeycloakAdminClient(): Promise { if (adminClient) { try { // Check if the token is still valid by making a simple request await adminClient.users.find({ max: 1 }); return adminClient; } catch (error) { // Token expired, create a new client console.log('Keycloak token expired, creating new admin client'); adminClient = null; } } const kcAdminClient = new KcAdminClient({ baseUrl: process.env.NEXT_PUBLIC_KEYCLOAK_ISSUER || 'http://localhost:8080', realmName: 'master', // Use master realm to manage other realms }); // Authenticate admin client await kcAdminClient.auth({ clientId: process.env.KEYCLOAK_ADMIN_CLIENT_ID || 'admin-cli', username: process.env.KEYCLOAK_ADMIN_USERNAME || 'admin', password: process.env.KEYCLOAK_ADMIN_PASSWORD || 'admin', grantType: 'password', } as Credentials); // Set the target realm to work with kcAdminClient.setConfig({ realmName: process.env.KEYCLOAK_REALM || 'cercle', }); // Cache the admin client adminClient = kcAdminClient; return kcAdminClient; } /** * Get a user by ID * @param userId - Keycloak user ID * @returns User representation or null if not found */ export async function getUserById(userId: string) { try { const kcAdminClient = await getKeycloakAdminClient(); return await kcAdminClient.users.findOne({ id: userId }); } catch (error) { console.error('Error getting user by ID:', error); return null; } } /** * Get a user by email * @param email - User email * @returns User representation or null if not found */ export async function getUserByEmail(email: string) { try { const kcAdminClient = await getKeycloakAdminClient(); const users = await kcAdminClient.users.find({ email: email }); return users?.[0] || null; } catch (error) { console.error('Error getting user by email:', error); return null; } } /** * Get all available roles in the realm * @returns Array of role representations */ export async function getAllRoles() { try { const kcAdminClient = await getKeycloakAdminClient(); return await kcAdminClient.roles.find(); } catch (error) { console.error('Error getting roles:', error); return []; } } /** * Get user roles for a specific user * @param userId - Keycloak user ID * @returns User role mappings */ export async function getUserRoles(userId: string) { try { const kcAdminClient = await getKeycloakAdminClient(); return await kcAdminClient.users.listRoleMappings({ id: userId }); } catch (error) { console.error('Error getting user roles:', error); return null; } }