Commit Graph
11 Commits
Author SHA1 Message Date
kevin b1e9d9cae6 feat: API 基建——/api JSON 接口统一契约与认证分支
- handlers/api.go:APIOK/APIError/bindJSON,统一 {ok,redirect,data} /
  {ok:false,code,error} 响应契约(code=i18n 键,error 按请求语言翻译)
- i18n:新增 api_error/api_unauthorized/api_forbidden/api_invalid_request(中英)
- middleware/auth.go:AuthRequired/AdminRequired 按 /api 前缀分支:
  JSON 401/403(页面保持 302),新增 isAPIRequest + apiAuthError
- main.go:路由注册提取为 registerRoutes;建立 /api 分组并搬移附件三件套
  (admin/my)与 /api/profile/avatar(旧 /admin|my/articles/attachments、
  /profile/avatar 路由移除)
- handlers/login_ratelimit.go:loginRateLimiter 导出为 LoginRateLimiter
- templates/layouts/base.html:blogAPI/blogForm/blogShowError 共享 fetch 助手
- main_test.go:TestRegisterRoutesSmoke 冒烟测试(注册期 gin 静态/参数
  冲突即 panic + 关键 /api 路由断言)
- go build/vet/test ./... 全绿
2026-08-27 19:24:43 +08:00
kevin f307781f58 docs: 全部 Go 代码注释汉化
- 48 个 Go 文件所有注释(行注释/块注释/行尾注释,含 _test.go)翻译为中文
- 保留技术标识符:SECURITY_TODO(n)、unsafe-inline、sqlite/mysql、路由参数等
- 代码、字符串字面量、日志消息保持英文原文,零逻辑改动
- go build/vet 通过,go test -count=1 ./... 全绿
2026-08-27 19:03:03 +08:00
kevin c9f858b626 fix: 完成 P2 安全修复 #9-13 #22-25
- #9 CDN 本地化:marked/DOMPurify/highlight.js/cropperjs/easymde 入 static/vendor(go:embed),Tailwind 改静态构建(scripts/build_tailwind.sh),CSP 收紧为 default-src 'self'
- #10 登录限速:IP+用户名维度 5 次失败锁 15 分钟,内存实现有界(handlers/login_ratelimit.go)
- #25 计时侧信道:用户不存在时执行 dummy bcrypt 抹平时间差(随 #10 实施)
- #11 配置文件权限 0640
- #12 首启随机一次性密码(弃用 admin/admin)
- #13 unix socket 660 + 代理用户加组提示
- #22 storage_dir 路径穿越校验(单安全路径段)
- #23 密码最小长度统一(改密/建号/重置),#24 邮箱格式统一校验
- 新增 13 个单元测试;go test ./... 含 -race 全绿
2026-08-27 18:10:22 +08:00
kevin e314b05670 fix: 修复 P1 复审漏洞 #20 #21(禁用用户会话失效 + 头像 XSS 链)
- #20 AuthRequired 改为 AuthRequired(db):受保护路由每次回库校验
  Status == StatusNormal 且未软删,失败清 session(保留 lang/csrf_token,
  与登录轮换口径一致)并 302 /login;session user_id 先断言为数值再入
  GORM(呼应 #19),AdminRequired 同步加固;SetUserContext 仅在用户
  存在且状态正常时置 is_logged_in——禁用用户发评论不再自动通过,
  回落游客审核策略
- #21 头像两个分支(UploadAvatar / UpdateProfile)强制
  Category == image,解码失败直接拒绝、删除"回退存原始字节"路径,
  统一经 processAvatar 解码→256px 缩放→JPEG 重编码;addUploadFileType
  增加危险扩展黑名单(.html/.htm/.xhtml/.xht/.svg/.xml/.js/.mjs),
  拒绝添加并在上传设置页提示(模板 + 中英 i18n)
- 附带修复:processAvatar 依赖的 png/gif 解码器此前未注册(旧代码靠
  回退存原始字节掩盖,PNG 头像从未真正处理过),补 blank import
- 新增回归测试 session_upload_security_test.go(6 用例:禁用/锁定/
  软删旧 cookie 302、锁定用户评论转 pending、6 组危险扩展拒绝、
  伪装扩展名头像拒绝且磁盘零写入、正常图片转存 .jpg;已变异验证:
  去掉任一修复对应测试即失败)
- SECURITY_TODO.md 勾选 #20/#21 并更新执行顺序
2026-08-27 17:35:46 +08:00
kevin 38cd09f723 fix: 安全加固,修复 P0/P1 安全漏洞
P0(高危):
- 新增全局 CSRF 中间件(同步器令牌),覆盖全部 30 个表单与 AJAX 请求
- 修复附件上传/列表/删除越权(IDOR),增加 admin/上传者/文章作者所有权校验
- 登录/注册成功后会话轮换,修复会话固定
- 会话密钥改用 crypto/rand 生成,配置缺失 secret 时拒绝启动

P1(中危):
- session 与 comment_uid cookie 增加 Secure/SameSite 标志
- 新增安全响应头:CSP、X-Content-Type-Options、X-Frame-Options、HSTS 等
- 新增 web.trusted_proxies 配置,修复 X-Forwarded-For 伪造
- 修复浏览量记录 goroutine 访问已回收 gin.Context 的数据竞争

补充 17 个安全回归测试(middleware/handlers),go test -race 全绿
2026-08-19 12:33:09 +08:00
kevinandClaude Fable 5 d9bb91af00 feat: add navigation links management and user registration
Features:
- Custom navigation links management in admin settings
- Multi-language support for navigation links (Chinese/English)
- Control link behavior (open in new window)
- Sort order and enable/disable toggle for nav links
- User registration system with validation
- Admin can enable/disable user registration
- Registration form with username, display name, email, password
- Link to registration from login page

Navigation Links:
- Admin interface to add/edit/delete custom nav links
- Support for both internal and external URLs
- Display links in header navigation bar
- Respects language preference

User Registration:
- Username validation (3-32 characters, alphanumeric + underscore/dash)
- Password validation (minimum 6 characters)
- Password confirmation matching
- Optional display name and email fields
- Can be toggled on/off by admin in site settings

Templates:
- Added navigation links settings page
- Added user registration page
- Updated login page with registration link
- Updated base layout to render custom nav links

Documentation:
- NAV_LINKS_FEATURE.md - Navigation links feature documentation
- REGISTRATION_FEATURE.md - User registration documentation
- IMPLEMENTATION_SUMMARY.md - Overall implementation summary

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-22 21:01:38 +08:00
kevinandClaude Fable 5 b600eac21c feat: add favicon settings to site configuration
- Add Favicon field to SiteSetting model with FaviconIsURL() helper
- Implement favicon upload and management in site settings page
- Support both external URL and local file upload for favicon
- Add favicon display in page header with automatic URL detection
- Add i18n translations for favicon settings (EN/ZH)
- Update middleware and helpers to pass favicon data to templates
- Include migration script for existing databases

Users can now customize their site's favicon from /admin/settings/site
by either providing an external URL or uploading a local image file
(recommended formats: .ico, .png, .svg, 16x16 or 32x32 pixels).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-22 20:09:05 +08:00
kevin cefaeac618 feat: add admin user management with role-based access and self-protection
- Add AdminRequired middleware for admin-role routes
- Add login status check to reject disabled/locked accounts
- Add CRUD handlers (list, create, edit, delete) for users
- Add user_list and user_form templates with role/status badges
- Add nav entry and dashboard button for user management
- Add dynamic user count on admin dashboard
- Fix userIDFromSession to handle all numeric session types
- Self-protection: cannot delete/disable self or demote last admin
- Add EN/ZH i18n keys for all user management strings
2026-06-22 18:11:39 +08:00
kevinandClaude Fable 5 0c5bcde7da feat: make home welcome/subtitle configurable and fix settings render
Add home_welcome and home_subtitle fields (zh/en) to site_settings so
the home page heading and subtitle are editable from the admin panel,
falling back to the i18n defaults when empty. Wire them through the
config cache, SetUserContext, DefaultData, and home.html.

Fix the /admin/settings/site page rendering blank: Go templates cannot
invoke methods on an interface{}-wrapped struct, so pre-compute
SiteLogoIsURL in the handler instead of calling .Site.LogoIsURL() in
the template.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-21 20:41:45 +08:00
kevinandClaude Fable 5 e3367e6e12 feat: add platform configuration tables and admin settings
Add four DB-backed configuration tables for site-wide settings:
site_settings (logo, top-left title, header/footer text with zh/en
variants), upload_configs (master switch, default size, storage dir),
upload_file_types (per-extension whitelist with per-type size limits),
and download_baseurls (multiple download sources with priority/default).

- Models, AutoMigrate, and first-run seed (18 common file types)
- Process-level config cache warmed at startup, refreshed on admin save
- SetUserContext injects cached site settings into templates
- base.html renders logo (local upload or external URL), title, header
  banner, and footer with i18n fallback
- Upload validator drives avatar uploads (form + AJAX) through the
  configured switch/type/size policy
- Admin pages for site/upload/download settings with i18n keys

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-21 20:32:28 +08:00
kevinandClaude Opus 4.8 c82d4482d4 feat: initial blog engine with multi-language, profile, and role system
- Gin + GORM + Tailwind CSS blog engine
- OS-aware config (Linux /etc/blog_go/, Windows ./win/etc/blog_go/)
- SQLite by default, MySQL support via config
- Auto-migrate database + seed admin user on first run
- Session-based auth (login/logout)
- i18n: Chinese/English with auto-detect + manual switch
- Avatar dropdown nav with click-to-toggle menu
- Profile page: avatar upload, edit info, change password
- Role system: admin (full access) and author (profile only)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 01:49:04 +08:00