feat: Enhance authentication flow by integrating permissions retrieval and updating related services (#256)

This commit is contained in:
samanhappy
2025-08-05 13:45:31 +08:00
committed by GitHub
parent 63b356b8d7
commit f63f06d879
8 changed files with 41 additions and 17 deletions

View File

@@ -1,7 +1,7 @@
import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import { AuthState } from '../types';
import * as authService from '../services/authService';
import { shouldSkipAuth } from '../services/configService';
import { getPublicConfig } from '../services/configService';
// Initial auth state
const initialState: AuthState = {
@@ -32,7 +32,7 @@ export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) =>
useEffect(() => {
const loadUser = async () => {
// First check if authentication should be skipped
const skipAuth = await shouldSkipAuth();
const { skipAuth, permissions } = await getPublicConfig();
if (skipAuth) {
// If authentication is disabled, set user as authenticated with a dummy user
@@ -42,6 +42,7 @@ export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) =>
user: {
username: 'guest',
isAdmin: true,
permissions,
},
error: null,
});

View File

@@ -26,6 +26,7 @@ export interface PublicConfigResponse {
success: boolean;
data?: {
skipAuth?: boolean;
permissions?: any;
};
message?: string;
}
@@ -41,7 +42,7 @@ export interface SystemConfigResponse {
/**
* Get public configuration (skipAuth setting) without authentication
*/
export const getPublicConfig = async (): Promise<{ skipAuth: boolean }> => {
export const getPublicConfig = async (): Promise<{ skipAuth: boolean; permissions?: any }> => {
try {
const basePath = getBasePath();
const response = await fetchWithInterceptors(`${basePath}/public-config`, {
@@ -53,7 +54,7 @@ export const getPublicConfig = async (): Promise<{ skipAuth: boolean }> => {
if (response.ok) {
const data: PublicConfigResponse = await response.json();
return { skipAuth: data.data?.skipAuth === true };
return { skipAuth: data.data?.skipAuth === true, permissions: data.data?.permissions || {} };
}
return { skipAuth: false };

View File

@@ -429,7 +429,7 @@
"edit": "编辑用户",
"delete": "删除用户",
"create": "创建",
"update": "用户",
"update": "更新",
"username": "用户名",
"password": "密码",
"newPassword": "新密码",

View File

@@ -1,6 +1,6 @@
import dotenv from 'dotenv';
import fs from 'fs';
import { McpSettings } from '../types/index.js';
import { McpSettings, IUser } from '../types/index.js';
import { getConfigFilePath } from '../utils/path.js';
import { getPackageVersion } from '../utils/version.js';
import { getDataService } from '../services/services.js';
@@ -54,14 +54,14 @@ export const loadOriginalSettings = (): McpSettings => {
}
};
export const loadSettings = (): McpSettings => {
return dataService.filterSettings!(loadOriginalSettings());
export const loadSettings = (user?: IUser): McpSettings => {
return dataService.filterSettings!(loadOriginalSettings(), user);
};
export const saveSettings = (settings: McpSettings): boolean => {
export const saveSettings = (settings: McpSettings, user?: IUser): boolean => {
const settingsPath = getSettingsPath();
try {
const mergedSettings = dataService.mergeSettings!(loadOriginalSettings(), settings);
const mergedSettings = dataService.mergeSettings!(loadOriginalSettings(), settings, user);
fs.writeFileSync(settingsPath, JSON.stringify(mergedSettings, null, 2), 'utf8');
// Update cache after successful save

View File

@@ -1,6 +1,11 @@
import { Request, Response } from 'express';
import config from '../config/index.js';
import { loadSettings } from '../config/index.js';
import { getDataService } from '../services/services.js';
import { DataService } from '../services/dataService.js';
import { IUser } from '../types/index.js';
const dataService: DataService = getDataService();
/**
* Get runtime configuration for frontend
@@ -38,6 +43,15 @@ export const getPublicConfig = (req: Request, res: Response): void => {
try {
const settings = loadSettings();
const skipAuth = settings.systemConfig?.routing?.skipAuth || false;
let permissions = {};
if (skipAuth) {
const user: IUser = {
username: 'guest',
password: '',
isAdmin: true,
};
permissions = dataService.getPermissions(user);
}
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
res.setHeader('Pragma', 'no-cache');
@@ -47,6 +61,7 @@ export const getPublicConfig = (req: Request, res: Response): void => {
success: true,
data: {
skipAuth,
permissions,
},
});
} catch (error) {

View File

@@ -506,6 +506,7 @@ export const updateToolDescription = async (req: Request, res: Response): Promis
export const updateSystemConfig = (req: Request, res: Response): void => {
try {
const { routing, install, smartRouting } = req.body;
const currentUser = (req as any).user;
if (
(!routing ||
@@ -675,7 +676,7 @@ export const updateSystemConfig = (req: Request, res: Response): void => {
needsSync = (!wasSmartRoutingEnabled && isNowEnabled) || (isNowEnabled && hasConfigChanged);
}
if (saveSettings(settings)) {
if (saveSettings(settings, currentUser)) {
res.json({
success: true,
data: settings.systemConfig,

View File

@@ -9,9 +9,15 @@ import {
getUserCount,
getAdminCount,
} from '../services/userService.js';
import { loadSettings } from '../config/index.js';
// Admin permission check middleware function
const requireAdmin = (req: Request, res: Response): boolean => {
const settings = loadSettings();
if (settings.systemConfig?.routing?.skipAuth) {
return true;
}
const user = (req as any).user;
if (!user || !user.isAdmin) {
res.status(403).json({

View File

@@ -2,9 +2,9 @@ import { IUser, McpSettings } from '../types/index.js';
export interface DataService {
foo(): void;
filterData(data: any[]): any[];
filterSettings(settings: McpSettings): McpSettings;
mergeSettings(all: McpSettings, newSettings: McpSettings): McpSettings;
filterData(data: any[], user?: IUser): any[];
filterSettings(settings: McpSettings, user?: IUser): McpSettings;
mergeSettings(all: McpSettings, newSettings: McpSettings, user?: IUser): McpSettings;
getPermissions(user: IUser): string[];
}
@@ -13,15 +13,15 @@ export class DataServiceImpl implements DataService {
console.log('default implementation');
}
filterData(data: any[]): any[] {
filterData(data: any[], _user?: IUser): any[] {
return data;
}
filterSettings(settings: McpSettings): McpSettings {
filterSettings(settings: McpSettings, _user?: IUser): McpSettings {
return settings;
}
mergeSettings(all: McpSettings, newSettings: McpSettings): McpSettings {
mergeSettings(all: McpSettings, newSettings: McpSettings, _user?: IUser): McpSettings {
return newSettings;
}