fix gitea workflow path and runner label
Some checks failed
Build docker and publish / build (20.15.1) (push) Failing after 8m1s
Some checks failed
Build docker and publish / build (20.15.1) (push) Failing after 8m1s
This commit is contained in:
parent
0c544268e5
commit
6c370485d1
47
initialize/migrate/database/02136_verify_code_unify.down.sql
Normal file
47
initialize/migrate/database/02136_verify_code_unify.down.sql
Normal file
@ -0,0 +1,47 @@
|
||||
INSERT INTO `system` (`category`, `key`, `value`, `type`, `desc`, `created_at`, `updated_at`)
|
||||
SELECT 'verify_code',
|
||||
'ExpireTime',
|
||||
COALESCE(MAX(CASE WHEN `key` = 'VerifyCodeExpireTime' THEN `value` END), '900'),
|
||||
'int',
|
||||
'Verify code expire time (legacy)',
|
||||
NOW(3),
|
||||
NOW(3)
|
||||
FROM `system`
|
||||
WHERE `category` = 'verify_code'
|
||||
ON DUPLICATE KEY UPDATE
|
||||
`value` = VALUES(`value`),
|
||||
`type` = VALUES(`type`),
|
||||
`desc` = VALUES(`desc`),
|
||||
`updated_at` = VALUES(`updated_at`);
|
||||
|
||||
INSERT INTO `system` (`category`, `key`, `value`, `type`, `desc`, `created_at`, `updated_at`)
|
||||
SELECT 'verify_code',
|
||||
'Limit',
|
||||
COALESCE(MAX(CASE WHEN `key` = 'VerifyCodeLimit' THEN `value` END), '15'),
|
||||
'int',
|
||||
'Verify code limit (legacy)',
|
||||
NOW(3),
|
||||
NOW(3)
|
||||
FROM `system`
|
||||
WHERE `category` = 'verify_code'
|
||||
ON DUPLICATE KEY UPDATE
|
||||
`value` = VALUES(`value`),
|
||||
`type` = VALUES(`type`),
|
||||
`desc` = VALUES(`desc`),
|
||||
`updated_at` = VALUES(`updated_at`);
|
||||
|
||||
INSERT INTO `system` (`category`, `key`, `value`, `type`, `desc`, `created_at`, `updated_at`)
|
||||
SELECT 'verify_code',
|
||||
'Interval',
|
||||
COALESCE(MAX(CASE WHEN `key` = 'VerifyCodeInterval' THEN `value` END), '60'),
|
||||
'int',
|
||||
'Verify code interval (legacy)',
|
||||
NOW(3),
|
||||
NOW(3)
|
||||
FROM `system`
|
||||
WHERE `category` = 'verify_code'
|
||||
ON DUPLICATE KEY UPDATE
|
||||
`value` = VALUES(`value`),
|
||||
`type` = VALUES(`type`),
|
||||
`desc` = VALUES(`desc`),
|
||||
`updated_at` = VALUES(`updated_at`);
|
||||
@ -0,0 +1,4 @@
|
||||
DELETE
|
||||
FROM `system`
|
||||
WHERE `category` = 'verify_code'
|
||||
AND `key` IN ('ExpireTime', 'Limit', 'Interval');
|
||||
@ -44,5 +44,22 @@ func Verify(svc *svc.ServiceContext) {
|
||||
return
|
||||
}
|
||||
tool.SystemConfigSliceReflectToStruct(cfg, &verifyCodeConfig)
|
||||
applyVerifyCodeDefaults(&verifyCodeConfig)
|
||||
svc.Config.VerifyCode = verifyCodeConfig
|
||||
}
|
||||
|
||||
func applyVerifyCodeDefaults(cfg *config.VerifyCode) {
|
||||
if cfg == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if cfg.VerifyCodeExpireTime <= 0 {
|
||||
cfg.VerifyCodeExpireTime = 900
|
||||
}
|
||||
if cfg.VerifyCodeLimit <= 0 {
|
||||
cfg.VerifyCodeLimit = 15
|
||||
}
|
||||
if cfg.VerifyCodeInterval <= 0 {
|
||||
cfg.VerifyCodeInterval = 60
|
||||
}
|
||||
}
|
||||
|
||||
94
initialize/verify_test.go
Normal file
94
initialize/verify_test.go
Normal file
@ -0,0 +1,94 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/perfect-panel/server/internal/config"
|
||||
"github.com/perfect-panel/server/internal/model/system"
|
||||
"github.com/perfect-panel/server/pkg/tool"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestApplyVerifyCodeDefaults(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
in config.VerifyCode
|
||||
want config.VerifyCode
|
||||
}{
|
||||
{
|
||||
name: "apply defaults when all zero",
|
||||
in: config.VerifyCode{},
|
||||
want: config.VerifyCode{
|
||||
VerifyCodeExpireTime: 900,
|
||||
VerifyCodeLimit: 15,
|
||||
VerifyCodeInterval: 60,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "keep provided values",
|
||||
in: config.VerifyCode{
|
||||
VerifyCodeExpireTime: 901,
|
||||
VerifyCodeLimit: 16,
|
||||
VerifyCodeInterval: 61,
|
||||
},
|
||||
want: config.VerifyCode{
|
||||
VerifyCodeExpireTime: 901,
|
||||
VerifyCodeLimit: 16,
|
||||
VerifyCodeInterval: 61,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "fix invalid non-positive values",
|
||||
in: config.VerifyCode{
|
||||
VerifyCodeExpireTime: -1,
|
||||
VerifyCodeLimit: 0,
|
||||
VerifyCodeInterval: -10,
|
||||
},
|
||||
want: config.VerifyCode{
|
||||
VerifyCodeExpireTime: 900,
|
||||
VerifyCodeLimit: 15,
|
||||
VerifyCodeInterval: 60,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
got := testCase.in
|
||||
applyVerifyCodeDefaults(&got)
|
||||
assert.Equal(t, testCase.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyCodeReflectUsesCanonicalKeys(t *testing.T) {
|
||||
configs := []*system.System{
|
||||
{Category: "verify_code", Key: "VerifyCodeExpireTime", Value: "901"},
|
||||
{Category: "verify_code", Key: "VerifyCodeLimit", Value: "16"},
|
||||
{Category: "verify_code", Key: "VerifyCodeInterval", Value: "61"},
|
||||
}
|
||||
|
||||
var got config.VerifyCode
|
||||
tool.SystemConfigSliceReflectToStruct(configs, &got)
|
||||
applyVerifyCodeDefaults(&got)
|
||||
|
||||
assert.Equal(t, int64(901), got.VerifyCodeExpireTime)
|
||||
assert.Equal(t, int64(16), got.VerifyCodeLimit)
|
||||
assert.Equal(t, int64(61), got.VerifyCodeInterval)
|
||||
}
|
||||
|
||||
func TestVerifyCodeReflectIgnoresLegacyKeys(t *testing.T) {
|
||||
configs := []*system.System{
|
||||
{Category: "verify_code", Key: "ExpireTime", Value: "901"},
|
||||
{Category: "verify_code", Key: "Limit", Value: "16"},
|
||||
{Category: "verify_code", Key: "Interval", Value: "61"},
|
||||
}
|
||||
|
||||
var got config.VerifyCode
|
||||
tool.SystemConfigSliceReflectToStruct(configs, &got)
|
||||
applyVerifyCodeDefaults(&got)
|
||||
|
||||
assert.Equal(t, int64(900), got.VerifyCodeExpireTime)
|
||||
assert.Equal(t, int64(15), got.VerifyCodeLimit)
|
||||
assert.Equal(t, int64(60), got.VerifyCodeInterval)
|
||||
}
|
||||
@ -9,32 +9,32 @@ import (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Model string `yaml:"Model" default:"prod"`
|
||||
Host string `yaml:"Host" default:"0.0.0.0"`
|
||||
Port int `yaml:"Port" default:"8080"`
|
||||
Debug bool `yaml:"Debug" default:"false"`
|
||||
TLS TLS `yaml:"TLS"`
|
||||
JwtAuth JwtAuth `yaml:"JwtAuth"`
|
||||
Logger logger.LogConf `yaml:"Logger"`
|
||||
MySQL orm.Config `yaml:"MySQL"`
|
||||
Redis RedisConfig `yaml:"Redis"`
|
||||
Site SiteConfig `yaml:"Site"`
|
||||
Node NodeConfig `yaml:"Node"`
|
||||
Mobile MobileConfig `yaml:"Mobile"`
|
||||
Email EmailConfig `yaml:"Email"`
|
||||
Device DeviceConfig `yaml:"device"`
|
||||
Verify Verify `yaml:"Verify"`
|
||||
VerifyCode VerifyCode `yaml:"VerifyCode"`
|
||||
Register RegisterConfig `yaml:"Register"`
|
||||
Subscribe SubscribeConfig `yaml:"Subscribe"`
|
||||
Invite InviteConfig `yaml:"Invite"`
|
||||
Model string `yaml:"Model" default:"prod"`
|
||||
Host string `yaml:"Host" default:"0.0.0.0"`
|
||||
Port int `yaml:"Port" default:"8080"`
|
||||
Debug bool `yaml:"Debug" default:"false"`
|
||||
TLS TLS `yaml:"TLS"`
|
||||
JwtAuth JwtAuth `yaml:"JwtAuth"`
|
||||
Logger logger.LogConf `yaml:"Logger"`
|
||||
MySQL orm.Config `yaml:"MySQL"`
|
||||
Redis RedisConfig `yaml:"Redis"`
|
||||
Site SiteConfig `yaml:"Site"`
|
||||
Node NodeConfig `yaml:"Node"`
|
||||
Mobile MobileConfig `yaml:"Mobile"`
|
||||
Email EmailConfig `yaml:"Email"`
|
||||
Device DeviceConfig `yaml:"device"`
|
||||
Verify Verify `yaml:"Verify"`
|
||||
VerifyCode VerifyCode `yaml:"VerifyCode"`
|
||||
Register RegisterConfig `yaml:"Register"`
|
||||
Subscribe SubscribeConfig `yaml:"Subscribe"`
|
||||
Invite InviteConfig `yaml:"Invite"`
|
||||
Kutt KuttConfig `yaml:"Kutt"`
|
||||
OpenInstall OpenInstallConfig `yaml:"OpenInstall"`
|
||||
Loki LokiConfig `yaml:"Loki"`
|
||||
Telegram Telegram `yaml:"Telegram"`
|
||||
Log Log `yaml:"Log"`
|
||||
Currency Currency `yaml:"Currency"`
|
||||
Trace trace.Config `yaml:"Trace"`
|
||||
Telegram Telegram `yaml:"Telegram"`
|
||||
Log Log `yaml:"Log"`
|
||||
Currency Currency `yaml:"Currency"`
|
||||
Trace trace.Config `yaml:"Trace"`
|
||||
Administrator struct {
|
||||
Email string `yaml:"Email" default:"admin@ppanel.dev"`
|
||||
Password string `yaml:"Password" default:"password"`
|
||||
@ -261,9 +261,9 @@ type TLS struct {
|
||||
}
|
||||
|
||||
type VerifyCode struct {
|
||||
ExpireTime int64 `yaml:"ExpireTime" default:"900"`
|
||||
Limit int64 `yaml:"Limit" default:"15"`
|
||||
Interval int64 `yaml:"Interval" default:"60"`
|
||||
VerifyCodeExpireTime int64 `yaml:"VerifyCodeExpireTime" default:"900"`
|
||||
VerifyCodeLimit int64 `yaml:"VerifyCodeLimit" default:"15"`
|
||||
VerifyCodeInterval int64 `yaml:"VerifyCodeInterval" default:"60"`
|
||||
}
|
||||
|
||||
type Log struct {
|
||||
|
||||
@ -73,7 +73,7 @@ func verifyEmailCode(ctx context.Context, serverCtx *svc.ServiceContext, email s
|
||||
continue
|
||||
}
|
||||
// 检查验证码是否匹配且未过期
|
||||
if payload.Code == code && time.Now().Unix()-payload.LastAt <= serverCtx.Config.VerifyCode.ExpireTime {
|
||||
if payload.Code == code && time.Now().Unix()-payload.LastAt <= serverCtx.Config.VerifyCode.VerifyCodeExpireTime {
|
||||
verified = true
|
||||
cacheKeyUsed = cacheKey
|
||||
break
|
||||
|
||||
@ -74,7 +74,7 @@ func TestDeleteAccountHandlerVerifyCodeErrorUsesUnifiedResponse(t *testing.T) {
|
||||
Redis: redisClient,
|
||||
Config: config.Config{
|
||||
VerifyCode: config.VerifyCode{
|
||||
ExpireTime: 900,
|
||||
VerifyCodeExpireTime: 900,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ func (l *EmailLoginLogic) EmailLogin(req *types.EmailLoginRequest) (resp *types.
|
||||
if err := json.Unmarshal([]byte(value), &payload); err != nil {
|
||||
continue
|
||||
}
|
||||
if payload.Code == req.Code && time.Now().Unix()-payload.LastAt <= l.svcCtx.Config.VerifyCode.ExpireTime {
|
||||
if payload.Code == req.Code && time.Now().Unix()-payload.LastAt <= l.svcCtx.Config.VerifyCode.VerifyCodeExpireTime {
|
||||
verified = true
|
||||
cacheKeyUsed = cacheKey
|
||||
break
|
||||
|
||||
@ -85,7 +85,7 @@ func (l *ResetPasswordLogic) ResetPassword(req *types.ResetPasswordRequest) (res
|
||||
l.Errorw("Verification code error", logger.Field("cacheKey", cacheKey), logger.Field("error", "Verification code error"), logger.Field("reqCode", req.Code), logger.Field("payloadCode", payload.Code))
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "Verification code error")
|
||||
}
|
||||
if time.Now().Unix()-payload.LastAt > l.svcCtx.Config.VerifyCode.ExpireTime {
|
||||
if time.Now().Unix()-payload.LastAt > l.svcCtx.Config.VerifyCode.VerifyCodeExpireTime {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code expired")
|
||||
}
|
||||
l.svcCtx.Redis.Del(l.ctx, cacheKey)
|
||||
|
||||
@ -80,7 +80,7 @@ func (l *UserRegisterLogic) UserRegister(req *types.UserRegisterRequest) (resp *
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
||||
}
|
||||
// 校验有效期
|
||||
if time.Now().Unix()-payload.LastAt > l.svcCtx.Config.VerifyCode.ExpireTime {
|
||||
if time.Now().Unix()-payload.LastAt > l.svcCtx.Config.VerifyCode.VerifyCodeExpireTime {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code expired")
|
||||
}
|
||||
l.svcCtx.Redis.Del(l.ctx, cacheKey)
|
||||
|
||||
@ -92,7 +92,7 @@ func (l *SendEmailCodeLogic) SendEmailCode(req *types.SendCodeRequest) (resp *ty
|
||||
taskPayload.Email = req.Email
|
||||
taskPayload.Subject = "Verification code"
|
||||
|
||||
expireTime := l.svcCtx.Config.VerifyCode.ExpireTime
|
||||
expireTime := l.svcCtx.Config.VerifyCode.VerifyCodeExpireTime
|
||||
if expireTime == 0 {
|
||||
expireTime = 900
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ func (l *SendSmsCodeLogic) SendSmsCode(req *types.SendSmsCodeRequest) (resp *typ
|
||||
}
|
||||
// Marshal the payload
|
||||
val, _ := json.Marshal(payload)
|
||||
if err = l.svcCtx.Redis.Set(l.ctx, cacheKey, string(val), time.Second*time.Duration(l.svcCtx.Config.VerifyCode.ExpireTime)).Err(); err != nil {
|
||||
if err = l.svcCtx.Redis.Set(l.ctx, cacheKey, string(val), time.Second*time.Duration(l.svcCtx.Config.VerifyCode.VerifyCodeExpireTime)).Err(); err != nil {
|
||||
l.Errorw("[SendSmsCode]: Redis Error", logger.Field("error", err.Error()), logger.Field("cacheKey", cacheKey))
|
||||
return nil, errors.Wrap(xerr.NewErrCode(xerr.ERROR), "Failed to set verification code")
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ func (l *BindEmailWithVerificationLogic) BindEmailWithVerification(req *types.Bi
|
||||
if err := json.Unmarshal([]byte(value), &p); err != nil {
|
||||
continue
|
||||
}
|
||||
if p.Code == req.Code && time.Now().Unix()-p.LastAt <= l.svcCtx.Config.VerifyCode.ExpireTime {
|
||||
if p.Code == req.Code && time.Now().Unix()-p.LastAt <= l.svcCtx.Config.VerifyCode.VerifyCodeExpireTime {
|
||||
_ = l.svcCtx.Redis.Del(l.ctx, cacheKey).Err()
|
||||
verified = true
|
||||
break
|
||||
|
||||
@ -55,7 +55,7 @@ func (l *VerifyEmailLogic) VerifyEmail(req *types.VerifyEmailRequest) error {
|
||||
if payload.Code != req.Code {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code error")
|
||||
}
|
||||
if time.Now().Unix()-payload.LastAt > l.svcCtx.Config.VerifyCode.ExpireTime {
|
||||
if time.Now().Unix()-payload.LastAt > l.svcCtx.Config.VerifyCode.VerifyCodeExpireTime {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "code expired")
|
||||
}
|
||||
l.svcCtx.Redis.Del(l.ctx, cacheKey)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user