NeahNew/app/api/auth/debug-keycloak/route.ts
2025-05-04 09:23:26 +02:00

113 lines
3.7 KiB
TypeScript

import { NextResponse } from 'next/server';
export async function GET() {
try {
// Get Keycloak URL
const keycloakUrl = process.env.KEYCLOAK_BASE_URL || process.env.KEYCLOAK_ISSUER || process.env.NEXT_PUBLIC_KEYCLOAK_ISSUER;
const clientId = process.env.KEYCLOAK_CLIENT_ID;
const clientSecret = process.env.KEYCLOAK_CLIENT_SECRET;
const adminUsername = process.env.KEYCLOAK_ADMIN_USERNAME;
const adminPassword = process.env.KEYCLOAK_ADMIN_PASSWORD;
const realm = process.env.KEYCLOAK_REALM;
// Log all relevant environment variables (without exposing secrets)
const envVars = {
hasKeycloakUrl: !!keycloakUrl,
keycloakUrl,
hasClientId: !!clientId,
clientId,
hasClientSecret: !!clientSecret,
hasAdminUsername: !!adminUsername,
hasAdminPassword: !!adminPassword,
realm,
};
if (!keycloakUrl) {
return NextResponse.json({
error: 'Missing Keycloak URL',
message: 'KEYCLOAK_BASE_URL, KEYCLOAK_ISSUER, or NEXT_PUBLIC_KEYCLOAK_ISSUER is required'
}, { status: 400 });
}
if (!clientId) {
return NextResponse.json({
error: 'Missing Client ID',
message: 'KEYCLOAK_CLIENT_ID is required'
}, { status: 400 });
}
if (!realm) {
return NextResponse.json({
error: 'Missing Realm',
message: 'KEYCLOAK_REALM is required'
}, { status: 400 });
}
console.log('Environment variables check:', envVars);
// Try direct authentication using the application realm, not master
const url = `${keycloakUrl}/realms/${realm}/protocol/openid-connect/token`;
const formData = new URLSearchParams();
// Try client credentials if available
if (clientSecret) {
formData.append('client_id', clientId);
formData.append('client_secret', clientSecret);
formData.append('grant_type', 'client_credentials');
console.log('Using client credentials flow');
}
// Fall back to password grant
else if (adminUsername && adminPassword) {
formData.append('client_id', clientId);
formData.append('username', adminUsername);
formData.append('password', adminPassword);
formData.append('grant_type', 'password');
console.log('Using password grant flow');
} else {
return NextResponse.json({
error: 'Missing authentication credentials',
message: 'Either client_secret or admin username/password is required'
}, { status: 400 });
}
console.log(`Testing authentication to: ${url}`);
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: formData,
});
console.log(`Response status: ${response.status}`);
const data = await response.json();
if (!response.ok) {
console.error('Authentication error:', data);
return NextResponse.json({
error: 'Authentication failed',
details: data,
requestedUrl: url,
clientId: clientId,
grantType: formData.get('grant_type')
}, { status: response.status });
}
// Success! Return sanitized token info (not the actual tokens)
return NextResponse.json({
success: true,
tokenType: data.token_type,
expiresIn: data.expires_in,
hasAccessToken: !!data.access_token,
hasRefreshToken: !!data.refresh_token,
});
} catch (error) {
console.error('Error testing Keycloak connection:', error);
return NextResponse.json({
error: 'Failed to test Keycloak connection',
message: error instanceof Error ? error.message : String(error)
}, { status: 500 });
}
}