wangjia
|
23dff69c62
|
feat(backend): 授权改为时长兑换券体系 + 退役 ed25519/HMAC + 平台生码工具
- 新增 license_codes 码池表 + model.LicenseCode;licenses 加 tier 档位列
- LicenseService.Redeem:单事务 FOR UPDATE 校验码未用 → 时长叠加(可叠加,0=永久)
→ 写 type/tier/max_devices → 绑设备(超限整笔回滚) → 标记已用 → 即时失效 phase 缓存
路由仍 POST /license/activate,客户端零破坏
- util.GenerateRedeemCode/NormalizeCode:JIUKU-XXXX-XXXX 短码(crypto/rand)
- cmd/gencode:平台批量生成兑换码并落库;删除 cmd/issue、cmd/genkey
- 退役 ed25519 + HMAC:删 util/license_key、GenerateKey、License 全部 config 字段
及生产启动私钥校验;trial 改直接建行(无需私钥、去 Fatal)
- tier 档位钩子默认 standard,分档消费模式后续设计
- 测试:Redeem 全场景(叠加/过期重置/永久/一码一次/无效/设备上限回滚)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-19 12:14:27 +08:00 |
|
wangjia
|
e41085a878
|
feat(backend): 会话安全加固 + 授权实时 phase + 首次使用自动试用
会话安全(jti 轮换 / 重用检测 / 改密吊销 / 禁用即时下线 / 清理 / 失败登录落库):
- refresh token 轮换 jti + token-family 重用检测,旧 token 重放即吊销整条会话
- 改密码、停用用户即时吊销其全部活跃会话(revoked_by 审计)
- 中间件 session JOIN user 校验,禁用/删除用户带 token 请求返回 401 USER_DISABLED
- 新增 login_attempts 失败登录落库 + 会话保留期清理 goroutine
授权实时 phase + 心跳回带:
- LicenseGuard 改为按当前 DB 实时计算 phase(30s 每店缓存),续费/过期/被改 ~30s 内对写操作生效,无需重登
- /auth/ping 回带授权概况(ShopInfoView,与 /license/info 同构),客户端一次心跳即刷新横幅/门禁
首次使用自动试用 + code-review 修复:
- 门店首次登录/续期无有效授权时自动签发 30 天 trial(快路径无锁 Count,仅首用走 FOR UPDATE 事务)
- ShopInfo 区分「确无授权」与瞬时 DB 错误,避免误降级
- trial 签发后改为在事务提交后再失效 phase 缓存(修复早于提交的竞态)
- 存量无 sid token 续期纳入显式上限,legacy 会话不再游离于并发配额之外
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-19 07:34:04 +08:00 |
|
wangjia
|
13fc9b7aaf
|
test(backend): 授权系统端到端验证测试 (21H)
util/license_key_test.go:
- TestLicenseKeyRoundTrip: 签发→验签完整流程
- TestVerifyLicenseToken_TamperedPayload: 签名被篡改后被拒绝
- TestVerifyLicenseToken_WrongKey: 用错误公钥验签失败
- TestVerifyLicenseToken_InvalidFormat: 格式非法被拒绝
middleware/license_guard_test.go:
- TestCalcLicensePhase: 覆盖全部 phase 边界
(perpetual→normal / future→normal / <7d→grace /
7-15d→readonly / >15d→locked)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-06-10 07:10:15 +08:00 |
|