Browse Source
refactor(backend): 列表排序字段白名单统一走 SortUtils 防 SQL 注入
refactor(backend): 列表排序字段白名单统一走 SortUtils 防 SQL 注入
- 新增 SortUtils.resolveColumn 统一排序字段白名单映射,未知字段回退默认列 - 各 Controller/Service 列表接口新增 sortField/sortOrder 参数并接入白名单 - 前端列表页列加 sorter 并透传服务端排序参数Spring-AI-1.1.2
44 changed files with 429 additions and 152 deletions
-
7frontend/src/api/api-key.ts
-
4frontend/src/api/conversation.ts
-
4frontend/src/api/faq.ts
-
4frontend/src/api/llm-trace.ts
-
7frontend/src/api/mcp-server.ts
-
4frontend/src/api/model-config.ts
-
8frontend/src/api/sensitive-word.ts
-
4frontend/src/api/user.ts
-
7frontend/src/api/webhook.ts
-
2frontend/src/views/AccountManager.vue
-
10frontend/src/views/ApiKeyManager.vue
-
10frontend/src/views/AuditLogManager.vue
-
23frontend/src/views/CategoryManager.vue
-
10frontend/src/views/ConversationManager.vue
-
4frontend/src/views/DashboardPanel.vue
-
16frontend/src/views/FaqManager.vue
-
16frontend/src/views/FeedbackOps.vue
-
10frontend/src/views/McpServerManager.vue
-
16frontend/src/views/ModelConfigManager.vue
-
40frontend/src/views/PromptTracePanel.vue
-
18frontend/src/views/SensitiveWordManager.vue
-
14frontend/src/views/UserManager.vue
-
10frontend/src/views/WebhookManager.vue
-
40src/main/java/com/wok/supportbot/common/SortUtils.java
-
6src/main/java/com/wok/supportbot/controller/AiModelConfigController.java
-
6src/main/java/com/wok/supportbot/controller/ApiKeyController.java
-
6src/main/java/com/wok/supportbot/controller/ConversationController.java
-
6src/main/java/com/wok/supportbot/controller/FaqController.java
-
6src/main/java/com/wok/supportbot/controller/LlmCallTraceController.java
-
6src/main/java/com/wok/supportbot/controller/McpServerConfigController.java
-
6src/main/java/com/wok/supportbot/controller/MessageFeedbackController.java
-
22src/main/java/com/wok/supportbot/controller/SensitiveWordController.java
-
6src/main/java/com/wok/supportbot/controller/SysUserController.java
-
6src/main/java/com/wok/supportbot/controller/WebhookController.java
-
29src/main/java/com/wok/supportbot/service/AiModelConfigService.java
-
17src/main/java/com/wok/supportbot/service/ApiKeyService.java
-
24src/main/java/com/wok/supportbot/service/ConversationService.java
-
21src/main/java/com/wok/supportbot/service/FaqService.java
-
24src/main/java/com/wok/supportbot/service/LlmCallTraceService.java
-
21src/main/java/com/wok/supportbot/service/McpServerConfigService.java
-
22src/main/java/com/wok/supportbot/service/MessageFeedbackService.java
-
19src/main/java/com/wok/supportbot/service/SensitiveWordService.java
-
19src/main/java/com/wok/supportbot/service/SysUserService.java
-
17src/main/java/com/wok/supportbot/service/WebhookService.java
@ -1,7 +1,12 @@ |
|||||
import request from './request' |
import request from './request' |
||||
import type { ApiResponse } from '@/types/api' |
import type { ApiResponse } from '@/types/api' |
||||
|
|
||||
export function listWebhooks(page = 1, size = 20): Promise<ApiResponse> { return request.get(`/webhook/list?page=${page}&size=${size}`).then(r => r.data) } |
|
||||
|
export function listWebhooks(page = 1, size = 20, sortField?: string, sortOrder?: string): Promise<ApiResponse> { |
||||
|
let path = `/webhook/list?page=${page}&size=${size}` |
||||
|
if (sortField) path += `&sortField=${sortField}` |
||||
|
if (sortOrder) path += `&sortOrder=${sortOrder}` |
||||
|
return request.get(path).then(r => r.data) |
||||
|
} |
||||
export function createWebhook(data: any): Promise<ApiResponse> { return request.post('/webhook', data).then(r => r.data) } |
export function createWebhook(data: any): Promise<ApiResponse> { return request.post('/webhook', data).then(r => r.data) } |
||||
export function updateWebhook(id: string, data: any): Promise<ApiResponse> { return request.put(`/webhook/${id}`, data).then(r => r.data) } |
export function updateWebhook(id: string, data: any): Promise<ApiResponse> { return request.put(`/webhook/${id}`, data).then(r => r.data) } |
||||
export function deleteWebhook(id: string): Promise<ApiResponse> { return request.delete(`/webhook/${id}`).then(r => r.data) } |
export function deleteWebhook(id: string): Promise<ApiResponse> { return request.delete(`/webhook/${id}`).then(r => r.data) } |
||||
|
|||||
@ -0,0 +1,40 @@ |
|||||
|
package com.wok.supportbot.common; |
||||
|
|
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* 列表排序工具类。 |
||||
|
* <p> |
||||
|
* 用于统一处理后台列表接口的排序参数:白名单映射(防 SQL 注入)、sortField 判空回退、sortOrder 二值化。 |
||||
|
* 避免在每个 Service 里重复书写「白名单 + getOrDefault(null) 判空 + asc/desc」逻辑。 |
||||
|
*/ |
||||
|
public final class SortUtils { |
||||
|
|
||||
|
private SortUtils() { |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 解析排序字段对应的数据库列名。 |
||||
|
* <p> |
||||
|
* sortField 为 null 或不在白名单内时,回退到 defaultColumn,杜绝将用户输入直接拼入 ORDER BY。 |
||||
|
* |
||||
|
* @param sortField 前端传入的 colKey(可为 null) |
||||
|
* @param whitelist 前端 colKey → 数据库列名(可含表别名)的白名单映射 |
||||
|
* @param defaultColumn 回退列名(通常为 create_time) |
||||
|
* @return 安全列名 |
||||
|
*/ |
||||
|
public static String resolveColumn(String sortField, Map<String, String> whitelist, String defaultColumn) { |
||||
|
if (sortField == null) { |
||||
|
return defaultColumn; |
||||
|
} |
||||
|
String column = whitelist.get(sortField); |
||||
|
return column != null ? column : defaultColumn; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 排序方向二值化:仅 asc 视为升序,其余(含 null、desc、其他值)一律降序。 |
||||
|
*/ |
||||
|
public static boolean isAscending(String sortOrder) { |
||||
|
return "asc".equalsIgnoreCase(sortOrder); |
||||
|
} |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue