fix: 修复代码审查发现的安全性和性能问题
主要修复: - 安全性:API 密钥使用恒定时间比较防止时序攻击 - 安全性:URL 验证仅允许 http/https 协议,防止 XSS - 安全性:移除 Markdown 的 rehypeRaw 插件增强 XSS 防护 - 安全性:Webhook 错误信息脱敏,生产环境不暴露敏感数据 - 性能:项目详情页使用并行数据获取 - 性能:Webhook 批量查询标签,避免 N+1 查询问题 - 类型安全:移除 any 类型,使用 Prisma 类型注解 - 类型安全:为 useProjects 函数添加返回类型 - 代码质量:创建 slug 工具函数统一 slug 生成逻辑 - 代码质量:搜索字符串添加最小长度限制(2字符) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -16,18 +16,16 @@ export default async function ProjectDetailPage({
|
||||
const { locale, id } = resolvedParams
|
||||
const tProject = await getTranslations('project')
|
||||
|
||||
// Get project by slug
|
||||
const project = await getProjectBySlug(id)
|
||||
// 并行获取项目和相关项目数据
|
||||
const [project, relatedProjectsResult] = await Promise.all([
|
||||
getProjectBySlug(id),
|
||||
getProjects({ limit: 3 }),
|
||||
])
|
||||
|
||||
if (!project) {
|
||||
notFound()
|
||||
}
|
||||
|
||||
// Get related projects (same tags, excluding current project)
|
||||
const relatedProjectsResult = await getProjects({
|
||||
limit: 3,
|
||||
})
|
||||
|
||||
const relatedProjects = relatedProjectsResult.projects
|
||||
.filter(p => p.id !== project.id)
|
||||
.filter(p => p.tags.some(t => project.tags.some(pt => pt.id === t.id)))
|
||||
@@ -72,12 +70,13 @@ export default async function ProjectDetailPage({
|
||||
export async function generateMetadata({ params }: ProjectDetailPageProps) {
|
||||
const resolvedParams = await params
|
||||
const { id, locale } = resolvedParams
|
||||
const tProject = await getTranslations('project')
|
||||
|
||||
const project = await getProjectBySlug(id)
|
||||
|
||||
if (!project) {
|
||||
return {
|
||||
title: 'Project Not Found',
|
||||
title: tProject('notFound'),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user