Neah/app/api/keycloak/token/route.ts
2025-05-02 11:41:43 +02:00

123 lines
3.2 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { getServerSession } from "next-auth/next";
import { authOptions } from "../../auth/[...nextauth]/route";
/**
* Handler for getting a Keycloak admin token
* This replaces the previous proxy implementation
*/
export async function GET(request: NextRequest) {
const session = await getServerSession(authOptions);
// Check authentication
if (!session || !session.user) {
return NextResponse.json(
{ error: "Unauthorized" },
{ status: 401 }
);
}
// Check if user has admin role
const isAdmin = session.user.role?.includes('admin');
if (!isAdmin) {
return NextResponse.json(
{ error: "Forbidden: Admin role required" },
{ status: 403 }
);
}
try {
// Get admin token
const tokenResponse = await fetch(
`${process.env.KEYCLOAK_ISSUER}/protocol/openid-connect/token`,
{
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
grant_type: "client_credentials",
client_id: process.env.KEYCLOAK_CLIENT_ID!,
client_secret: process.env.KEYCLOAK_CLIENT_SECRET!,
}),
}
);
const data = await tokenResponse.json();
if (!tokenResponse.ok || !data.access_token) {
console.error("Token Error:", data);
return NextResponse.json(
{ error: "Failed to get admin token" },
{ status: 500 }
);
}
// Return the token
return NextResponse.json({
access_token: data.access_token,
expires_in: data.expires_in,
token_type: data.token_type
});
} catch (error) {
console.error("Token Error:", error);
return NextResponse.json(
{ error: "Server error obtaining token" },
{ status: 500 }
);
}
}
/**
* Handle refreshing a token
*/
export async function POST(request: NextRequest) {
try {
const { refresh_token } = await request.json();
if (!refresh_token) {
return NextResponse.json(
{ error: "Refresh token is required" },
{ status: 400 }
);
}
const response = await fetch(
`${process.env.KEYCLOAK_ISSUER}/protocol/openid-connect/token`,
{
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
client_id: process.env.KEYCLOAK_CLIENT_ID!,
client_secret: process.env.KEYCLOAK_CLIENT_SECRET!,
grant_type: "refresh_token",
refresh_token: refresh_token,
}),
}
);
const data = await response.json();
if (!response.ok) {
return NextResponse.json(
{ error: "Token refresh failed", details: data },
{ status: response.status }
);
}
return NextResponse.json({
access_token: data.access_token,
refresh_token: data.refresh_token,
expires_in: data.expires_in,
token_type: data.token_type
});
} catch (error) {
console.error("Token refresh error:", error);
return NextResponse.json(
{ error: "Server error refreshing token" },
{ status: 500 }
);
}
}