diff --git a/app/api/auth/rocket-login/route.ts b/app/api/auth/rocket-login/route.ts index 216ad7c5..8f53bbd2 100644 --- a/app/api/auth/rocket-login/route.ts +++ b/app/api/auth/rocket-login/route.ts @@ -13,6 +13,8 @@ async function getUserTokenForRocketChat(email: string) { return null; } + console.log(`Authenticating with Rocket.Chat at ${baseUrl} for user ${email}`); + // Admin headers for Rocket.Chat API const adminHeaders = { 'X-Auth-Token': process.env.ROCKET_CHAT_TOKEN!, @@ -22,6 +24,7 @@ async function getUserTokenForRocketChat(email: string) { // Get the username from email const username = email.split('@')[0]; + console.log(`Derived username: ${username}`); // Get all users to find the current user const usersResponse = await fetch(`${baseUrl}/api/v1/users.list`, { @@ -30,22 +33,42 @@ async function getUserTokenForRocketChat(email: string) { }); if (!usersResponse.ok) { - console.error('Failed to get users list:', usersResponse.status); + console.error(`Failed to get users list: ${usersResponse.status}`); return null; } const usersData = await usersResponse.json(); + console.log(`Retrieved ${usersData.users?.length || 0} users from Rocket.Chat`); - // Find the current user in the list - const currentUser = usersData.users.find((user: any) => - user.username === username || user.emails?.some((email: any) => email.address === email) - ); + // Find the current user in the list - FIX: properly check email address + const currentUser = usersData.users.find((user: any) => { + // Check username match + if (user.username === username) { + return true; + } + + // Check email match in emails array + if (user.emails && Array.isArray(user.emails)) { + return user.emails.some((emailObj: any) => emailObj.address === email); + } + + return false; + }); if (!currentUser) { - console.error('User not found in Rocket.Chat users list'); + console.error(`User not found in Rocket.Chat users list with username ${username} or email ${email}`); + // Try to log some users for debugging + const someUsers = usersData.users.slice(0, 3).map((u: any) => ({ + username: u.username, + emails: u.emails, + name: u.name + })); + console.log('Sample users:', JSON.stringify(someUsers)); return null; } + console.log(`Found user in Rocket.Chat: ${currentUser.username} (${currentUser._id})`); + // Create a token for the current user const createTokenResponse = await fetch(`${baseUrl}/api/v1/users.createToken`, { method: 'POST', @@ -56,11 +79,14 @@ async function getUserTokenForRocketChat(email: string) { }); if (!createTokenResponse.ok) { - console.error('Failed to create user token:', createTokenResponse.status); + console.error(`Failed to create user token: ${createTokenResponse.status}`); + const errorText = await createTokenResponse.text(); + console.error(`Error details: ${errorText}`); return null; } const tokenData = await createTokenResponse.json(); + console.log('Successfully created Rocket.Chat token'); return { authToken: tokenData.data.authToken, @@ -81,16 +107,16 @@ export async function GET(request: NextRequest) { return NextResponse.json({ error: 'User not authenticated' }, { status: 401 }); } + const userEmail = session.user.email; + console.log(`Processing Rocket.Chat login for user ${userEmail}`); + // Get a token for Rocket.Chat - const rocketChatTokens = await getUserTokenForRocketChat(session.user.email); + const rocketChatTokens = await getUserTokenForRocketChat(userEmail); if (!rocketChatTokens) { return NextResponse.json({ error: 'Failed to obtain Rocket.Chat tokens' }, { status: 500 }); } - // Now we have the tokens, but we can't update the session directly - // The client needs to make a new auth call to refresh its JWT tokens - // Return the tokens to the client return NextResponse.json({ success: true, diff --git a/app/api/proxy/[...path]/route.ts b/app/api/proxy/[...path]/route.ts index 183ea491..9dadb016 100644 --- a/app/api/proxy/[...path]/route.ts +++ b/app/api/proxy/[...path]/route.ts @@ -22,11 +22,14 @@ function isRocketChat(serviceName: string): boolean { export async function GET( request: NextRequest, - { params }: { params: { path: string[] } } + context: { params: { path: string[] } } ) { // Get the service prefix (first part of the path) - const serviceName = params.path[0]; - const restOfPath = params.path.slice(1).join('/'); + const paramsObj = await Promise.resolve(context.params); + const pathArray = await Promise.resolve(paramsObj.path); + + const serviceName = pathArray[0]; + const restOfPath = pathArray.slice(1).join('/'); // Get the base URL for this service const baseUrl = SERVICE_URLS[serviceName]; @@ -95,10 +98,14 @@ export async function GET( export async function POST( request: NextRequest, - { params }: { params: { path: string[] } } + context: { params: { path: string[] } } ) { - const serviceName = params.path[0]; - const restOfPath = params.path.slice(1).join('/'); + // Get the service prefix (first part of the path) + const paramsObj = await Promise.resolve(context.params); + const pathArray = await Promise.resolve(paramsObj.path); + + const serviceName = pathArray[0]; + const restOfPath = pathArray.slice(1).join('/'); const baseUrl = SERVICE_URLS[serviceName]; if (!baseUrl) { diff --git a/app/components/rocket-auth.tsx b/app/components/rocket-auth.tsx index d1f3fb32..04defe88 100644 --- a/app/components/rocket-auth.tsx +++ b/app/components/rocket-auth.tsx @@ -6,27 +6,48 @@ import { useSession } from 'next-auth/react'; export function RocketChatAuth() { const { data: session } = useSession(); const [isAuthenticated, setIsAuthenticated] = useState(false); + const [error, setError] = useState(null); useEffect(() => { async function authenticateWithRocketChat() { - if (!session?.user?.email) return; + if (!session?.user?.email) { + setError('No user session available'); + return; + } try { + console.log('Authenticating with Rocket.Chat for user:', session.user.email); + // Call our API to get Rocket.Chat tokens const response = await fetch('/api/auth/rocket-login'); + // Get the text response for debugging if there's an error + const responseText = await response.text(); + if (!response.ok) { - console.error('Failed to authenticate with Rocket.Chat'); + console.error('Failed to authenticate with Rocket.Chat:', responseText); + setError(`Failed to authenticate: ${response.status} ${response.statusText}`); return; } - const data = await response.json(); + // Parse the JSON now that we've read the text + const data = JSON.parse(responseText); if (data.rocketChatToken && data.rocketChatUserId) { + console.log('Received tokens from API:', { + hasToken: !!data.rocketChatToken, + hasUserId: !!data.rocketChatUserId + }); + + // Get the current hostname to set domain cookies properly + const hostname = window.location.hostname; + const domain = hostname.includes('localhost') ? 'localhost' : hostname; + + console.log(`Setting cookies for domain: ${domain}`); + // Store tokens in cookies that can be accessed by the Rocket.Chat iframe - // Note: These cookies need to have proper domain settings to be accessible - document.cookie = `rc_token=${data.rocketChatToken}; path=/; SameSite=None; Secure`; - document.cookie = `rc_uid=${data.rocketChatUserId}; path=/; SameSite=None; Secure`; + document.cookie = `rc_token=${data.rocketChatToken}; path=/; domain=${domain}; SameSite=None; Secure`; + document.cookie = `rc_uid=${data.rocketChatUserId}; path=/; domain=${domain}; SameSite=None; Secure`; // Also store in localStorage which Rocket.Chat might check localStorage.setItem('Meteor.loginToken', data.rocketChatToken); @@ -34,17 +55,28 @@ export function RocketChatAuth() { console.log('Successfully authenticated with Rocket.Chat'); setIsAuthenticated(true); + setError(null); + } else { + setError('Received invalid response from authentication API'); + console.error('Invalid response data:', data); } } catch (error) { - console.error('Error authenticating with Rocket.Chat:', error); + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + console.error('Error authenticating with Rocket.Chat:', errorMessage); + setError(`Error: ${errorMessage}`); } } authenticateWithRocketChat(); }, [session]); - // This component doesn't render anything visible - return null; + // This component doesn't render visible UI by default + return error ? ( +
+ Authentication Error: + {error} +
+ ) : null; } export default RocketChatAuth; \ No newline at end of file