diff --git a/app/api/users/[userId]/route.ts b/app/api/users/[userId]/route.ts index 38fc6da2..7758918c 100644 --- a/app/api/users/[userId]/route.ts +++ b/app/api/users/[userId]/route.ts @@ -125,6 +125,7 @@ export async function DELETE( { params }: { params: { userId: string } } ) { const session = await getServerSession(authOptions); + const userId = params.userId; // Store userId from params to avoid sync access issues if (!session) { return NextResponse.json({ error: "Non autorisé" }, { status: 401 }); @@ -155,7 +156,7 @@ export async function DELETE( // Get user details before deletion const userResponse = await fetch( - `${process.env.KEYCLOAK_BASE_URL}/admin/realms/${process.env.KEYCLOAK_REALM}/users/${params.userId}`, + `${process.env.KEYCLOAK_BASE_URL}/admin/realms/${process.env.KEYCLOAK_REALM}/users/${userId}`, { headers: { Authorization: `Bearer ${tokenData.access_token}`, @@ -172,12 +173,12 @@ export async function DELETE( } const userDetails = await userResponse.json(); - console.log('Processing user deletion for ID:', params.userId); + console.log('Processing user deletion for ID:', userId); // Forward the request to the new endpoint format with the email parameter // This ensures Dolibarr deletion is also handled const apiUrl = new URL(`${req.headers.get('origin') || process.env.NEXTAUTH_URL}/api/users`); - apiUrl.searchParams.append('id', params.userId); + apiUrl.searchParams.append('id', userId); apiUrl.searchParams.append('email', userDetails.email); const forwardResponse = await fetch(apiUrl.toString(), { diff --git a/app/api/users/route.ts b/app/api/users/route.ts index 06947784..475c5f2f 100644 --- a/app/api/users/route.ts +++ b/app/api/users/route.ts @@ -545,9 +545,68 @@ export async function POST(req: Request) { } } +// Helper function to get Leantime user ID by email +async function getLeantimeUserId(email: string): Promise { + try { + // Validate email format + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + if (!emailRegex.test(email)) { + console.error('Invalid email format'); + return null; + } + + // Get user by email using the proper method + const userResponse = await fetch('https://agilite.slm-lab.net/api/jsonrpc', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-API-Key': process.env.LEANTIME_TOKEN || '', + }, + body: JSON.stringify({ + method: 'leantime.rpc.Users.Users.getUserByEmail', + jsonrpc: '2.0', + id: 1, + params: { + email: email + } + }) + }); + + const userData = await userResponse.json(); + + console.log('Leantime user lookup response status:', userResponse.status); + + if (!userResponse.ok || !userData.result) { + console.error('Failed to get Leantime user'); + return null; + } + + // The result should be the user object or false + if (userData.result === false) { + return null; + } + + return userData.result.id; + } catch (error) { + console.error('Error getting Leantime user'); + return null; + } +} + // Helper function to delete user from Leantime async function deleteLeantimeUser(email: string): Promise<{ success: boolean; error?: string }> { try { + // First get the Leantime user ID + const leantimeUserId = await getLeantimeUserId(email); + if (!leantimeUserId) { + return { + success: false, + error: 'User not found in Leantime' + }; + } + + console.log(`Found Leantime user with ID: ${leantimeUserId}, proceeding with deletion`); + const response = await fetch('https://agilite.slm-lab.net/api/jsonrpc', { method: 'POST', headers: { @@ -559,7 +618,7 @@ async function deleteLeantimeUser(email: string): Promise<{ success: boolean; er jsonrpc: '2.0', id: 1, params: { - email: email + id: leantimeUserId } }) });