|
|
97adf54d6d
|
fix: golangci-lint 零告警通过 (57→0) + gofumpt/goimports 全量格式化
## CI 修复 (P0/P1)
P0 — 编译阻塞:
- interfaces.go: postUseCase ISP 接口移除不用的 Create/Update/Delete
P1 — 必须修复:
- ST1000: 为 13 个包添加包注释 (common/config/model/service/...)
- ST1005: redis_store.go 全部错误消息改为小写开头
- errcheck (19处): defer Close()→闭包忽略, notifier.Create→_=, r.Run→检查error
- errorlint (9处): switch-on-error→errors.Is 链, ==→errors.Is
- ST1020/ST1022: 导出符号注释以符号名开头
P2 — 安全评审:
- gosec (12处): G203/G301/G304/G306 添加 nolint 注释并附理由
P3 — 清理:
- unused: 移除 hasUnicode/energyStore/current/energyAdminUseCase
- gofumpt + goimports 全量格式化 (35+ 文件)
|
2026-06-22 02:27:35 +08:00 |
|
|
|
9a496d3055
|
feat: 密码强度多级校验 — low/medium/high/very_high
- site_settings 新增 password.strength 配置项
- 四级:low(len>=8) / medium(两类) / high(三类+无连续) / very_high(四类+无连续)
- 连续字符检查:重复/升序/降序/键盘水平/键盘垂直序列
- 注册和改密接口统一读取配置
- 前端 register.js 动态校验 + 管理后台安全设置区
|
2026-06-22 00:54:21 +08:00 |
|
|
|
1933ea86b4
|
feat: 注册准则阅读控制 + Footer 合规信息
准则阅读(三层控制):
- registration.show_guidelines — 弹窗/复选框模式
- registration.force_guidelines — 是否强制倒计时+滚动
- registration.guidelines_timer — 倒计时秒数
Footer 合规(8 字段,空值不显示,链接纯手写):
- site.operator_name / site.icp_number / site.icp_license
- site.police_number / site.wenwangwen / site.algorithm_filing
- site.privacy_url / site.terms_url
- 新增 safeHTML 模板函数输出不转义 HTML
|
2026-06-21 23:50:52 +08:00 |
|
|
|
0014bdb9ff
|
feat: 品牌CMS配置化 + cookie_secure配置
- config.yaml 新增 server.cookie_secure 配置项
- site_settings 新增 site_name/site_tagline/contact_email 站点信息
- SiteInfo 结构体扩展,支持运行时从 DB 读取站点品牌信息
- cookie.go 使用 cfg.Server.CookieSecure 替代 Mode!=debug 判断
- SetSessionCookie/ClearSessionCookie 支持 siteSettings 运行时覆盖
- 模板替换硬编码 MetaLab → {{.SiteName}}(nav/header/footer/home/login/register/guidelines/admin,12+处)
- 管理后台站点设置页新增站点名称/标语/联系邮箱输入项
- 页脚版权年份改为动态 CurrentYear
- 注册成功消息 CMS 化(后端+前端)
|
2026-06-21 23:34:14 +08:00 |
|
|
|
a2e8242c21
|
chore: 全局包名路径从 metalab 更改为 mce
|
2026-06-21 16:55:46 +08:00 |
|
|
|
72c08f3689
|
feat: 社区准则改为数据库存储
- AuthController 注入 SiteSettings 依赖,RegisterPage 优先从 DB 读取准则
- DB 中 site.guidelines 为空时 fallback 到静态 guidelines.html 文件
- 管理后台站点设置页新增「内容管理」分区,textarea 编辑社区准则
- 添加准则编辑区垂直布局样式
|
2026-06-02 20:17:23 +08:00 |
|
|
|
daf87f895b
|
refactor: JWT 无状态认证替换为服务端 Session,修复记住我掉线问题
- 新增 internal/session 包:Session 结构体、Store 接口、MemoryStore(内存+后台清理)、RedisStore 预留
- Cookie 从 3 个精简为 1 个 mlb_sid(HttpOnly),移除 JWT access/refresh cookie
- 会话过期采用滑动窗口:每次请求自动续期,记住我 30 天无操作过期
- AuthMiddleware/AuthAdmin/Maintenance 中间件改用 SessionManager.Validate()
- AuthService Login/Register/ConfirmRestore 去除 token 生成,返回 *model.User
- Controller 层在登录/注册后调用 SessionManager.Create 创建会话
- AdminService UpdateUserStatus/ResetUserToken 同步销毁 session 实现即时退登
- 改密/注销时通过 DestroyByUID 删除所有 session(替换 TokenVersion 检查)
- config.yaml 新增 session 配置段(idle_timeout/remember_timeout/cleanup_interval)
- TokenService/auth_parser/auth_token 标记废弃,移除 JWT 到期字段依赖
|
2026-05-30 23:36:52 +08:00 |
|
|
|
fb2eff5f23
|
feat: 注册关闭时页面隐藏表单并显示友好提示,保留登录入口
- RegisterPage 传入 RegistrationEnabled 标志到模板
- 注册关闭时隐藏输入框和按钮,显示“当前暂不开放注册”提示
- 保留“已有账号?立即登录”链接
- API 层已有拦截(AuthService.Register 返回 403),无需修改
- authUseCase 接口新增 IsRegistrationEnabled 方法(ISP)
|
2026-05-30 20:38:55 +08:00 |
|
|
|
0b948cf70f
|
feat(admin): 站点信息 + 注册开关可后台设置,模板动态渲染
新增 4 项可配置站点设置(DB持久化+内存缓存,即时生效):
- site.brand 品牌名(页面标题/页脚/管理面板,默认 MetaLab)
- site.framework 框架名(页脚标识,默认 MetaZone)
- site.copyright_start 版权起始年(页脚,默认 2024)
- registration.enabled 注册开关(关闭后禁止新用户注册,默认 true)
实现方式:
- InjectSiteInfo 中间件:全局注入 Brand/Framework/CopyrightStart 到 gin.Context
- BuildPageData 读取 context,所有 SSR 页面自动获取站点信息
- AuthService.Register 最先检查 IsRegistrationEnabled()
- 管理后台新增「基本设置」+「注册设置」区块,文本输入手动保存 + Toggle 即时生效
|
2026-05-27 15:12:28 +08:00 |
|
|
|
a19b1fcb51
|
refactor: 拆分超标控制器文件至行数≤120行
- auth_controller.go(238→54): 拆出auth_api_login.go(107)+auth_api_register.go(96)
- settings_controller.go(289→101): 拆出settings_api_profile(116)+account(59)+error_handlers(41)
- message_controller.go(129→85): 拆出message_page_controller.go(55)
- 所有拆分后文件均≤120行,符合code-style.md瘦控制器规范
|
2026-05-27 13:57:08 +08:00 |
|
|
|
0cc903b44a
|
refactor: 修复DRY分页 + LoD违规(RefreshToken业务逻辑下沉)
- audit_service.List()使用common.Pagination替代手动分页计算
- RefreshToken封禁状态检查从控制器移至TokenService.RefreshAccessToken
- 消除控制器层业务逻辑,符合瘦控制器铁律
|
2026-05-27 13:53:51 +08:00 |
|
|
|
0800ee2f3e
|
feat: 消息通知中心 + 账号安全体系 + Bug修复
## 新增功能
### 消息通知中心 (全新模块)
- 新增 MessageController / NotificationService / NotificationRepo
- SSR 消息页面 (/messages):左侧边栏 + 右侧卡片列表,noindex 元标签
- 通知能力:列表分页、单条标为已读、一键全部标为已读
- 未读数角标 (1/66/99+):侧边栏 + 导航栏铃铛图标
- 导航栏轮询 /api/messages/unread 每 60 秒刷新未读数
- 审核通过/驳回时自动 fire-and-forget 推送通知
### 密码修改
- ChangePassword:验证当前密码 → 新密码强度校验(8位+字母+数字) → 哈希更新
- 修改后递增 token_version 强制所有设备退登
### 账号自助注销
- DeleteAccount:验证密码 → 设置 deleted 状态 → 记录原因 → 吊销 JWT
- 注销后登录二次确认:Login 检测 deleted → 返回 confirm_restore
- ConfirmRestore 恢复账号,重新签发 token
- 注销页文案:"账号将在 7 天后正式注销,期间可随时重新登录恢复"
### IP 审计记录
- 注册时记录 RegIP,登录时记录 LastLoginIP + LastLoginAt
- clientIP() 支持 X-Forwarded-For / X-Real-IP 反向代理
### 安全加固
- Login 防时序攻击:用户不存在时仍执行完整 bcrypt 比对
- FindByEmail 改用 Unscoped() 覆盖软删除用户
- 站长 (owner) 不允许自主注销,避免权限体系死锁
## Bug 修复
1. 注销按钮不触发:JS IIFE 中 profile 代码 return 阻塞了 account 标签页处理器注册
→ 拆分为两层 IIFE,profile 放在内层
2. label 缺少 for 属性导致控制台警告 → 全部补充 for 属性
3. 注销后未自动退登:DeleteAccount 只设状态未吊销 JWT → 末尾加 InvalidateSessions
4. 退登后重定向 500 panic:authenticateToken 中 err||versionMismatch 合并判断
在 err=nil 但版本不匹配时返回 (nil,nil) → 拆为两个独立判断
injectUserContext 增加 claims==nil / 类型断言空安全守卫
5. 注销后登录直接提示"登录成功":FindByEmail 默认 scope 排除软删除记录
→ 改用 Unscoped()
## 文件变更
- 新建 17 个文件 (消息/审核/站点设置完整模块)
- 修改 25 个文件 (认证/设置/中间件/前端)
- 统计:+3229 / -161,42 files changed
|
2026-05-27 13:32:45 +08:00 |
|
|
|
39d13993ba
|
fix: 设计原则审查修复 — DIP/ISP, LoD, DRY, OCP, URL, 301缓存
- P0 DIP+ISP: 全链路注入接口,消除零接口紧耦合
- P0 URL: auth 301→302,修复登出后浏览器缓存陷阱
- P1 DRY: JWT 认证逻辑收敛至 TokenService+中间件
- P2 DRY: 前后端角色/状态映射统一为 model 常量
- P2 LoD: 新增 SettingsController,router 不再跨层调 repo
- P2 URL: settings ?tab= → /settings/:tab 伪静态
- P3 OCP: 角色权限 map 化,告别硬编码 switch
|
2026-05-26 21:12:19 +08:00 |
|
|
|
483fdd919f
|
初始化项目:基础设施 + 用户认证 + 后台管理系统 + AGPL 3.0 许可
|
2026-05-26 13:46:33 +08:00 |
|