fix: harden token search with pagination, rate limiting and input validation
- Add configurable per-user token creation limit (max_user_tokens) - Sanitize search input patterns to prevent expensive queries - Add per-user search rate limiting (by user ID) - Add pagination to search endpoint with strict page size cap - Skip empty search fields instead of matching nothing - Hide internal errors from API responses - Fix Interface2String float64 formatting causing config parse failures - Add float-string fallback in config system for int/uint fields
This commit is contained in:
@@ -40,6 +40,7 @@ export const useTokensData = (openFluentNotification) => {
|
||||
const [tokenCount, setTokenCount] = useState(0);
|
||||
const [pageSize, setPageSize] = useState(ITEMS_PER_PAGE);
|
||||
const [searching, setSearching] = useState(false);
|
||||
const [searchMode, setSearchMode] = useState(false); // 是否处于搜索结果视图
|
||||
|
||||
// Selection state
|
||||
const [selectedKeys, setSelectedKeys] = useState([]);
|
||||
@@ -91,6 +92,7 @@ export const useTokensData = (openFluentNotification) => {
|
||||
// Load tokens function
|
||||
const loadTokens = async (page = 1, size = pageSize) => {
|
||||
setLoading(true);
|
||||
setSearchMode(false);
|
||||
const res = await API.get(`/api/token/?p=${page}&size=${size}`);
|
||||
const { success, message, data } = res.data;
|
||||
if (success) {
|
||||
@@ -188,21 +190,21 @@ export const useTokensData = (openFluentNotification) => {
|
||||
};
|
||||
|
||||
// Search tokens function
|
||||
const searchTokens = async () => {
|
||||
const searchTokens = async (page = 1, size = pageSize) => {
|
||||
const { searchKeyword, searchToken } = getFormValues();
|
||||
if (searchKeyword === '' && searchToken === '') {
|
||||
setSearchMode(false);
|
||||
await loadTokens(1);
|
||||
return;
|
||||
}
|
||||
setSearching(true);
|
||||
const res = await API.get(
|
||||
`/api/token/search?keyword=${searchKeyword}&token=${searchToken}`,
|
||||
`/api/token/search?keyword=${encodeURIComponent(searchKeyword)}&token=${encodeURIComponent(searchToken)}&p=${page}&size=${size}`,
|
||||
);
|
||||
const { success, message, data } = res.data;
|
||||
if (success) {
|
||||
setTokens(data);
|
||||
setTokenCount(data.length);
|
||||
setActivePage(1);
|
||||
setSearchMode(true);
|
||||
syncPageData(data);
|
||||
} else {
|
||||
showError(message);
|
||||
}
|
||||
@@ -226,12 +228,20 @@ export const useTokensData = (openFluentNotification) => {
|
||||
|
||||
// Page handlers
|
||||
const handlePageChange = (page) => {
|
||||
loadTokens(page, pageSize).then();
|
||||
if (searchMode) {
|
||||
searchTokens(page, pageSize).then();
|
||||
} else {
|
||||
loadTokens(page, pageSize).then();
|
||||
}
|
||||
};
|
||||
|
||||
const handlePageSizeChange = async (size) => {
|
||||
setPageSize(size);
|
||||
await loadTokens(1, size);
|
||||
if (searchMode) {
|
||||
await searchTokens(1, size);
|
||||
} else {
|
||||
await loadTokens(1, size);
|
||||
}
|
||||
};
|
||||
|
||||
// Row selection handlers
|
||||
|
||||
Reference in New Issue
Block a user