418 Commits

Author SHA1 Message Date
xfy
28f0117f06 test(sanitizer): 补充 is_safe_url 分支测试
is_safe_url 是 HTML 消毒器的安全核心,原仅通过 clean_html 间接覆盖。
新增 9 个直接单元测试,锁定各分支契约:

- https/http 白名单通过
- javascript / vbscript scheme 拒绝(含大小写混淆)
- data URI 按 allow_data_uri 标志决定(文章正文 vs 评论)
- 相对路径与锚点片段通过
- 空字符串/纯空白视为安全
- mailto / tel / ftp 等其它白名单 scheme 通过
- 含空白的 scheme 名(混淆手法)被拒绝

共 17 个测试,全部通过。
2026-06-15 11:19:46 +08:00
xfy
a9cde41de8 test(webp): 扩充 WebP 编解码测试覆盖
原仅 6 个测试,补充后覆盖:
- WebpError 的 Display 格式与 std::error::Error trait 约束
- encode 对非快速路径像素格式(Luma8 / LumaA8)的 RGBA 转换
- encode 质量参数对体积的单调性(低质量 <= 高质量)
- decode 对非法字节流与空输入的错误处理(不 panic)
- decode 错误信息带 'WebP decode error' 前缀便于排查
- 编解码往返保持图像尺寸不变

共 17 个测试,全部通过。
2026-06-15 11:18:55 +08:00
xfy
e9aac7d6b4 fix(highlight): 修复大写语言标识无法走别名映射的问题
别名表此前用 lang == from 做严格相等比较,导致 'RUST' 这类
大写标识无法命中 ('rust' → 'rs') 这类别名,最终回退到纯文本。

改用 eq_ignore_ascii_case 比较,使别名解析与扩展名/名称的小写
回退路径保持一致。

test(highlight): 补充 find_syntax 分支覆盖

新增 8 个测试覆盖此前未测的路径:
- 大写语言标识的小写回退(同时验证了上述修复)
- 别名表:golang/bash/yml 等映射
- 未知语言与空字符串的纯文本回退
- 代码首尾空白被 trim
- 多行代码逐行高亮

通过等价性断言(而非脆弱的 span class 字面量)校验别名解析,
避免 syntect 内部 class 命名变化导致测试漂移。

共 15 个测试,全部通过。
2026-06-15 11:17:53 +08:00
xfy
4e89412cde test(theme): 扩充主题模块测试覆盖
原仅 2 个 toggle 测试,补充后覆盖:
- toggle 的对合性(连续切换两次回到原值)
- Theme 的 PartialEq / Copy trait 行为
- 首屏预加载脚本的关键行为契约:读取 localStorage、
  回退 prefers-color-scheme、添加 dark class、
  包裹 try/catch 防止禁用 localStorage 时抛错

共 9 个测试,全部通过。
2026-06-15 10:57:51 +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
041cdf4102 test(cache): mark cache tests serial to fix parallel flakiness 2026-06-12 17:40:15 +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
4ae7b38131 feat(auth): add Secure flag to session cookie via COOKIE_SECURE env 2026-06-12 17:02:22 +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
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
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
xfy
a975e45cc9 feat(posts): store toc_html in DB on create and update
- create_post: include toc_html in INSERT alongside content_html
- update_post: include toc_html in UPDATE alongside content_html
- Both write toc_html as NULL when empty, Some(..) otherwise
2026-06-12 10:35:51 +08:00
xfy
acd85d18ce perf(posts): read pre-rendered content_html/toc_html from DB instead of re-rendering
Previously row_to_post_full() ignored the stored content_html and
re-rendered markdown with render_markdown_enhanced() on every read,
triggering expensive ammonia sanitization (aho_corasick accounted for
87% CPU in flame graph).

Now reads content_html and toc_html directly from the database row.
Falls back to render_markdown_enhanced() only for legacy posts where
content_html is NULL.
2026-06-12 10:35:39 +08:00
xfy
bd9e87128d perf(ssr): optimize request throughput by 32%
- Cache ammonia::Builder with LazyLock (was rebuilt per request)
- Enable tracing release_max_level_info to strip tracing overhead at compile time
- Remove TraceLayer and tower-http trace feature from production
- Increase DB pool size 10→20 (configurable via DB_POOL_SIZE)
- Increase SSR cache TTL 300s→3600s (configurable via SSR_CACHE_SECS)

Benchmark: 7,444 → 9,840 req/s, P99 latency 27.6ms → 11.1ms
2026-06-12 09:36:53 +08:00
xfy
8dbe564ca2 fix(write): 骨架屏与实际页面结构对齐 2026-06-11 18:12:35 +08:00
xfy
75e0659cb2 fix(admin): 后台管理页改为 CSR 避免闪烁
- dashboard: use_resource → use_signal + wasm32-only 加载
- posts: use_server_future → use_signal + wasm32-only 加载 + 乐观删除
- write: use_resource → use_signal + wasm32-only 加载
- 移除 use_server_future/use_resource 导致的骨架屏闪烁
- 操作按钮使用乐观更新,不调用 restart()
2026-06-11 18:04:07 +08:00
xfy
ea440cd61c fix(admin): 评论管理页改为 CSR 避免按钮点击闪烁 2026-06-11 17:34:39 +08:00
xfy
569eec5bf8 fix(admin): 评论管理页多项修复
- 修复默认头像无法显示:AdminComment 添加 avatar_url 字段
- 修复状态标签换行:移除 w-20 固定宽度,添加 whitespace-nowrap
- 操作按钮添加 cursor-pointer
- 已处于该状态的评论隐藏对应操作按钮
- 修复操作后页面不自动刷新:将 restart() 移到异步块内
2026-06-11 16:10:42 +08:00
xfy
b55409d421 fix(comments): remove admin action buttons from public comment item 2026-06-11 15:47:46 +08:00
xfy
3e95353cc5 fix(comments): nest pending replies under parent comments 2026-06-11 15:35:14 +08:00
xfy
44a738a940 fix(comments): migrate from use_server_future to use_resource 2026-06-11 15:19:37 +08:00
xfy
2b36a7c669 fix: resolve WASM compilation errors
- Remove tracing::warn! (tracing not available in WASM builds)
- Fix parameter names in comment_storage: _key → key, _value → value
- Add #[allow(unused_variables)] for non-WASM builds where params are unused
2026-06-11 14:55:10 +08:00
xfy
aa68dc4c55 fix(comments): address code quality issues in CommentForm
- Add mount guard (loaded signal) to use_effect to prevent re-firing
- Add in-flight guard at top of onclick handler to prevent double submits
- Prevent overwriting user input when clearing form fields
2026-06-11 14:49:48 +08:00
xfy
f855a9a6cd fix(comments): fix compilation errors in list.rs and pending_item.rs
- Fix rsx! macro syntax: can't use let inside for loop
- Revert post_id parameter name and use #[allow(unused_variables)] instead
- All components now compile successfully
2026-06-11 14:45:48 +08:00
xfy
792b06a2eb fix(comments): address code quality issues in list and pending_item
- Add key prop to CommentList for loop for Dioxus list diffing
- Rename post_id to _post_id in PendingCommentItem signature
- Remove unnecessary let _ = post_id suppression
2026-06-11 14:42:03 +08:00
xfy
8ae3299b3e feat(comments): add PendingCommentItem component
Renders pending (unapproved) comments with:
- opacity-70 for visual distinction
- amber '审核中' badge
- Client-side content_md rendering (HTML escape + newline→br)
- No reply button (server rejects replies to pending parents)
- Same depth/indent logic as approved comments
2026-06-11 14:36:05 +08:00
xfy
12a91e3b8e feat(comments): merge approved and pending comments in CommentList
- Accept both comments and pending props
- Merge into chronologically sorted list
- Route to CommentItem or PendingCommentItem per item type
2026-06-11 14:34:36 +08:00
xfy
9e658662cb fix(comments): add error logging for check_pending_status failure
Address code quality review: log warnings when the server call fails
instead of silently swallowing the error.
2026-06-11 14:33:13 +08:00