mirror of
https://github.com/samanhappy/mcphub.git
synced 2026-01-01 20:28:42 -05:00
feat: Implement bearer token validation in auth middleware (#186)
This commit is contained in:
102
frontend/src/services/configService.ts
Normal file
102
frontend/src/services/configService.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { getApiUrl, getBasePath } from '../utils/runtime';
|
||||
|
||||
export interface SystemConfig {
|
||||
routing?: {
|
||||
enableGlobalRoute?: boolean;
|
||||
enableGroupNameRoute?: boolean;
|
||||
enableBearerAuth?: boolean;
|
||||
bearerAuthKey?: string;
|
||||
skipAuth?: boolean;
|
||||
};
|
||||
install?: {
|
||||
pythonIndexUrl?: string;
|
||||
npmRegistry?: string;
|
||||
};
|
||||
smartRouting?: {
|
||||
enabled?: boolean;
|
||||
dbUrl?: string;
|
||||
openaiApiBaseUrl?: string;
|
||||
openaiApiKey?: string;
|
||||
openaiApiEmbeddingModel?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface PublicConfigResponse {
|
||||
success: boolean;
|
||||
data?: {
|
||||
skipAuth?: boolean;
|
||||
};
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export interface SystemConfigResponse {
|
||||
success: boolean;
|
||||
data?: {
|
||||
systemConfig?: SystemConfig;
|
||||
};
|
||||
message?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get public configuration (skipAuth setting) without authentication
|
||||
*/
|
||||
export const getPublicConfig = async (): Promise<{ skipAuth: boolean }> => {
|
||||
try {
|
||||
const basePath = getBasePath();
|
||||
const response = await fetch(`${basePath}/public-config`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data: PublicConfigResponse = await response.json();
|
||||
return { skipAuth: data.data?.skipAuth === true };
|
||||
}
|
||||
|
||||
return { skipAuth: false };
|
||||
} catch (error) {
|
||||
console.debug('Failed to get public config:', error);
|
||||
return { skipAuth: false };
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get system configuration without authentication
|
||||
* This function tries to get the system configuration first without auth,
|
||||
* and if that fails (likely due to auth requirements), it returns null
|
||||
*/
|
||||
export const getSystemConfigPublic = async (): Promise<SystemConfig | null> => {
|
||||
try {
|
||||
const response = await fetch(getApiUrl('/settings'), {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data: SystemConfigResponse = await response.json();
|
||||
return data.data?.systemConfig || null;
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.debug('Failed to get system config without auth:', error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if authentication should be skipped based on system configuration
|
||||
*/
|
||||
export const shouldSkipAuth = async (): Promise<boolean> => {
|
||||
try {
|
||||
const config = await getPublicConfig();
|
||||
return config.skipAuth;
|
||||
} catch (error) {
|
||||
console.debug('Failed to check skipAuth setting:', error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -15,13 +15,9 @@ export const fetchLogs = async (): Promise<LogEntry[]> => {
|
||||
try {
|
||||
// Get authentication token
|
||||
const token = getToken();
|
||||
if (!token) {
|
||||
throw new Error('Authentication token not found. Please log in.');
|
||||
}
|
||||
|
||||
const response = await fetch(getApiUrl('/logs'), {
|
||||
headers: {
|
||||
'x-auth-token': token,
|
||||
'x-auth-token': token || '',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -43,14 +39,10 @@ export const clearLogs = async (): Promise<void> => {
|
||||
try {
|
||||
// Get authentication token
|
||||
const token = getToken();
|
||||
if (!token) {
|
||||
throw new Error('Authentication token not found. Please log in.');
|
||||
}
|
||||
|
||||
const response = await fetch(getApiUrl('/logs'), {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'x-auth-token': token,
|
||||
'x-auth-token': token || '',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -84,12 +76,6 @@ export const useLogs = () => {
|
||||
|
||||
// Get the authentication token
|
||||
const token = getToken();
|
||||
if (!token) {
|
||||
setError(new Error('Authentication token not found. Please log in.'));
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Connect to SSE endpoint with auth token in URL
|
||||
eventSource = new EventSource(getApiUrl(`/logs/stream?token=${token}`));
|
||||
|
||||
|
||||
@@ -26,10 +26,6 @@ export const callTool = async (
|
||||
): Promise<ToolCallResult> => {
|
||||
try {
|
||||
const token = getToken();
|
||||
if (!token) {
|
||||
throw new Error('Authentication token not found. Please log in.');
|
||||
}
|
||||
|
||||
// Construct the URL with optional server parameter
|
||||
const url = server ? `/tools/call/${server}` : '/tools/call';
|
||||
|
||||
@@ -37,7 +33,7 @@ export const callTool = async (
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'x-auth-token': token,
|
||||
'x-auth-token': token || '', // Include token for authentication
|
||||
Authorization: `Bearer ${token}`, // Add bearer auth for MCP routing
|
||||
},
|
||||
body: JSON.stringify({
|
||||
@@ -81,15 +77,11 @@ export const toggleTool = async (
|
||||
): Promise<{ success: boolean; error?: string }> => {
|
||||
try {
|
||||
const token = getToken();
|
||||
if (!token) {
|
||||
throw new Error('Authentication token not found. Please log in.');
|
||||
}
|
||||
|
||||
const response = await fetch(getApiUrl(`/servers/${serverName}/tools/${toolName}/toggle`), {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'x-auth-token': token,
|
||||
'x-auth-token': token || '',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
body: JSON.stringify({ enabled }),
|
||||
@@ -123,18 +115,14 @@ export const updateToolDescription = async (
|
||||
): Promise<{ success: boolean; error?: string }> => {
|
||||
try {
|
||||
const token = getToken();
|
||||
if (!token) {
|
||||
throw new Error('Authentication token not found. Please log in.');
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
getApiUrl(`/servers/${serverName}/tools/${toolName}/description`),
|
||||
{
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'x-auth-token': token,
|
||||
Authorization: `Bearer ${token}`,
|
||||
'x-auth-token': token || '',
|
||||
Authorization: `Bearer ${token || ''}`,
|
||||
},
|
||||
body: JSON.stringify({ description }),
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user