安全加固 + 结构清理:修注入/串写/竞态,DOMPurify 上线,后端补事务与 handler 测试

后端:
- ORDER BY 白名单(sanitizeOrder)堵住 ?order= SQL 注入,补回归测试
- 登录限速(每 IP 10 次失败/10 分钟 429)、TLS/反代下 Secure cookie、NewAPI 构造器
- Delete/setTags/MergeTags/DeleteTag 包事务;Archive 去 500 篇上限
- 列表接口裁剪:不传 content_md,长文 content_html 截 600,新增 content_len;health 探 DB

前端:
- EditorView 路由复用串写修复(RouterView :key + sync watch 回写原文章)
- v-html 出口统一过 DOMPurify(sanitizeHtml),stripTags 改 DOMParser
- 列表竞态防护(Home/Tag/Posts 请求序号)、TagView 分页修复
- 侧栏接口 30s 缓存去重;one:unauthorized 监听器泄漏修复
- 删 styles.css 498 行重复块;移除 tailwind/marked/vue-tsc 死依赖;CommandPalette a11y 语义
This commit is contained in:
Sakurasan committed 2026-09-21 23:59:09 +08:00
1 parent c762f06cd7
commit dd2994189a
25 files changed
+539 -1411

No files matched your search

+7 -1
View File
@@ -37,7 +37,11 @@ const tabs = [
{ label: '短文', value: 'short' }
]
// 快速翻页/切标签时旧响应可能后到并覆盖新结果,用递增序号只采纳最新一次
let seq = 0
async function load() {
const my = ++seq
loading.value = true
error.value = ''
try {
@@ -47,13 +51,15 @@ async function load() {
page: page.value,
size: size.value
})
if (my !== seq) return
items.value = data.items || []
total.value = data.total || 0
} catch (e) {
if (my !== seq) return
error.value = e.message || '加载失败'
items.value = []
} finally {
loading.value = false
if (my === seq) loading.value = false
}
}