105 lines
3.0 KiB
TypeScript
105 lines
3.0 KiB
TypeScript
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<KcAdminClient> {
|
|
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;
|
|
}
|
|
}
|