94 lines
2.7 KiB
TypeScript
94 lines
2.7 KiB
TypeScript
// server/api/hak-akses/entities.get.ts
|
|
export default defineEventHandler(async (event) => {
|
|
console.log("📥 Fetching Keycloak entities (roles & groups)");
|
|
|
|
// Get session from session store
|
|
const { getSessionFromCookie } = await import('~/server/utils/sessionStore');
|
|
const session = await getSessionFromCookie(event);
|
|
|
|
if (!session) {
|
|
throw createError({
|
|
statusCode: 401,
|
|
statusMessage: "Session expired or not found",
|
|
});
|
|
}
|
|
|
|
const config = useRuntimeConfig();
|
|
const accessToken = session.accessToken;
|
|
|
|
if (!accessToken) {
|
|
throw createError({
|
|
statusCode: 401,
|
|
statusMessage: "No access token found in session",
|
|
});
|
|
}
|
|
|
|
try {
|
|
const issuerUrl = new URL(config.keycloakIssuer);
|
|
const realm = issuerUrl.pathname.split('/').filter(Boolean).pop() || 'master';
|
|
const adminBaseUrl = `${config.keycloakIssuer.replace('/realms/' + realm, '')}/admin/realms/${realm}`;
|
|
|
|
// 1. Fetch Realm Roles
|
|
const rolesResponse = await fetch(`${adminBaseUrl}/roles`, {
|
|
method: 'GET',
|
|
headers: {
|
|
'Authorization': `Bearer ${accessToken}`,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
});
|
|
|
|
if (!rolesResponse.ok) {
|
|
throw new Error(`Failed to fetch roles: ${rolesResponse.status}`);
|
|
}
|
|
|
|
const roles = await rolesResponse.json();
|
|
// Filter out potential client-specific roles if needed, keeping realm roles
|
|
const realmRoles = roles.filter((r: any) => !r.clientRole);
|
|
|
|
// 2. Fetch Groups
|
|
const groupsResponse = await fetch(`${adminBaseUrl}/groups`, {
|
|
method: 'GET',
|
|
headers: {
|
|
'Authorization': `Bearer ${accessToken}`,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
});
|
|
|
|
if (!groupsResponse.ok) {
|
|
throw new Error(`Failed to fetch groups: ${groupsResponse.status}`);
|
|
}
|
|
|
|
const groups = await groupsResponse.json();
|
|
|
|
// 3. For each role and group, we'll need to fetch members to show the count
|
|
// NOTE: This might be expensive if there are many roles/groups.
|
|
// For now, let's just return the list and we'll fetch members on demand in the UI or in a separate task.
|
|
// To be efficient, we'll only return basic info here.
|
|
|
|
return {
|
|
success: true,
|
|
data: {
|
|
roles: realmRoles.map((r: any) => ({
|
|
id: r.id,
|
|
name: r.name,
|
|
description: r.description || '',
|
|
type: 'role'
|
|
})),
|
|
groups: groups.map((g: any) => ({
|
|
id: g.id,
|
|
name: g.name,
|
|
path: g.path,
|
|
type: 'group'
|
|
}))
|
|
}
|
|
};
|
|
|
|
} catch (error: any) {
|
|
console.error("❌ Error fetching Keycloak entities:", error);
|
|
throw createError({
|
|
statusCode: 500,
|
|
statusMessage: error.message || "Failed to fetch Keycloak entities",
|
|
});
|
|
}
|
|
});
|