fix: address code review feedback for LANGDRIVE implementation
- Normalize module paths in deploy permission checks (trailing slash) - Add devId format validation in PATCH /dev/:devId/status - Fix onboarding resume logic (allow resuming incomplete sessions) - Switch audit logging from sync to async file I/O - Add hasModuleAccess helper for consistent module permission checks 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:
parent
38d8afef55
commit
5e8bb969a4
|
|
@ -45,14 +45,17 @@ function auditLog(req, res, next) {
|
|||
logEntry.statusCode = res.statusCode;
|
||||
|
||||
// 异步写入日志,不阻塞响应
|
||||
try {
|
||||
fs.mkdirSync(AUDIT_LOG_DIR, { recursive: true });
|
||||
fs.mkdir(AUDIT_LOG_DIR, { recursive: true }, function(mkdirErr) {
|
||||
if (mkdirErr) {
|
||||
console.error('审计日志目录创建失败:', mkdirErr.message);
|
||||
return;
|
||||
}
|
||||
var today = new Date().toISOString().split('T')[0];
|
||||
var logFile = path.join(AUDIT_LOG_DIR, 'audit-' + today + '.jsonl');
|
||||
fs.appendFileSync(logFile, JSON.stringify(logEntry) + '\n');
|
||||
} catch (e) {
|
||||
console.error('审计日志写入失败:', e.message);
|
||||
}
|
||||
fs.appendFile(logFile, JSON.stringify(logEntry) + '\n', function(writeErr) {
|
||||
if (writeErr) console.error('审计日志写入失败:', writeErr.message);
|
||||
});
|
||||
});
|
||||
|
||||
return originalSend.call(this, body);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -62,6 +62,25 @@ function rateLimit(req, res, next) {
|
|||
|
||||
router.use(rateLimit);
|
||||
|
||||
// 模块路径归一化(确保带末尾斜杠)
|
||||
function normalizeModule(mod) {
|
||||
if (!mod) return '';
|
||||
mod = mod.trim();
|
||||
if (mod !== '*' && !mod.endsWith('/')) mod += '/';
|
||||
return mod;
|
||||
}
|
||||
|
||||
// 检查开发者是否拥有指定模块
|
||||
function hasModuleAccess(userModules, module) {
|
||||
if (!userModules || !module) return false;
|
||||
if (userModules.includes('*')) return true;
|
||||
var normalized = normalizeModule(module);
|
||||
for (var i = 0; i < userModules.length; i++) {
|
||||
if (normalizeModule(userModules[i]) === normalized) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 获取实际数据库 ID(沙箱环境使用沙箱 DB)
|
||||
function getDbId(req, configKey) {
|
||||
if (req.sandbox && req.sandboxDbIds && req.sandboxDbIds[configKey]) {
|
||||
|
|
@ -251,7 +270,7 @@ router.post('/deploy/preview',
|
|||
}
|
||||
|
||||
// 检查开发者是否拥有该模块
|
||||
if (!req.user.modules.includes('*') && !req.user.modules.includes(module)) {
|
||||
if (!hasModuleAccess(req.user.modules, module)) {
|
||||
return res.status(403).json({
|
||||
error: true,
|
||||
code: 'MODULE_DENIED',
|
||||
|
|
@ -290,7 +309,7 @@ router.post('/deploy/production',
|
|||
}
|
||||
|
||||
// 检查模块权限
|
||||
if (!req.user.modules.includes('*') && !req.user.modules.includes(module)) {
|
||||
if (!hasModuleAccess(req.user.modules, module)) {
|
||||
return res.status(403).json({
|
||||
error: true,
|
||||
code: 'MODULE_DENIED',
|
||||
|
|
@ -432,6 +451,11 @@ router.patch('/dev/:devId/status',
|
|||
var devId = req.params.devId;
|
||||
var status = req.body.status;
|
||||
|
||||
// 验证 devId 格式
|
||||
if (!/^DEV-\d{3}$/.test(devId) && !/^TCS-\d{4}$/.test(devId)) {
|
||||
return res.status(400).json({ error: true, code: 'INVALID_DEV_ID', message: '无效的开发者编号' });
|
||||
}
|
||||
|
||||
// 开发者只能更新自己的状态(管理者除外)
|
||||
if (req.user.devId !== devId && !req.user.permissions.includes('dev:update_all')) {
|
||||
return res.status(403).json({
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@
|
|||
});
|
||||
if (res.ok) {
|
||||
var data = await res.json();
|
||||
return !data.started && !data.completed && data.permissionLevel === 0;
|
||||
// Show onboarding if not completed (handles both new and resumed sessions)
|
||||
return !data.completed && data.permissionLevel === 0;
|
||||
}
|
||||
} catch (e) {
|
||||
console.debug('[Onboarding] check failed:', e.message);
|
||||
|
|
|
|||
Loading…
Reference in New Issue