mirror of
https://github.com/samanhappy/mcphub.git
synced 2026-01-01 04:08:52 -05:00
Implement OAuth client and token management with settings updates (#464)
This commit is contained in:
@@ -1,658 +1,10 @@
|
||||
import { useState, useCallback, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ApiResponse } from '@/types';
|
||||
import { useToast } from '@/contexts/ToastContext';
|
||||
import { apiGet, apiPut } from '../utils/fetchInterceptor';
|
||||
|
||||
// Define types for the settings data
|
||||
interface RoutingConfig {
|
||||
enableGlobalRoute: boolean;
|
||||
enableGroupNameRoute: boolean;
|
||||
enableBearerAuth: boolean;
|
||||
bearerAuthKey: string;
|
||||
skipAuth: boolean;
|
||||
}
|
||||
|
||||
interface InstallConfig {
|
||||
pythonIndexUrl: string;
|
||||
npmRegistry: string;
|
||||
baseUrl: string;
|
||||
}
|
||||
|
||||
interface SmartRoutingConfig {
|
||||
enabled: boolean;
|
||||
dbUrl: string;
|
||||
openaiApiBaseUrl: string;
|
||||
openaiApiKey: string;
|
||||
openaiApiEmbeddingModel: string;
|
||||
}
|
||||
|
||||
interface MCPRouterConfig {
|
||||
apiKey: string;
|
||||
referer: string;
|
||||
title: string;
|
||||
baseUrl: string;
|
||||
}
|
||||
|
||||
interface OAuthServerConfig {
|
||||
enabled: boolean;
|
||||
accessTokenLifetime: number;
|
||||
refreshTokenLifetime: number;
|
||||
authorizationCodeLifetime: number;
|
||||
requireClientSecret: boolean;
|
||||
allowedScopes: string[];
|
||||
requireState: boolean;
|
||||
dynamicRegistration: {
|
||||
enabled: boolean;
|
||||
allowedGrantTypes: string[];
|
||||
requiresAuthentication: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
interface SystemSettings {
|
||||
systemConfig?: {
|
||||
routing?: RoutingConfig;
|
||||
install?: InstallConfig;
|
||||
smartRouting?: SmartRoutingConfig;
|
||||
mcpRouter?: MCPRouterConfig;
|
||||
nameSeparator?: string;
|
||||
oauthServer?: OAuthServerConfig;
|
||||
enableSessionRebuild?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
interface TempRoutingConfig {
|
||||
bearerAuthKey: string;
|
||||
}
|
||||
|
||||
const getDefaultOAuthServerConfig = (): OAuthServerConfig => ({
|
||||
enabled: true,
|
||||
accessTokenLifetime: 3600,
|
||||
refreshTokenLifetime: 1209600,
|
||||
authorizationCodeLifetime: 300,
|
||||
requireClientSecret: false,
|
||||
allowedScopes: ['read', 'write'],
|
||||
requireState: false,
|
||||
dynamicRegistration: {
|
||||
enabled: true,
|
||||
allowedGrantTypes: ['authorization_code', 'refresh_token'],
|
||||
requiresAuthentication: false,
|
||||
},
|
||||
});
|
||||
import { useSettings } from '@/contexts/SettingsContext';
|
||||
|
||||
/**
|
||||
* Hook that provides access to settings data via SettingsContext.
|
||||
* This hook is a thin wrapper around useSettings to maintain backward compatibility.
|
||||
* The actual data fetching happens once in SettingsProvider, avoiding duplicate API calls.
|
||||
*/
|
||||
export const useSettingsData = () => {
|
||||
const { t } = useTranslation();
|
||||
const { showToast } = useToast();
|
||||
|
||||
const [routingConfig, setRoutingConfig] = useState<RoutingConfig>({
|
||||
enableGlobalRoute: true,
|
||||
enableGroupNameRoute: true,
|
||||
enableBearerAuth: false,
|
||||
bearerAuthKey: '',
|
||||
skipAuth: false,
|
||||
});
|
||||
|
||||
const [tempRoutingConfig, setTempRoutingConfig] = useState<TempRoutingConfig>({
|
||||
bearerAuthKey: '',
|
||||
});
|
||||
|
||||
const [installConfig, setInstallConfig] = useState<InstallConfig>({
|
||||
pythonIndexUrl: '',
|
||||
npmRegistry: '',
|
||||
baseUrl: 'http://localhost:3000',
|
||||
});
|
||||
|
||||
const [smartRoutingConfig, setSmartRoutingConfig] = useState<SmartRoutingConfig>({
|
||||
enabled: false,
|
||||
dbUrl: '',
|
||||
openaiApiBaseUrl: '',
|
||||
openaiApiKey: '',
|
||||
openaiApiEmbeddingModel: '',
|
||||
});
|
||||
|
||||
const [mcpRouterConfig, setMCPRouterConfig] = useState<MCPRouterConfig>({
|
||||
apiKey: '',
|
||||
referer: 'https://www.mcphubx.com',
|
||||
title: 'MCPHub',
|
||||
baseUrl: 'https://api.mcprouter.to/v1',
|
||||
});
|
||||
|
||||
const [oauthServerConfig, setOAuthServerConfig] = useState<OAuthServerConfig>(
|
||||
getDefaultOAuthServerConfig(),
|
||||
);
|
||||
|
||||
const [nameSeparator, setNameSeparator] = useState<string>('-');
|
||||
const [enableSessionRebuild, setEnableSessionRebuild] = useState<boolean>(false);
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [refreshKey, setRefreshKey] = useState(0);
|
||||
|
||||
// Trigger a refresh of the settings data
|
||||
const triggerRefresh = useCallback(() => {
|
||||
setRefreshKey((prev) => prev + 1);
|
||||
}, []);
|
||||
|
||||
// Fetch current settings
|
||||
const fetchSettings = useCallback(async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const data: ApiResponse<SystemSettings> = await apiGet('/settings');
|
||||
|
||||
if (data.success && data.data?.systemConfig?.routing) {
|
||||
setRoutingConfig({
|
||||
enableGlobalRoute: data.data.systemConfig.routing.enableGlobalRoute ?? true,
|
||||
enableGroupNameRoute: data.data.systemConfig.routing.enableGroupNameRoute ?? true,
|
||||
enableBearerAuth: data.data.systemConfig.routing.enableBearerAuth ?? false,
|
||||
bearerAuthKey: data.data.systemConfig.routing.bearerAuthKey || '',
|
||||
skipAuth: data.data.systemConfig.routing.skipAuth ?? false,
|
||||
});
|
||||
}
|
||||
if (data.success && data.data?.systemConfig?.install) {
|
||||
setInstallConfig({
|
||||
pythonIndexUrl: data.data.systemConfig.install.pythonIndexUrl || '',
|
||||
npmRegistry: data.data.systemConfig.install.npmRegistry || '',
|
||||
baseUrl: data.data.systemConfig.install.baseUrl || 'http://localhost:3000',
|
||||
});
|
||||
}
|
||||
if (data.success && data.data?.systemConfig?.smartRouting) {
|
||||
setSmartRoutingConfig({
|
||||
enabled: data.data.systemConfig.smartRouting.enabled ?? false,
|
||||
dbUrl: data.data.systemConfig.smartRouting.dbUrl || '',
|
||||
openaiApiBaseUrl: data.data.systemConfig.smartRouting.openaiApiBaseUrl || '',
|
||||
openaiApiKey: data.data.systemConfig.smartRouting.openaiApiKey || '',
|
||||
openaiApiEmbeddingModel:
|
||||
data.data.systemConfig.smartRouting.openaiApiEmbeddingModel || '',
|
||||
});
|
||||
}
|
||||
if (data.success && data.data?.systemConfig?.mcpRouter) {
|
||||
setMCPRouterConfig({
|
||||
apiKey: data.data.systemConfig.mcpRouter.apiKey || '',
|
||||
referer: data.data.systemConfig.mcpRouter.referer || 'https://www.mcphubx.com',
|
||||
title: data.data.systemConfig.mcpRouter.title || 'MCPHub',
|
||||
baseUrl: data.data.systemConfig.mcpRouter.baseUrl || 'https://api.mcprouter.to/v1',
|
||||
});
|
||||
}
|
||||
if (data.success) {
|
||||
if (data.data?.systemConfig?.oauthServer) {
|
||||
const oauth = data.data.systemConfig.oauthServer;
|
||||
const defaultOauthConfig = getDefaultOAuthServerConfig();
|
||||
const defaultDynamic = defaultOauthConfig.dynamicRegistration;
|
||||
const allowedScopes = Array.isArray(oauth.allowedScopes)
|
||||
? [...oauth.allowedScopes]
|
||||
: [...defaultOauthConfig.allowedScopes];
|
||||
const dynamicAllowedGrantTypes = Array.isArray(
|
||||
oauth.dynamicRegistration?.allowedGrantTypes,
|
||||
)
|
||||
? [...oauth.dynamicRegistration!.allowedGrantTypes!]
|
||||
: [...defaultDynamic.allowedGrantTypes];
|
||||
|
||||
setOAuthServerConfig({
|
||||
enabled: oauth.enabled ?? defaultOauthConfig.enabled,
|
||||
accessTokenLifetime:
|
||||
oauth.accessTokenLifetime ?? defaultOauthConfig.accessTokenLifetime,
|
||||
refreshTokenLifetime:
|
||||
oauth.refreshTokenLifetime ?? defaultOauthConfig.refreshTokenLifetime,
|
||||
authorizationCodeLifetime:
|
||||
oauth.authorizationCodeLifetime ?? defaultOauthConfig.authorizationCodeLifetime,
|
||||
requireClientSecret:
|
||||
oauth.requireClientSecret ?? defaultOauthConfig.requireClientSecret,
|
||||
requireState: oauth.requireState ?? defaultOauthConfig.requireState,
|
||||
allowedScopes,
|
||||
dynamicRegistration: {
|
||||
enabled: oauth.dynamicRegistration?.enabled ?? defaultDynamic.enabled,
|
||||
allowedGrantTypes: dynamicAllowedGrantTypes,
|
||||
requiresAuthentication:
|
||||
oauth.dynamicRegistration?.requiresAuthentication ??
|
||||
defaultDynamic.requiresAuthentication,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
setOAuthServerConfig(getDefaultOAuthServerConfig());
|
||||
}
|
||||
}
|
||||
if (data.success && data.data?.systemConfig?.nameSeparator !== undefined) {
|
||||
setNameSeparator(data.data.systemConfig.nameSeparator);
|
||||
}
|
||||
if (data.success && data.data?.systemConfig?.enableSessionRebuild !== undefined) {
|
||||
setEnableSessionRebuild(data.data.systemConfig.enableSessionRebuild);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch settings:', error);
|
||||
setError(error instanceof Error ? error.message : 'Failed to fetch settings');
|
||||
// 使用一个稳定的 showToast 引用,避免将其加入依赖数组
|
||||
showToast(t('errors.failedToFetchSettings'));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [t]); // 移除 showToast 依赖
|
||||
|
||||
// Update routing configuration
|
||||
const updateRoutingConfig = async (key: keyof RoutingConfig, value: any) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const data = await apiPut('/system-config', {
|
||||
routing: {
|
||||
[key]: value,
|
||||
},
|
||||
});
|
||||
|
||||
if (data.success) {
|
||||
setRoutingConfig({
|
||||
...routingConfig,
|
||||
[key]: value,
|
||||
});
|
||||
showToast(t('settings.systemConfigUpdated'));
|
||||
return true;
|
||||
} else {
|
||||
showToast(data.message || t('errors.failedToUpdateRouteConfig'));
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to update routing config:', error);
|
||||
setError(error instanceof Error ? error.message : 'Failed to update routing config');
|
||||
showToast(t('errors.failedToUpdateRouteConfig'));
|
||||
return false;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Update install configuration
|
||||
const updateInstallConfig = async (key: keyof InstallConfig, value: string) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const data = await apiPut('/system-config', {
|
||||
install: {
|
||||
[key]: value,
|
||||
},
|
||||
});
|
||||
|
||||
if (data.success) {
|
||||
setInstallConfig({
|
||||
...installConfig,
|
||||
[key]: value,
|
||||
});
|
||||
showToast(t('settings.systemConfigUpdated'));
|
||||
return true;
|
||||
} else {
|
||||
showToast(data.message || t('errors.failedToUpdateSystemConfig'));
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to update system config:', error);
|
||||
setError(error instanceof Error ? error.message : 'Failed to update system config');
|
||||
showToast(t('errors.failedToUpdateSystemConfig'));
|
||||
return false;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Update smart routing configuration
|
||||
const updateSmartRoutingConfig = async <T extends keyof SmartRoutingConfig>(
|
||||
key: T,
|
||||
value: SmartRoutingConfig[T],
|
||||
) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const data = await apiPut('/system-config', {
|
||||
smartRouting: {
|
||||
[key]: value,
|
||||
},
|
||||
});
|
||||
|
||||
if (data.success) {
|
||||
setSmartRoutingConfig({
|
||||
...smartRoutingConfig,
|
||||
[key]: value,
|
||||
});
|
||||
showToast(t('settings.systemConfigUpdated'));
|
||||
return true;
|
||||
} else {
|
||||
showToast(data.message || t('errors.failedToUpdateSmartRoutingConfig'));
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to update smart routing config:', error);
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : 'Failed to update smart routing config';
|
||||
setError(errorMessage);
|
||||
showToast(errorMessage);
|
||||
return false;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Update multiple smart routing configuration fields at once
|
||||
const updateSmartRoutingConfigBatch = async (updates: Partial<SmartRoutingConfig>) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const data = await apiPut('/system-config', {
|
||||
smartRouting: updates,
|
||||
});
|
||||
|
||||
if (data.success) {
|
||||
setSmartRoutingConfig({
|
||||
...smartRoutingConfig,
|
||||
...updates,
|
||||
});
|
||||
showToast(t('settings.systemConfigUpdated'));
|
||||
return true;
|
||||
} else {
|
||||
showToast(data.message || t('errors.failedToUpdateSmartRoutingConfig'));
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to update smart routing config:', error);
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : 'Failed to update smart routing config';
|
||||
setError(errorMessage);
|
||||
showToast(errorMessage);
|
||||
return false;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Update multiple routing configuration fields at once
|
||||
const updateRoutingConfigBatch = async (updates: Partial<RoutingConfig>) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const data = await apiPut('/system-config', {
|
||||
routing: updates,
|
||||
});
|
||||
|
||||
if (data.success) {
|
||||
setRoutingConfig({
|
||||
...routingConfig,
|
||||
...updates,
|
||||
});
|
||||
showToast(t('settings.systemConfigUpdated'));
|
||||
return true;
|
||||
} else {
|
||||
showToast(data.message || t('errors.failedToUpdateRouteConfig'));
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to update routing config:', error);
|
||||
setError(error instanceof Error ? error.message : 'Failed to update routing config');
|
||||
showToast(t('errors.failedToUpdateRouteConfig'));
|
||||
return false;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Update MCPRouter configuration
|
||||
const updateMCPRouterConfig = async <T extends keyof MCPRouterConfig>(
|
||||
key: T,
|
||||
value: MCPRouterConfig[T],
|
||||
) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const data = await apiPut('/system-config', {
|
||||
mcpRouter: {
|
||||
[key]: value,
|
||||
},
|
||||
});
|
||||
|
||||
if (data.success) {
|
||||
setMCPRouterConfig({
|
||||
...mcpRouterConfig,
|
||||
[key]: value,
|
||||
});
|
||||
showToast(t('settings.systemConfigUpdated'));
|
||||
return true;
|
||||
} else {
|
||||
showToast(data.message || t('errors.failedToUpdateSystemConfig'));
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to update MCPRouter config:', error);
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : 'Failed to update MCPRouter config';
|
||||
setError(errorMessage);
|
||||
showToast(errorMessage);
|
||||
return false;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Update multiple MCPRouter configuration fields at once
|
||||
const updateMCPRouterConfigBatch = async (updates: Partial<MCPRouterConfig>) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const data = await apiPut('/system-config', {
|
||||
mcpRouter: updates,
|
||||
});
|
||||
|
||||
if (data.success) {
|
||||
setMCPRouterConfig({
|
||||
...mcpRouterConfig,
|
||||
...updates,
|
||||
});
|
||||
showToast(t('settings.systemConfigUpdated'));
|
||||
return true;
|
||||
} else {
|
||||
showToast(data.message || t('errors.failedToUpdateSystemConfig'));
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to update MCPRouter config:', error);
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : 'Failed to update MCPRouter config';
|
||||
setError(errorMessage);
|
||||
showToast(errorMessage);
|
||||
return false;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Update OAuth server configuration
|
||||
const updateOAuthServerConfig = async <T extends keyof OAuthServerConfig>(
|
||||
key: T,
|
||||
value: OAuthServerConfig[T],
|
||||
) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const data = await apiPut('/system-config', {
|
||||
oauthServer: {
|
||||
[key]: value,
|
||||
},
|
||||
});
|
||||
|
||||
if (data.success) {
|
||||
setOAuthServerConfig((prev) => ({
|
||||
...prev,
|
||||
[key]: value,
|
||||
}));
|
||||
showToast(t('settings.systemConfigUpdated'));
|
||||
return true;
|
||||
} else {
|
||||
showToast(data.message || t('errors.failedToUpdateSystemConfig'));
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to update OAuth server config:', error);
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : 'Failed to update OAuth server config';
|
||||
setError(errorMessage);
|
||||
showToast(errorMessage);
|
||||
return false;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Update multiple OAuth server config fields
|
||||
const updateOAuthServerConfigBatch = async (updates: Partial<OAuthServerConfig>) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const data = await apiPut('/system-config', {
|
||||
oauthServer: updates,
|
||||
});
|
||||
|
||||
if (data.success) {
|
||||
setOAuthServerConfig((prev) => ({
|
||||
...prev,
|
||||
...updates,
|
||||
}));
|
||||
showToast(t('settings.systemConfigUpdated'));
|
||||
return true;
|
||||
} else {
|
||||
showToast(data.message || t('errors.failedToUpdateSystemConfig'));
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to update OAuth server config:', error);
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : 'Failed to update OAuth server config';
|
||||
setError(errorMessage);
|
||||
showToast(errorMessage);
|
||||
return false;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Update name separator
|
||||
const updateNameSeparator = async (value: string) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const data = await apiPut('/system-config', {
|
||||
nameSeparator: value,
|
||||
});
|
||||
|
||||
if (data.success) {
|
||||
setNameSeparator(value);
|
||||
showToast(t('settings.restartRequired'), 'info');
|
||||
return true;
|
||||
} else {
|
||||
showToast(data.message || t('errors.failedToUpdateSystemConfig'));
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to update name separator:', error);
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : 'Failed to update name separator';
|
||||
setError(errorMessage);
|
||||
showToast(errorMessage);
|
||||
return false;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Update session rebuild setting
|
||||
const updateSessionRebuild = async (value: boolean) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const data = await apiPut('/system-config', {
|
||||
enableSessionRebuild: value,
|
||||
});
|
||||
|
||||
if (data.success) {
|
||||
setEnableSessionRebuild(value);
|
||||
showToast(t('settings.restartRequired'), 'info');
|
||||
return true;
|
||||
} else {
|
||||
showToast(data.message || t('errors.failedToUpdateSystemConfig'));
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to update session rebuild setting:', error);
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : 'Failed to update session rebuild setting';
|
||||
setError(errorMessage);
|
||||
showToast(errorMessage);
|
||||
return false;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const exportMCPSettings = async (serverName?: string) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
return await apiGet(`/mcp-settings/export?serverName=${serverName ? serverName : ''}`);
|
||||
} catch (error) {
|
||||
console.error('Failed to export MCP settings:', error);
|
||||
const errorMessage = error instanceof Error ? error.message : 'Failed to export MCP settings';
|
||||
setError(errorMessage);
|
||||
showToast(errorMessage);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Fetch settings when the component mounts or refreshKey changes
|
||||
useEffect(() => {
|
||||
fetchSettings();
|
||||
}, [fetchSettings, refreshKey]);
|
||||
|
||||
useEffect(() => {
|
||||
if (routingConfig) {
|
||||
setTempRoutingConfig({
|
||||
bearerAuthKey: routingConfig.bearerAuthKey,
|
||||
});
|
||||
}
|
||||
}, [routingConfig]);
|
||||
|
||||
return {
|
||||
routingConfig,
|
||||
tempRoutingConfig,
|
||||
setTempRoutingConfig,
|
||||
installConfig,
|
||||
smartRoutingConfig,
|
||||
mcpRouterConfig,
|
||||
oauthServerConfig,
|
||||
nameSeparator,
|
||||
enableSessionRebuild,
|
||||
loading,
|
||||
error,
|
||||
setError,
|
||||
triggerRefresh,
|
||||
fetchSettings,
|
||||
updateRoutingConfig,
|
||||
updateInstallConfig,
|
||||
updateSmartRoutingConfig,
|
||||
updateSmartRoutingConfigBatch,
|
||||
updateRoutingConfigBatch,
|
||||
updateMCPRouterConfig,
|
||||
updateMCPRouterConfigBatch,
|
||||
updateOAuthServerConfig,
|
||||
updateOAuthServerConfigBatch,
|
||||
updateNameSeparator,
|
||||
updateSessionRebuild,
|
||||
exportMCPSettings,
|
||||
};
|
||||
return useSettings();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user