feat(backend): 首次登录无有效授权时自动发放 30 天试用
未激活门店(seed/手动建店/老数据,无任何 license 行)此前被当作永久授权, 既不拦截也无提示。现在登录时若门店无有效授权,自动签发 30 天 trial, 之后照常走 grace/readonly/locked 降级链。须在 issueTokens 之前发放, 使 JWT 的 lic_exp 带上新到期日。幂等(已有有效授权不重发),签发失败 仅记日志不阻断登录。复用注册路径的发放逻辑(抽出 issueTrialLicense)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y2Wdwo7SmgBJU37cBrkhPK
This commit is contained in:
@@ -143,12 +143,13 @@ func (s *LicenseService) Deactivate(shopID uint64, deviceID string) error {
|
||||
Delete(&model.LicenseDevice{}).Error
|
||||
}
|
||||
|
||||
// createTrialLicense 在注册事务中为新门店签发 30 天 trial license。
|
||||
// 私钥未配置时 Fatal,防止生产环境静默跳过导致新注册门店无 license。
|
||||
func createTrialLicense(tx *gorm.DB, shopID uint64) {
|
||||
// issueTrialLicense 为门店签发并写入一条 30 天 trial license。
|
||||
// 私钥未配置或签发/落库失败时返回 error,由调用方决定如何处理(注册路径 Fatal、
|
||||
// 登录路径仅记日志)。
|
||||
func issueTrialLicense(db *gorm.DB, shopID uint64) error {
|
||||
privKey := config.C.License.Ed25519PrivateKey
|
||||
if privKey == "" {
|
||||
log.Fatalf("[license] Ed25519 private key not configured — cannot issue trial for shop %d; set License.Ed25519PrivateKey in config", shopID)
|
||||
return fmt.Errorf("ed25519 private key not configured")
|
||||
}
|
||||
|
||||
expiresAt := time.Now().Add(30 * 24 * time.Hour)
|
||||
@@ -162,8 +163,7 @@ func createTrialLicense(tx *gorm.DB, shopID uint64) {
|
||||
}
|
||||
token, err := util.IssueLicenseToken(payload, privKey)
|
||||
if err != nil {
|
||||
log.Printf("[license] failed to issue trial token for shop %d: %v", shopID, err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
lic := model.License{
|
||||
@@ -174,7 +174,16 @@ func createTrialLicense(tx *gorm.DB, shopID uint64) {
|
||||
IsActive: true,
|
||||
MaxDevices: 1,
|
||||
}
|
||||
if err := tx.Create(&lic).Error; err != nil {
|
||||
return db.Create(&lic).Error
|
||||
}
|
||||
|
||||
// createTrialLicense 在注册事务中为新门店签发 30 天 trial license。
|
||||
// 私钥未配置时 Fatal,防止生产环境静默跳过导致新注册门店无 license。
|
||||
func createTrialLicense(tx *gorm.DB, shopID uint64) {
|
||||
if config.C.License.Ed25519PrivateKey == "" {
|
||||
log.Fatalf("[license] Ed25519 private key not configured — cannot issue trial for shop %d; set License.Ed25519PrivateKey in config", shopID)
|
||||
}
|
||||
if err := issueTrialLicense(tx, shopID); err != nil {
|
||||
log.Printf("[license] failed to create trial license for shop %d: %v", shopID, err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user