fix: address code review feedback - timer leaks, CORS, validation, cache TTL

- Fix timer leak in fetchNotionProfile/loadDatabaseCache with finally block
- Remove HTTP origin from CORS whitelist (HTTPS-only)
- Validate devId against DEV_REGISTRY instead of regex
- Fix cache TTL check to use >= instead of >
- Fix chat.js count queries to use page_size 100 instead of 1

Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/a260ce18-279a-4490-af90-a90a7b1f46cd
This commit is contained in:
copilot-swe-agent[bot] 2026-03-25 08:15:48 +00:00
parent df21bae395
commit 726b05bc0b
5 changed files with 15 additions and 17 deletions

View File

@ -55,7 +55,7 @@ router.post('/chat/context', async function(req, res) {
// 获取 Agent 注册表计数
try {
if (dbConfig.agentRegistry) {
var agents = await notionService.queryDB(dbConfig.agentRegistry, null, null, 1);
var agents = await notionService.queryDB(dbConfig.agentRegistry, null, null, 100);
context.agents_count = agents.results ? agents.results.length : 0;
}
} catch (_) {}
@ -66,7 +66,7 @@ router.post('/chat/context', async function(req, res) {
var syslogs = await notionService.queryDB(dbConfig.syslogInbox, {
property: 'DEV编号',
rich_text: { equals: devId }
}, null, 1);
}, null, 100);
context.syslogs_count = syslogs.results ? syslogs.results.length : 0;
}
} catch (_) {}
@ -75,7 +75,7 @@ router.post('/chat/context', async function(req, res) {
try {
if (dbConfig.ticketBook) {
var tickets = await notionService.queryDB(dbConfig.ticketBook,
{ property: '状态', select: { does_not_equal: '已完成' } }, null, 1);
{ property: '状态', select: { does_not_equal: '已完成' } }, null, 100);
context.tickets_count = tickets.results ? tickets.results.length : 0;
}
} catch (_) {}

View File

@ -28,15 +28,12 @@ var DEV_REGISTRY = {
router.get('/dev/:devId', async function(req, res) {
var devId = req.params.devId;
// 验证 devId 格式
if (!/^DEV-\d{3}$/.test(devId)) {
return res.status(400).json({ error: true, code: 'INVALID_DEV_ID', message: '无效的开发者编号格式' });
// 验证 devId
if (!DEV_REGISTRY[devId]) {
return res.status(404).json({ error: true, code: 'DEV_NOT_FOUND', message: '开发者不存在' });
}
var devInfo = DEV_REGISTRY[devId];
if (!devInfo) {
return res.status(404).json({ error: true, code: 'DEV_NOT_FOUND', message: '开发者不存在' });
}
var profile = {
dev_id: devId,

View File

@ -18,7 +18,6 @@ const app = express();
app.use(cors({
origin: [
'https://guanghulab.com',
'http://guanghulab.com',
'https://www.guanghulab.com',
'https://qinfendebingshuo.github.io'
],

View File

@ -14,7 +14,7 @@ var store = new Map();
function get(key) {
var item = store.get(key);
if (!item) return null;
if (Date.now() - item.time > (item.ttl || DEFAULT_TTL)) {
if (Date.now() - item.time >= (item.ttl || DEFAULT_TTL)) {
store.delete(key);
return null;
}

View File

@ -1771,9 +1771,10 @@ async function fetchNotionProfile(devId) {
try {
const ctrl = new AbortController();
const tid = setTimeout(function() { ctrl.abort(); }, 5000);
const res = await fetch(API_BASE + '/dev/' + encodeURIComponent(devId), { signal: ctrl.signal });
clearTimeout(tid);
if (res.ok) { const d = await res.json(); d._source = 'realtime'; return d; }
try {
const res = await fetch(API_BASE + '/dev/' + encodeURIComponent(devId), { signal: ctrl.signal });
if (res.ok) { const d = await res.json(); d._source = 'realtime'; return d; }
} finally { clearTimeout(tid); }
} catch (e) { console.debug('[通道B] profile fetch failed, 降级到通道A:', e.message); }
}
// 通道AGitHub 缓存)
@ -1791,9 +1792,10 @@ async function loadDatabaseCache(name) {
try {
const ctrl = new AbortController();
const tid = setTimeout(function() { ctrl.abort(); }, 5000);
const res = await fetch(API_BASE + '/databases/' + encodeURIComponent(name), { signal: ctrl.signal });
clearTimeout(tid);
if (res.ok) return await res.json();
try {
const res = await fetch(API_BASE + '/databases/' + encodeURIComponent(name), { signal: ctrl.signal });
if (res.ok) return await res.json();
} finally { clearTimeout(tid); }
} catch (e) { console.debug('[通道B] database ' + name + ' fetch failed:', e.message); }
}
// 通道AGitHub 缓存)