auth flow
This commit is contained in:
parent
279a5a34ab
commit
44f278b7ab
@ -13,6 +13,8 @@ async function getUserTokenForRocketChat(email: string) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(`Authenticating with Rocket.Chat at ${baseUrl} for user ${email}`);
|
||||||
|
|
||||||
// Admin headers for Rocket.Chat API
|
// Admin headers for Rocket.Chat API
|
||||||
const adminHeaders = {
|
const adminHeaders = {
|
||||||
'X-Auth-Token': process.env.ROCKET_CHAT_TOKEN!,
|
'X-Auth-Token': process.env.ROCKET_CHAT_TOKEN!,
|
||||||
@ -22,6 +24,7 @@ async function getUserTokenForRocketChat(email: string) {
|
|||||||
|
|
||||||
// Get the username from email
|
// Get the username from email
|
||||||
const username = email.split('@')[0];
|
const username = email.split('@')[0];
|
||||||
|
console.log(`Derived username: ${username}`);
|
||||||
|
|
||||||
// Get all users to find the current user
|
// Get all users to find the current user
|
||||||
const usersResponse = await fetch(`${baseUrl}/api/v1/users.list`, {
|
const usersResponse = await fetch(`${baseUrl}/api/v1/users.list`, {
|
||||||
@ -30,22 +33,42 @@ async function getUserTokenForRocketChat(email: string) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!usersResponse.ok) {
|
if (!usersResponse.ok) {
|
||||||
console.error('Failed to get users list:', usersResponse.status);
|
console.error(`Failed to get users list: ${usersResponse.status}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const usersData = await usersResponse.json();
|
const usersData = await usersResponse.json();
|
||||||
|
console.log(`Retrieved ${usersData.users?.length || 0} users from Rocket.Chat`);
|
||||||
|
|
||||||
// Find the current user in the list
|
// Find the current user in the list - FIX: properly check email address
|
||||||
const currentUser = usersData.users.find((user: any) =>
|
const currentUser = usersData.users.find((user: any) => {
|
||||||
user.username === username || user.emails?.some((email: any) => email.address === email)
|
// 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) {
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(`Found user in Rocket.Chat: ${currentUser.username} (${currentUser._id})`);
|
||||||
|
|
||||||
// Create a token for the current user
|
// Create a token for the current user
|
||||||
const createTokenResponse = await fetch(`${baseUrl}/api/v1/users.createToken`, {
|
const createTokenResponse = await fetch(`${baseUrl}/api/v1/users.createToken`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -56,11 +79,14 @@ async function getUserTokenForRocketChat(email: string) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!createTokenResponse.ok) {
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tokenData = await createTokenResponse.json();
|
const tokenData = await createTokenResponse.json();
|
||||||
|
console.log('Successfully created Rocket.Chat token');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
authToken: tokenData.data.authToken,
|
authToken: tokenData.data.authToken,
|
||||||
@ -81,16 +107,16 @@ export async function GET(request: NextRequest) {
|
|||||||
return NextResponse.json({ error: 'User not authenticated' }, { status: 401 });
|
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
|
// Get a token for Rocket.Chat
|
||||||
const rocketChatTokens = await getUserTokenForRocketChat(session.user.email);
|
const rocketChatTokens = await getUserTokenForRocketChat(userEmail);
|
||||||
|
|
||||||
if (!rocketChatTokens) {
|
if (!rocketChatTokens) {
|
||||||
return NextResponse.json({ error: 'Failed to obtain Rocket.Chat tokens' }, { status: 500 });
|
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 the tokens to the client
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
success: true,
|
success: true,
|
||||||
|
|||||||
@ -22,11 +22,14 @@ function isRocketChat(serviceName: string): boolean {
|
|||||||
|
|
||||||
export async function GET(
|
export async function GET(
|
||||||
request: NextRequest,
|
request: NextRequest,
|
||||||
{ params }: { params: { path: string[] } }
|
context: { params: { path: string[] } }
|
||||||
) {
|
) {
|
||||||
// Get the service prefix (first part of the path)
|
// Get the service prefix (first part of the path)
|
||||||
const serviceName = params.path[0];
|
const paramsObj = await Promise.resolve(context.params);
|
||||||
const restOfPath = params.path.slice(1).join('/');
|
const pathArray = await Promise.resolve(paramsObj.path);
|
||||||
|
|
||||||
|
const serviceName = pathArray[0];
|
||||||
|
const restOfPath = pathArray.slice(1).join('/');
|
||||||
|
|
||||||
// Get the base URL for this service
|
// Get the base URL for this service
|
||||||
const baseUrl = SERVICE_URLS[serviceName];
|
const baseUrl = SERVICE_URLS[serviceName];
|
||||||
@ -95,10 +98,14 @@ export async function GET(
|
|||||||
|
|
||||||
export async function POST(
|
export async function POST(
|
||||||
request: NextRequest,
|
request: NextRequest,
|
||||||
{ params }: { params: { path: string[] } }
|
context: { params: { path: string[] } }
|
||||||
) {
|
) {
|
||||||
const serviceName = params.path[0];
|
// Get the service prefix (first part of the path)
|
||||||
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('/');
|
||||||
|
|
||||||
const baseUrl = SERVICE_URLS[serviceName];
|
const baseUrl = SERVICE_URLS[serviceName];
|
||||||
if (!baseUrl) {
|
if (!baseUrl) {
|
||||||
|
|||||||
@ -6,27 +6,48 @@ import { useSession } from 'next-auth/react';
|
|||||||
export function RocketChatAuth() {
|
export function RocketChatAuth() {
|
||||||
const { data: session } = useSession();
|
const { data: session } = useSession();
|
||||||
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
||||||
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function authenticateWithRocketChat() {
|
async function authenticateWithRocketChat() {
|
||||||
if (!session?.user?.email) return;
|
if (!session?.user?.email) {
|
||||||
|
setError('No user session available');
|
||||||
try {
|
|
||||||
// Call our API to get Rocket.Chat tokens
|
|
||||||
const response = await fetch('/api/auth/rocket-login');
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
console.error('Failed to authenticate with Rocket.Chat');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
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:', responseText);
|
||||||
|
setError(`Failed to authenticate: ${response.status} ${response.statusText}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the JSON now that we've read the text
|
||||||
|
const data = JSON.parse(responseText);
|
||||||
|
|
||||||
if (data.rocketChatToken && data.rocketChatUserId) {
|
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
|
// 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=/; domain=${domain}; SameSite=None; Secure`;
|
||||||
document.cookie = `rc_token=${data.rocketChatToken}; path=/; SameSite=None; Secure`;
|
document.cookie = `rc_uid=${data.rocketChatUserId}; path=/; domain=${domain}; SameSite=None; Secure`;
|
||||||
document.cookie = `rc_uid=${data.rocketChatUserId}; path=/; SameSite=None; Secure`;
|
|
||||||
|
|
||||||
// Also store in localStorage which Rocket.Chat might check
|
// Also store in localStorage which Rocket.Chat might check
|
||||||
localStorage.setItem('Meteor.loginToken', data.rocketChatToken);
|
localStorage.setItem('Meteor.loginToken', data.rocketChatToken);
|
||||||
@ -34,17 +55,28 @@ export function RocketChatAuth() {
|
|||||||
|
|
||||||
console.log('Successfully authenticated with Rocket.Chat');
|
console.log('Successfully authenticated with Rocket.Chat');
|
||||||
setIsAuthenticated(true);
|
setIsAuthenticated(true);
|
||||||
|
setError(null);
|
||||||
|
} else {
|
||||||
|
setError('Received invalid response from authentication API');
|
||||||
|
console.error('Invalid response data:', data);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} 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();
|
authenticateWithRocketChat();
|
||||||
}, [session]);
|
}, [session]);
|
||||||
|
|
||||||
// This component doesn't render anything visible
|
// This component doesn't render visible UI by default
|
||||||
return null;
|
return error ? (
|
||||||
|
<div className="fixed bottom-4 right-4 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded z-50" role="alert">
|
||||||
|
<strong className="font-bold">Authentication Error: </strong>
|
||||||
|
<span className="block sm:inline">{error}</span>
|
||||||
|
</div>
|
||||||
|
) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default RocketChatAuth;
|
export default RocketChatAuth;
|
||||||
Loading…
Reference in New Issue
Block a user