Commit Graph
8 Commits
Author SHA1 Message Date
kevin efc30156b9 feat: 站点设置接口 JSON 化——/api/admin/settings/*
- settings.go:5 组 save handler 改 JSON 绑定(siteSettingsRequest/
  uploadSettingsRequest/downloadSettingsRequest/commentSettingsRequest/
  navLinkSettingsRequest);request struct 变更子函数签名(不再触碰
  c.PostForm),upload/navlink/download 的 action 分发保留,未知
  action 返回 400;enabled 用 *bool(nil 沿用旧默认启用语义)
- favicon/logo 上传拆出:POST /api/admin/settings/site/favicon|logo
  (multipart,图片类别校验 + 旧本地文件替换),SiteSettingsSave 只
  处理文本/URL/clear(存储路径校验保留 illegal_dir 400)
- main.go:设置旧 POST 路由移除,新 /api/admin/settings 分组注册
- 模板:base.html 新增 blogSettingsForm 委托(data-api-url/data-action/
  data-confirm → POST + redirect/alert);settings_site 主表单 JSON +
  logo/favicon 选择即上传;navlinks/upload/download/comments 页全部
  小表单改委托(约 14 个)
- blogForm:剔除 file 字段(文件走 multipart)
- 测试:TestStorageDirTraversalRejected、TestAddUploadFileTypeRejectsDangerousExtensions
  更新 JSON 断言;env 路由补 /api/admin/settings
- main_test 冒烟补设置 API 断言;go build/vet/test 全绿
2026-08-27 19:52:07 +08:00
kevin 856d414295 feat: 用户管理接口 JSON 化——/api/admin/users CRUD
- admin_user.go:userForm 加 json tags,parseUserFormJSON(绑定+去白,
  ID 取路由参数);UserCreate/Update/Delete 校验错误改 APIError
  (400 校验、409 user_username_exists、403 自防/最后管理员、404
  user_not_found、500),成功 {ok,redirect:?saved=1&msg=...}
- i18n:新增 user_not_found(中英)
- main.go:旧 POST /admin/users/new|:id/edit|:id/delete 移除,
  改 POST/PUT/DELETE /api/admin/users[/:id](自防屏障保留)
- user_form.html:表单改 blogAPI(FormID 分流 POST/PUT),错误内联
- user_list.html:删除改 blogDelete 委托
- p2/security 测试:环境路由同步 + 用户校验/注入用例改 JSON 断言
  (TestAdminUserPasswordAndEmailEnforcement、TestAdminUserRoutesRejectNonNumericIDs)
- main_test 冒烟补用户 API 断言;go build/vet/test 全绿
2026-08-27 19:44:09 +08:00
kevin 5b227b71ef feat: 文章 CRUD 接口 JSON 化——/api/admin|my/articles
- article.go:articleForm 加 json tags,新增 parseArticleFormJSON(绑定+
  去白);ArticleCreate/ArticleUpdate/ArticleDelete 增加 redirectPath 参数,
  校验失败改 APIError 400、DB 错误 500,成功 {ok,redirect}(原 renderForm
  分支移除);id 改用 parseUintParam 数值化
- my_articles.go:MyArticleCreate 复用 ArticleCreate(db, /my/articles);
  MyArticleUpdate/MyArticleDelete 保留 author_id 所有权约束(404
  article_not_found);my 更新不触碰标签(表单无该字段,与旧行为一致)
- main.go:admin/my 文章旧 POST 路由移除,改 POST/PUT/DELETE
  /api/admin/articles[/:id] 与 /api/my/articles[/:id]
- 模板:article_create.html/my_article_form.html 表单改 blogAPI 提交
  (easyMDE.value() 同步正文、editor e.submitter 分流草稿/发布),错误内联
  articleError/myArticleError;article_list.html/my_articles.html 删除改
  blogDelete 委托(base.html 新公共函数,DELETE + reload 保筛选状态)
- main_test 冒烟补文章 CRUD 断言;go build/vet/test 全绿
2026-08-27 19:40:02 +08:00
kevin a0061b14e3 feat: 评论接口 JSON 化——/api/article/:slug/comments 与 admin 审核操作
- comment.go:commentForm 加 json tag;PostComment 校验分支改 APIError
  (404 article_not_found、403 comments_disabled/comments_guests_disabled、
  400 校验码、500 article_error),保留 guest 令牌与 flash 机制,成功返回
  {ok,redirect:/article/:slug#comment-N,comment_id}
- api.go:新增 APIErrorf(支持 %d/%s 占位符键如 comments_too_long)
- admin_comment.go:approve/reject/delete 改 JSON(parseUintParam 拒绝非
  数值 id 400),成功带原 ?saved=1&msg= 查询串 redirect
- main.go:PostComment 迁入 /api;评论审核三操作迁入 /api/admin/comments
- article.html:评论表单改 blogAPI 提交,错误内联 commentError div
- comment_list.html:审核操作改 to commentAct() 委托(confirm 在函数内,
  取消不发请求),成功 reload 保持筛选状态
- 测试:security_test env 路由同步 /api;session_upload 评论用例改 JSON
- main_test 冒烟补评论 API 路由断言;go build/vet/test 全绿
2026-08-27 19:36:09 +08:00
kevin 7062c755a3 feat: 认证接口 JSON 化——/api/auth/login|register|logout
- auth.go:Login/Register 改 JSON 绑定(loginRequest/registerRequest),
  错误码复用 i18n 键:登录失败 login_error(401)、限流锁定 login_locked(429)、
  注册校验 400、用户名冲突 user_username_exists(409)、注册禁用
  registration_disabled(403);成功返回 {ok,redirect}(角色定向 /admin 或 /)
- main.go:旧 POST /login /register /logout 移除,迁入 /api/auth 分组
- i18n:新增 registration_disabled(中英)
- security_test.go:env 路由改 /api/auth/*,e.login 改 JSON 登录,
  新增 postJSON/respCode/respRedirect/respOK 测试辅助
- p2_validation_test.go:TestLoginRateLimited/TestLoginTimingDoesNotRevealUser/
  TestRegisterRejectsInvalidEmail 迁移 JSON 断言(429/401/409/400)
- base.html:logout-form 全局委托 fetch + login/register 模板 id/JS
- main_test.go:冒烟断言补 /api/auth 三端点
- go build/vet/test ./... 全绿
2026-08-27 19:31:29 +08:00
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 f7870e8557 fix: 修复 P0 复审漏洞 #18 #19(数据库泄露 + SQL 注入)
- #18 /uploads 改为白名单子目录挂载(attachments/avatars/logos + 配置的
  存储目录),存储根不再整体暴露,blog.db 不可被下载;禁用目录列表,
  拒绝 .. 穿越与反斜杠
- #19 admin 用户管理三个 handler 的路由参数先解析为数值(uintFormID),
  非数值直接 302,消除 GORM First() 字符串条件 SQL 注入
- 新增回归测试 main_test.go(4 用例)与 TestAdminUserRoutesRejectNonNumericIDs
  (已变异验证:旧代码下注入用例失败)
- SECURITY_TODO.md 勾选 #18/#19 并更新执行顺序
2026-08-27 17:08:22 +08:00