From d40811a1e8fc6558e9195186376191c18b50b181 Mon Sep 17 00:00:00 2001 From: alma Date: Sat, 3 May 2025 15:48:12 +0200 Subject: [PATCH] equipes keycloak flow --- app/api/users/[userId]/roles/route.ts | 60 ++++++++++++++++++++++----- lib/keycloak.ts | 12 +++++- 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/app/api/users/[userId]/roles/route.ts b/app/api/users/[userId]/roles/route.ts index 2ad78746..c55a6f6d 100644 --- a/app/api/users/[userId]/roles/route.ts +++ b/app/api/users/[userId]/roles/route.ts @@ -5,7 +5,7 @@ import { getKeycloakAdminClient } from "@/lib/keycloak"; export async function GET( request: Request, - { params }: { params: { userId: string } } + context: { params: { userId: string } } ) { try { const session = await getServerSession(authOptions); @@ -13,16 +13,36 @@ export async function GET( return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } - // Handle params correctly for Next.js App Router - // Convert to string primitive to avoid "used `params.userId`" error - const userIdParam = params.userId; - const userId = String(userIdParam); + // Use the userId from context instead of trying to destructure it + const userId = context.params.userId.toString(); if (!userId) { return NextResponse.json({ error: "User ID is required" }, { status: 400 }); } try { + // Check for required environment variables before attempting to connect + const missingVars = []; + if (!process.env.KEYCLOAK_BASE_URL && !process.env.KEYCLOAK_ISSUER && !process.env.NEXT_PUBLIC_KEYCLOAK_ISSUER) { + missingVars.push('KEYCLOAK_BASE_URL or KEYCLOAK_ISSUER'); + } + if (!process.env.KEYCLOAK_ADMIN_CLIENT_ID) missingVars.push('KEYCLOAK_ADMIN_CLIENT_ID'); + if (!process.env.KEYCLOAK_ADMIN_USERNAME) missingVars.push('KEYCLOAK_ADMIN_USERNAME'); + if (!process.env.KEYCLOAK_ADMIN_PASSWORD) missingVars.push('KEYCLOAK_ADMIN_PASSWORD'); + if (!process.env.KEYCLOAK_REALM) missingVars.push('KEYCLOAK_REALM'); + + if (missingVars.length > 0) { + console.error(`Missing Keycloak environment variables: ${missingVars.join(', ')}`); + return NextResponse.json( + { + error: "Keycloak configuration incomplete", + message: "Role management is currently unavailable due to missing configuration.", + details: `Missing: ${missingVars.join(', ')}` + }, + { status: 503 } + ); + } + const kcAdminClient = await getKeycloakAdminClient(); // Get all available roles @@ -55,7 +75,7 @@ export async function GET( export async function PUT( request: Request, - { params }: { params: { userId: string } } + context: { params: { userId: string } } ) { try { const session = await getServerSession(authOptions); @@ -63,16 +83,36 @@ export async function PUT( return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } - // Handle params correctly for Next.js App Router - // Convert to string primitive to avoid "used `params.userId`" error - const userIdParam = params.userId; - const userId = String(userIdParam); + // Use the userId from context instead of trying to destructure it + const userId = context.params.userId.toString(); if (!userId) { return NextResponse.json({ error: "User ID is required" }, { status: 400 }); } try { + // Check for required environment variables before attempting to connect + const missingVars = []; + if (!process.env.KEYCLOAK_BASE_URL && !process.env.KEYCLOAK_ISSUER && !process.env.NEXT_PUBLIC_KEYCLOAK_ISSUER) { + missingVars.push('KEYCLOAK_BASE_URL or KEYCLOAK_ISSUER'); + } + if (!process.env.KEYCLOAK_ADMIN_CLIENT_ID) missingVars.push('KEYCLOAK_ADMIN_CLIENT_ID'); + if (!process.env.KEYCLOAK_ADMIN_USERNAME) missingVars.push('KEYCLOAK_ADMIN_USERNAME'); + if (!process.env.KEYCLOAK_ADMIN_PASSWORD) missingVars.push('KEYCLOAK_ADMIN_PASSWORD'); + if (!process.env.KEYCLOAK_REALM) missingVars.push('KEYCLOAK_REALM'); + + if (missingVars.length > 0) { + console.error(`Missing Keycloak environment variables: ${missingVars.join(', ')}`); + return NextResponse.json( + { + error: "Keycloak configuration incomplete", + message: "Role management is currently unavailable due to missing configuration.", + details: `Missing: ${missingVars.join(', ')}` + }, + { status: 503 } + ); + } + const { roles } = await request.json(); const kcAdminClient = await getKeycloakAdminClient(); diff --git a/lib/keycloak.ts b/lib/keycloak.ts index 860e40f1..9ddb155e 100644 --- a/lib/keycloak.ts +++ b/lib/keycloak.ts @@ -30,11 +30,19 @@ export async function getKeycloakAdminClient(): Promise { // Validate required environment variables if (!keycloakUrl) { - throw new Error('Missing Keycloak URL. Please set KEYCLOAK_BASE_URL or KEYCLOAK_ISSUER or NEXT_PUBLIC_KEYCLOAK_ISSUER in your environment variables.'); + console.error('Missing Keycloak URL. Please add one of these to your .env file: KEYCLOAK_BASE_URL, KEYCLOAK_ISSUER, or NEXT_PUBLIC_KEYCLOAK_ISSUER'); + throw new Error('Missing Keycloak URL configuration'); } if (!adminClientId || !adminUsername || !adminPassword || !realmName) { - throw new Error('Missing Keycloak admin credentials. Please set KEYCLOAK_ADMIN_CLIENT_ID, KEYCLOAK_ADMIN_USERNAME, KEYCLOAK_ADMIN_PASSWORD, and KEYCLOAK_REALM in your environment variables.'); + const missing = []; + if (!adminClientId) missing.push('KEYCLOAK_ADMIN_CLIENT_ID'); + if (!adminUsername) missing.push('KEYCLOAK_ADMIN_USERNAME'); + if (!adminPassword) missing.push('KEYCLOAK_ADMIN_PASSWORD'); + if (!realmName) missing.push('KEYCLOAK_REALM'); + + console.error(`Missing Keycloak admin credentials in .env: ${missing.join(', ')}`); + throw new Error('Missing Keycloak admin credentials'); } console.log(`Connecting to Keycloak at ${keycloakUrl}, realm: ${realmName}`);