fix: address code review feedback - validation, sanitization, docs
- Fix email validation JSDoc comment in chat.js - Add explicit format validation for devId/project in preview routes - Sanitize contact field input in build route - Add detailed token estimation comment in memory-injector - Add warning log when ws module is not available Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
parent
6f02d67ecd
commit
b4a835b8a7
|
|
@ -129,7 +129,9 @@ function loadProfile(devId) {
|
|||
}
|
||||
|
||||
/**
|
||||
* 粗略估算 token 数量(中文约 1.5 token/字,英文约 0.25 token/word)
|
||||
* 粗略估算 token 数量
|
||||
* 中文约 1.5 token/字(CJK字符经 BPE 分词通常为 1-2 token)
|
||||
* 英文/其他约 0.4 token/字符(英文单词平均 4 字符 ≈ 1 token)
|
||||
*/
|
||||
function estimateTokens(text) {
|
||||
if (!text) return 0;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ router.post('/start', async (req, res) => {
|
|||
});
|
||||
}
|
||||
|
||||
// 联系方式输入清理(去除潜在 HTML/script 注入)
|
||||
const safeContact = contact ? String(contact).replace(/[<>&"']/g, '').substring(0, 100) : null;
|
||||
|
||||
// 先立即响应,后台异步处理
|
||||
res.json({
|
||||
error: false,
|
||||
|
|
@ -68,7 +71,7 @@ router.post('/start', async (req, res) => {
|
|||
memoryManager.addProject(dev_id, {
|
||||
name: result.projectName || 'untitled',
|
||||
email: email,
|
||||
contact: contact || null,
|
||||
contact: safeContact,
|
||||
status: 'completed',
|
||||
created_at: new Date().toISOString(),
|
||||
files: result.files || []
|
||||
|
|
|
|||
|
|
@ -21,9 +21,18 @@ router.get('/:devId/:project', (req, res) => {
|
|||
});
|
||||
}
|
||||
|
||||
// 安全校验:防止路径遍历
|
||||
// 安全校验:确保 devId 和 project 匹配预期格式(防止路径遍历)
|
||||
const safeDevId = path.basename(devId);
|
||||
const safeProject = path.basename(project);
|
||||
|
||||
if (!/^[a-zA-Z0-9_-]+$/.test(safeDevId) || !/^[a-zA-Z0-9_.-]+$/.test(safeProject)) {
|
||||
return res.status(400).json({
|
||||
error: true,
|
||||
code: 'INVALID_PARAMS',
|
||||
message: '参数格式无效'
|
||||
});
|
||||
}
|
||||
|
||||
const previewDir = path.join(WORKSPACE_DIR, safeDevId, safeProject, 'preview');
|
||||
const projectDir = path.join(WORKSPACE_DIR, safeDevId, safeProject);
|
||||
|
||||
|
|
@ -53,6 +62,10 @@ router.get('/:devId/:project/:file', (req, res) => {
|
|||
const safeProject = path.basename(project);
|
||||
const safeFile = path.basename(file);
|
||||
|
||||
if (!/^[a-zA-Z0-9_-]+$/.test(safeDevId) || !/^[a-zA-Z0-9_.-]+$/.test(safeProject) || !/^[a-zA-Z0-9_.-]+$/.test(safeFile)) {
|
||||
return res.status(400).send('Invalid parameters');
|
||||
}
|
||||
|
||||
const previewDir = path.join(WORKSPACE_DIR, safeDevId, safeProject, 'preview');
|
||||
const projectDir = path.join(WORKSPACE_DIR, safeDevId, safeProject);
|
||||
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ try {
|
|||
};
|
||||
} catch (_e) {
|
||||
// ws module not installed, WebSocket disabled
|
||||
console.warn('[Persona Studio] ws module not available, WebSocket features disabled');
|
||||
app.locals.broadcastToClient = function () {};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -606,7 +606,9 @@ function closeEmailModal() {
|
|||
}
|
||||
|
||||
/**
|
||||
* 后端二次校验用的邮箱正则
|
||||
* 前端邮箱格式校验(与后端 build.js 使用相同正则,双重校验)
|
||||
* @param {string} email - 邮箱地址
|
||||
* @returns {boolean} 是否合法
|
||||
*/
|
||||
function validateEmail(email) {
|
||||
var re = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
||||
|
|
|
|||
Loading…
Reference in New Issue