60 Commits

Author SHA1 Message Date
xfy
0319c927c6 chore: format code 2026-06-09 13:43:10 +08:00
xfy
b26094835f feat: convert uploaded images to WebP for storage savings 2026-06-09 13:39:36 +08:00
xfy
281da208f5 fix: remove stray space in upload filename format string 2026-06-09 13:37:11 +08:00
xfy
42b39266a6 fix: preserve data URI in img src during markdown rendering
ammonia's default url_schemes whitelist excludes 'data', causing
data:image/* URLs to be stripped from img src attributes. Add 'data'
to allowed schemes. Also skip data: URIs in JS thumbnail logic.
2026-06-09 10:06:34 +08:00
xfy
3974856f3d fix: resolve image/upload 500 errors and refactor rate limiting
- Separate /uploads and /api/upload routes from Dioxus app to avoid
  IncrementalRenderer intercepting non-page requests
- Remove broken SmartIpKeyExtractor-based general_limit() that failed
  under Dioxus dev server proxy (Unable To Extract Key)
- Move rate limiting into handlers using governor::RateLimiter directly
- Add IMAGE_LIMITER for /uploads/* serving
- Make all rate limits configurable via environment variables
- Add rate limit config to .env.example with sensible defaults
2026-06-09 09:48:51 +08:00
xfy
4f368e6fb8 test: add 122 unit tests across 12 modules
Cover utils/text, api/slug, auth/password, auth/session,
models/post, models/user, api/auth validation, api/markdown,
api/image, highlight, api/rate_limit. Add make test target.
2026-06-09 09:25:44 +08:00
959d813630 feat: pg_trgm full-text search for posts (#2)
* feat(db): add pg_trgm search index on posts

* feat(api): use pg_trgm similarity search for posts

* fix(api): use ILIKE + word_similarity instead of % operator for search
2026-06-08 18:26:35 +08:00
xfy
e74b9f3c39 feat: apply rate limiting to Register, Login, and upload endpoints
- Remove unused tags.rs and related re-exports
- Convert strict_limit/upload_limit from Layer to manual check functions
- Add IP-based rate limiting checks to Register, Login, and upload_image
- Keep general_limit as global middleware for all other routes
2026-06-08 17:30:26 +08:00
xfy
76f1b8dd53 feat: add rate limiting configurations 2026-06-08 16:57:48 +08:00
xfy
771b155a88 refactor: split posts.rs and fix N+1 with JOIN+array_agg 2026-06-08 16:53:31 +08:00
xfy
32131377c3 refactor: integrate tags module into posts.rs and mod.rs 2026-06-08 16:45:20 +08:00
xfy
441060e7c2 refactor: extract tag operations into api/tags.rs 2026-06-08 16:44:38 +08:00
xfy
6e4e72b232 refactor: extract markdown rendering into api/markdown.rs 2026-06-08 16:42:55 +08:00
xfy
4c88d5e2bb refactor: extract slug utilities into api/slug.rs 2026-06-08 16:40:44 +08:00
xfy
e5d37aa034 refactor(api): extract error helper functions, DRY up db/query/tx error handling 2026-06-08 16:17:03 +08:00
xfy
717266db1e fix: resolve conditional compilation and dead code warnings 2026-06-08 16:11:24 +08:00
xfy
2c08c6c7fd fix(image): case-insensitive format matching in process_image 2026-06-08 15:29:17 +08:00
xfy
8b1b949bf8 refactor: apply formatting to image.rs 2026-06-08 15:13:18 +08:00
xfy
d584ef6e00 fix(image): improve cache keys, case-insensitive format, strict thumb validation 2026-06-08 15:13:18 +08:00
xfy
1f009f57c8 feat: add image processing handler with resize/thumbnail/rotate/format 2026-06-08 15:13:18 +08:00
xfy
6d28c2b4ce feat(api): add get_post_by_id server function for editing 2026-06-05 17:29:48 +08:00
xfy
22de5add83 fix(api): restore deleted_at filter in slug uniqueness check 2026-06-05 16:20:43 +08:00
xfy
c7668c679c fix(api): include deleted posts in slug uniqueness check 2026-06-05 16:02:45 +08:00
xfy
371ebcf8f9 fix(upload): gate axum imports behind #[cfg(feature = "server")]
Wrap all axum imports and constants with #[cfg(feature = "server")]
to prevent WASM compilation failures. Provide a no-op stub for
non-server builds.

Fixes: error[E0433]: cannot find module or crate  in scope
2026-06-05 15:08:19 +08:00
xfy
93020a8e14 fix(upload): remove space in filename format and unused UploadResponse struct 2026-06-05 15:00:29 +08:00
xfy
1bae3446e6 feat(api): add image upload handler with admin auth 2026-06-05 14:56:29 +08:00
xfy
81d3d72a48 feat: enable extended markdown parsing with table support in post rendering 2026-06-04 18:06:46 +08:00
xfy
675349a5b4 fix: add #[cfg(feature = server)] to server-only imports for WASM compatibility 2026-06-04 16:40:42 +08:00
xfy
e5ce1580e2 fix: restore dead_code allow on CreatePostRequest to suppress warning 2026-06-04 16:25:05 +08:00
xfy
1830fc9f2e cleanup: remove dead code, debug prints, and unused dead_code allow attributes 2026-06-04 16:20:43 +08:00
xfy
c27b2d513e perf: pre-compile regex patterns and extract markdown stripping to utils/text.rs 2026-06-04 16:08:01 +08:00
xfy
28707d3c3a refactor: reuse session validation in get_current_admin_user via get_user_by_token 2026-06-04 16:02:47 +08:00
xfy
d3be04bcec refactor: extract session parsing to auth/session.rs and db error helpers to api/utils.rs 2026-06-04 15:16:40 +08:00
xfy
593666135c feat: add DB connection retry logic with get_conn() helper 2026-06-04 10:03:56 +08:00
xfy
3d19f62fb4 fix: prevent syntax-highlighted spans from being displayed as block due to Tailwind .block class conflict 2026-06-03 16:18:24 +08:00
xfy
34e3bcdf95 fix: address code review feedback
- Remove unnecessary 'style' from ammonia whitelist (syntect uses classes)
- Log syntect parse errors instead of silently discarding them
- Simplify find_syntax fallback: return &'static directly, remove OnceLock
- Add generated/highlight.css to .gitignore (build artifact)
- Add #[cfg(feature = "server")] guard on mod highlight in main.rs
- Remove redundant code_buffer/code_lang clear on CodeBlock end
2026-06-03 13:13:29 +08:00
xfy
11261836c7 feat: add syntect code highlighting with catppuccin themes
- Add syntect dependency (server feature, fancy-regex backend)
- Create highlight module with LazyLock globals for SyntaxSet + themes
- Intercept CodeBlock events in markdown rendering for syntax highlighting
- Update ammonia whitelist to allow span/pre/code class/style attributes
- Add generate_highlight_css binary for CSS generation
- Add highlight-css Makefile target (runs before tailwindcss)
- Import generated highlight.css in input.css
- Remove hardcoded code block colors, let catppuccin CSS take over
2026-06-03 11:52:58 +08:00
xfy
6c039e16e8 refactor(api): remove unused word_count/reading_time from RenderedContent 2026-06-03 10:54:02 +08:00
xfy
61ae3abbc2 fix(api): generate ASCII-only slugs with timestamp fallback
Use is_ascii_alphanumeric() instead of is_alphanumeric() to keep
URLs clean. Non-ASCII characters (CJK, etc.) are replaced with
dashes. When the result is empty (pure non-ASCII title), fall back
to a Unix timestamp.
2026-06-03 10:33:11 +08:00
xfy
f5413e00cc fix(auth): prevent password_hash from reaching the frontend
Introduce PublicUser struct without password_hash field. The
get_current_user server function now returns PublicUser via
CurrentUserResponse, so Argon2 hashes are never serialized to WASM.

Internal server-side functions (get_current_admin_user) continue
using the full User struct.
2026-06-03 10:32:15 +08:00
xfy
8146a8a779 perf(api): split row_to_post into list and full variants
List pages (home, tags, search, admin) now use row_to_post_list which
reads pre-rendered content_html from DB instead of re-rendering markdown
on every request. Only get_post_by_slug uses row_to_post_full which
includes TOC, anchors, word count, and prev/next navigation.
2026-06-03 10:29:46 +08:00
xfy
19e5a0be41 fix(api): correct count_words for CJK characters
Chinese characters (U+4E00-U+9FFF) also return true for is_alphabetic(),
so they were being counted as part of English words instead of individually.
Fix: check CJK range before is_alphabetic().
2026-06-03 10:25:38 +08:00
xfy
0290f4d2e7 fix(api): remove debug logging that caused UTF-8 boundary panic; configure ammonia to preserve anchor attributes 2026-06-03 10:09:14 +08:00
xfy
0c34df4ba7 fix(api): configure ammonia to preserve class and aria-hidden attributes for anchor links 2026-06-03 09:54:16 +08:00
xfy
fb4f5790fc fix(api): remove hidden attr from anchor links, use CSS display instead 2026-06-03 09:48:12 +08:00
xfy
5ff58fec59 fix(api): fix markdown rendering to properly handle code blocks and other elements 2026-06-02 18:30:26 +08:00
xfy
14e4a26dc0 fix(api): use rendered HTML with anchors in row_to_post 2026-06-02 18:28:24 +08:00
xfy
1088691dca feat(api): enhance markdown rendering with TOC, anchors, word count; add cover_image support; prev/next post navigation 2026-06-02 18:17:21 +08:00
xfy
9c5b09a278 chore: code cleanup - formatting, EOF newlines, model helper, and UI tweaks 2026-06-02 17:33:28 +08:00
xfy
1950646bef feat: add shared components, new pages, and pagination 2026-06-02 17:33:28 +08:00