345 Commits

Author SHA1 Message Date
xfy
a3d6c2f19e refactor(markdown): 复用既有 escape_html,删除重复的转义实现
hooks::comment_storage::escape_html 已实现完整 OWASP 转义(& < > " '),
且无 server feature 门控,全平台可用。escape_heading_text 改为委托给它,
避免在仓库内维护第二份行为略有差异(缺 >)的转义函数。补充 < 转义测试。
2026-06-15 11:38:24 +08:00
xfy
eaa7118e09 fix(posts): 钳制 page 上限,防止无界 OFFSET 与缓存键扇出
clamp_pagination 原先仅限制 per_page,page 无上限。攻击者可用海量不同
page 值撑大缓存键空间(缓存污染)并触发无意义的超大 OFFSET 扫描。新增
MAX_PAGE=10_000,对任何实际博客都足够宽裕(配合 MAX_PER_PAGE 最多覆盖
50 万篇文章),同时把缓存键空间限制在有限范围。
2026-06-15 11:38:24 +08:00
xfy
6d32664020 fix(markdown): 转义 TOC 标题文本,防止属性上下文注入
generate_toc_html 原先用 clean_html 处理标题后拼进 aria-label="..." 与
<a> 正文,但 clean_html 只做正文 HTML 消毒、不转义双引号。标题形如
" onmouseover="alert(1) 会越出属性边界。新增 escape_html_attr(),对
标题文本统一做属性上下文转义(& " <),正文与属性两处一致使用。

内容由 admin 写入、严重度中低,但属真实消毒逻辑缺口,TOC 会展示给所有读者。
2026-06-15 11:27:32 +08:00
xfy
cfa4975813 fix(posts): 钳制分页参数 per_page 上限,消除公开接口 DoS
list_published_posts 为无需认证的公开接口,原先 per_page 直接透传给
SQL LIMIT,攻击者可传入巨大值迫使数据库扫描并实例化超大 Vec,造成
内存放大与拒绝服务。新增 MAX_PER_PAGE=50 与 clamp_pagination(),在
list_published_posts 与 list_posts 入口钳制 page/per_page;钳制值同时
用于缓存键与查询,避免同一逻辑页落入不同缓存条目。
2026-06-15 11:27:25 +08:00
xfy
81ee60a77d chore: ignore .worktrees directory
Add .worktrees/ to .gitignore so isolated git worktrees created for
parallel development work are not accidentally tracked.
2026-06-15 10:50:48 +08:00
xfy
e12e59461b docs: 整理表格格式并添加 CI 链接
Some checks failed
CI / check (push) Successful in 12m26s
CI / build (push) Failing after 13m0s
2026-06-15 10:41:03 +08:00
xfy
f7288cc390 style: 格式化测试代码以符合 clippy 宽度限制 2026-06-15 10:40:00 +08:00
xfy
0242534274 style(tags): 修复文档注释列表缩进以消除 clippy 警告
Some checks failed
CI / check (push) Failing after 4m52s
CI / build (push) Has been skipped
2026-06-12 19:48:10 +08:00
xfy
194611bb7e docs(bin): 补充中文注释 2026-06-12 19:45:59 +08:00
xfy
c43da3676f docs(components): 补充中文注释 2026-06-12 19:42:42 +08:00
xfy
c5d1eb117c docs(auth-pages, router, main): 补充中文注释 2026-06-12 19:31:21 +08:00
xfy
18500c9496 docs(pages-admin): 补充中文注释 2026-06-12 19:24:22 +08:00
xfy
abfab19839 docs(pages-frontend): 补充中文注释 2026-06-12 19:16:59 +08:00
xfy
1904907add docs(hooks, theme): 补充中文注释 2026-06-12 19:07:43 +08:00
xfy
671a9fea7a docs(infra): 补充中文注释 2026-06-12 19:02:37 +08:00
xfy
2db652137d docs(models, db, cache): 补充中文注释 2026-06-12 18:56:56 +08:00
xfy
a785683fc6 docs(posts): 补充中文注释 2026-06-12 18:50:17 +08:00
xfy
9921f8eebf docs(comments): 补充中文注释 2026-06-12 18:42:19 +08:00
xfy
26b012c40c docs(api, auth): 补充中文注释 2026-06-12 18:27:24 +08:00
xfy
4fe26f7eb3 test: improve unit test coverage and assertions
Some checks failed
CI / check (push) Failing after 15m51s
CI / build (push) Has been skipped
- Add tests for sanitizer, mime_to_ext, clean_tags, Theme::toggle
- Tighten assertions in highlight, markdown, post status classes
- Add boundary and XSS cases for comments, slug, rate_limit, webp
- Update Cargo.lock for serial_test dev-dependency
2026-06-12 18:13:51 +08:00
xfy
6fe7dc3ff5 build: use npx tailwindcss instead of global binary
Some checks failed
CI / check (push) Successful in 8m46s
CI / build (push) Has been cancelled
2026-06-12 18:09:20 +08:00
xfy
220a1f91b0 ci: retry rustup install on network failure
Some checks failed
CI / check (push) Successful in 7m51s
CI / build (push) Failing after 8m18s
2026-06-12 17:44:19 +08:00
xfy
041cdf4102 test(cache): mark cache tests serial to fix parallel flakiness 2026-06-12 17:40:15 +08:00
xfy
fa6fa9a77c docs: document COOKIE_SECURE and TRUSTED_PROXY_COUNT 2026-06-12 17:31:20 +08:00
xfy
997f9b4617 ci: switch to rsproxy cargo mirror
Some checks failed
CI / check (push) Successful in 10m25s
CI / build (push) Failing after 2m45s
2026-06-12 17:29:37 +08:00
xfy
942ac853fe refactor: tighten module-level allow attributes 2026-06-12 17:26:46 +08:00
xfy
294d60afab style: format rust code
Some checks failed
CI / build (push) Has been cancelled
CI / check (push) Has been cancelled
2026-06-12 17:14:31 +08:00
xfy
71ac08c373 feat(rate_limit): derive real client IP from X-Forwarded-For with TRUSTED_PROXY_COUNT 2026-06-12 17:13:17 +08:00
xfy
c8182f89da ci: back to runner host with tsinghua rustup mirror
Some checks failed
CI / check (push) Failing after 8m4s
CI / build (push) Has been skipped
2026-06-12 17:05:13 +08:00
xfy
cb137cfdfb ci: use printf instead of heredoc for cargo config
Some checks failed
CI / check (push) Failing after 0s
CI / build (push) Has been skipped
2026-06-12 17:04:17 +08:00
xfy
8014e202f8 ci: use aliyun rust mirror container
Some checks failed
CI / check (push) Failing after 1s
CI / build (push) Has been skipped
2026-06-12 17:03:38 +08:00
xfy
4ae7b38131 feat(auth): add Secure flag to session cookie via COOKIE_SECURE env 2026-06-12 17:02:22 +08:00
xfy
a070e3f8fc ci: use tsinghua rustup mirror and ustc cargo mirror
Some checks failed
CI / check (push) Failing after 6s
CI / build (push) Has been skipped
2026-06-12 16:57:07 +08:00
xfy
cab12a1e5e ci: replace actions/checkout with raw git clone
Some checks failed
CI / check (push) Failing after 3m33s
CI / build (push) Has been skipped
2026-06-12 16:42:17 +08:00
xfy
99e1f2e98d ci: avoid actions/setup-node, install node via nodesource
Some checks failed
CI / build (push) Has been cancelled
CI / check (push) Has been cancelled
2026-06-12 16:41:38 +08:00
xfy
94de78c513 ci: run directly on runner without docker container
Some checks failed
CI / build (push) Has been cancelled
CI / check (push) Has been cancelled
2026-06-12 16:39:12 +08:00
xfy
2a19bc4e28 ci: add gitea actions workflow
Some checks failed
CI / check (push) Failing after 55s
CI / build (push) Has been skipped
2026-06-12 16:31:19 +08:00
xfy
b72bc512c2 chore(make): use npm ci for tiptap editor to avoid lockfile drift 2026-06-12 16:27:12 +08:00
xfy
ee6aaf179c feat(posts): add batch limit and error handling to rebuild_content_html 2026-06-12 11:44:53 +08:00
xfy
835d71972c fix(admin): add missing dark mode background colors to skeleton components 2026-06-12 11:15:46 +08:00
xfy
a10bf8737c refactor(sanitizer): extract shared sanitizer module and migrate from ammonia to lol_html 2026-06-12 11:15:42 +08:00
xfy
b898b55308 chore: add profile.json.gz to .gitignore 2026-06-12 10:56:56 +08:00
xfy
f8fb35f8c2 fix(admin): use arbitrary value for tooltip dark text color 2026-06-12 10:55:32 +08:00
xfy
1c3f1aac34 fix(admin): flip tooltip to bottom to avoid navbar overlap
Changed from bottom-full/mb-2 to top-full/mt-2, added z-50.
2026-06-12 10:54:02 +08:00
xfy
8840faa830 fix(admin): use arbitrary dark mode values for tooltip bg
Matches project pattern of dark:text-[#dadadb] / dark:bg-[#dadadb]
for reliable Tailwind v4 class-based dark mode.
2026-06-12 10:52:05 +08:00
xfy
c62cf5a239 feat(admin): add tooltip to rebuild content button
Pure CSS tooltip appears on hover, inverted color scheme
(white-on-dark / dark-on-light) matching admin aesthetic.
2026-06-12 10:50:18 +08:00
xfy
67e23d672c feat(admin): add rebuild content button to posts management page
Outline-style button next to '写文章', calls rebuild_content_html(false)
to rebuild posts with NULL content_html. Shows result message below header.
2026-06-12 10:43:49 +08:00
xfy
0219f923e9 docs: add DEVELOPMENT.md with performance testing guide 2026-06-12 10:36:12 +08:00
xfy
f6589121da perf(markdown): eliminate duplicate clean_html call in generate_toc_html
clean_html() triggers expensive ammonia sanitization with aho_corasick.
Previously called twice for the same text (aria-label + display text).
Now calls once and reuses the result.
2026-06-12 10:36:06 +08:00
xfy
2e9d123396 feat(posts): add rebuild_content_html server function
New admin-only server function that re-renders content_html and
toc_html for posts from their content_md:
- rebuild_all=false: only processes posts where content_html IS NULL
- rebuild_all=true: processes all non-deleted posts
- Processes rows one at a time to avoid table locks
- Invalidates post list and stats caches after rebuild
2026-06-12 10:35:59 +08:00