diff --git a/app/api/auth/[...nextauth]/route.ts b/app/api/auth/[...nextauth]/route.ts index 3f021614..9c03b7d5 100644 --- a/app/api/auth/[...nextauth]/route.ts +++ b/app/api/auth/[...nextauth]/route.ts @@ -34,6 +34,13 @@ export const authOptions: NextAuthOptions = { clientSecret: process.env.KEYCLOAK_CLIENT_SECRET!, issuer: process.env.KEYCLOAK_ISSUER!, profile(profile) { + // Filter out system roles and only keep valid user roles + const validRoles = (profile.groups || []) + .filter((role: string) => + !role.startsWith('default-roles-') && + !['offline_access', 'uma_authorization'].includes(role) + ); + return { id: profile.sub, name: profile.name ?? profile.preferred_username, @@ -41,7 +48,7 @@ export const authOptions: NextAuthOptions = { first_name: profile.given_name ?? '', last_name: profile.family_name ?? '', username: profile.preferred_username ?? profile.email?.split('@')[0] ?? '', - role: profile.groups ?? [], + role: validRoles, } }, }), @@ -52,7 +59,12 @@ export const authOptions: NextAuthOptions = { token.accessToken = account.access_token; token.refreshToken = account.refresh_token; token.accessTokenExpires = account.expires_at! * 1000; - token.role = (profile as any).groups ?? []; + // Filter roles consistently + token.role = (profile as any).groups + ?.filter((role: string) => + !role.startsWith('default-roles-') && + !['offline_access', 'uma_authorization'].includes(role) + ) ?? []; token.username = (profile as any).preferred_username ?? profile.email?.split('@')[0] ?? ''; token.first_name = (profile as any).given_name ?? ''; token.last_name = (profile as any).family_name ?? ''; diff --git a/app/api/rocket-chat/messages/route.ts b/app/api/rocket-chat/messages/route.ts index 3ff3ef6a..421460a3 100644 --- a/app/api/rocket-chat/messages/route.ts +++ b/app/api/rocket-chat/messages/route.ts @@ -2,10 +2,6 @@ import { getServerSession } from "next-auth"; import { authOptions } from "@/app/api/auth/[...nextauth]/route"; import { NextResponse } from "next/server"; -if (!process.env.ROCKET_CHAT_TOKEN || !process.env.ROCKET_CHAT_USER_ID) { - console.error('Missing Rocket.Chat credentials in environment variables'); -} - export async function GET() { try { const session = await getServerSession(authOptions); @@ -13,91 +9,21 @@ export async function GET() { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } - // Debug log to see all session data - console.log('Session data:', { - user: session.user, - accessToken: session.accessToken ? 'present' : 'missing' - }); + // Get the user's Rocket.Chat token from their session + const rocketChatToken = session.accessToken; + const rocketChatUserId = session.user.id; - if (!session.accessToken) { - return NextResponse.json({ error: "No access token found" }, { status: 401 }); + if (!rocketChatToken || !rocketChatUserId) { + return NextResponse.json({ error: "No Rocket.Chat credentials found" }, { status: 401 }); } - // First get the username from Keycloak - const keycloakResponse = await fetch( - `${process.env.KEYCLOAK_BASE_URL}/realms/${process.env.KEYCLOAK_REALM}/protocol/openid-connect/userinfo`, - { - headers: { - 'Authorization': `Bearer ${session.accessToken}` - } - } - ); - - if (!keycloakResponse.ok) { - console.error('Failed to get Keycloak user info:', { - status: keycloakResponse.status, - statusText: keycloakResponse.statusText, - response: await keycloakResponse.text().catch(() => 'Could not get response text') - }); - return NextResponse.json( - { error: "Failed to get user info from Keycloak" }, - { status: keycloakResponse.status } - ); - } - - const keycloakUser = await keycloakResponse.json(); - const username = keycloakUser.preferred_username; - - console.log('Keycloak user info:', { - username, - sub: keycloakUser.sub - }); - - if (!username) { - return NextResponse.json( - { error: "No username found in Keycloak user info" }, - { status: 400 } - ); - } - - // Get user info using personal access token - const userInfoResponse = await fetch( - `https://parole.slm-lab.net/api/v1/users.info?username=${username}`, - { - headers: { - 'X-Auth-Token': process.env.ROCKET_CHAT_TOKEN!, - 'X-User-Id': process.env.ROCKET_CHAT_USER_ID!, - 'Content-Type': 'application/json' - } - } - ); - - if (!userInfoResponse.ok) { - console.error('Failed to get user info:', { - status: userInfoResponse.status, - statusText: userInfoResponse.statusText, - headers: userInfoResponse.headers, - response: await userInfoResponse.text().catch(() => 'Could not get response text') - }); - return NextResponse.json( - { error: "Failed to get user info" }, - { status: userInfoResponse.status } - ); - } - - const userInfo = await userInfoResponse.json(); - console.log('User info success:', { - userId: userInfo.user._id, - username: userInfo.user.username - }); - // Get the user's subscriptions (rooms they are in) const subscriptionsResponse = await fetch( 'https://parole.slm-lab.net/api/v1/subscriptions.get', { headers: { - 'X-Auth-Token': process.env.ROCKET_CHAT_TOKEN!, - 'X-User-Id': userInfo.user._id, + 'X-Auth-Token': rocketChatToken, + 'X-User-Id': rocketChatUserId, 'Content-Type': 'application/json' } } @@ -146,8 +72,8 @@ export async function GET() { `https://parole.slm-lab.net/api/v1/${endpoint}?roomId=${subscription.rid}&count=1`, { headers: { - 'X-Auth-Token': process.env.ROCKET_CHAT_TOKEN!, - 'X-User-Id': process.env.ROCKET_CHAT_USER_ID!, + 'X-Auth-Token': rocketChatToken, + 'X-User-Id': rocketChatUserId, 'Content-Type': 'application/json' } }