feat: bind device limit
This commit is contained in:
parent
ec0a0f968e
commit
23ef9dbff1
@ -152,6 +152,7 @@ type (
|
||||
EnableIpRegisterLimit bool `json:"enable_ip_register_limit"`
|
||||
IpRegisterLimit int64 `json:"ip_register_limit"`
|
||||
IpRegisterLimitDuration int64 `json:"ip_register_limit_duration"`
|
||||
DeviceLimit int64 `json:"device_limit"`
|
||||
}
|
||||
VerifyConfig {
|
||||
TurnstileSiteKey string `json:"turnstile_site_key"`
|
||||
@ -456,6 +457,7 @@ type (
|
||||
SubscribePlan int64 `json:"subscribe_plan"`
|
||||
UnitTime string `json:"unit_time"`
|
||||
Quantity int64 `json:"quantity"`
|
||||
Status int64 `json:"status"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at"`
|
||||
}
|
||||
|
||||
@ -73,6 +73,7 @@ type RegisterConfig struct {
|
||||
IpRegisterLimit int64 `yaml:"IpRegisterLimit" default:"0"`
|
||||
IpRegisterLimitDuration int64 `yaml:"IpRegisterLimitDuration" default:"0"`
|
||||
EnableIpRegisterLimit bool `yaml:"EnableIpRegisterLimit" default:"false"`
|
||||
DeviceLimit int64 `yaml:"DeviceLimit" default:"5"`
|
||||
}
|
||||
|
||||
type EmailConfig struct {
|
||||
|
||||
@ -89,6 +89,36 @@ func (l *BindDeviceLogic) createDeviceForUser(identifier, ip, userAgent string,
|
||||
logger.Field("user_id", userId),
|
||||
)
|
||||
|
||||
// Check device limit
|
||||
deviceLimit := l.svcCtx.Config.Register.DeviceLimit
|
||||
if deviceLimit > 0 {
|
||||
// Count current user's devices
|
||||
var deviceCount int64
|
||||
if err := l.svcCtx.DB.Model(&user.Device{}).Where("user_id = ?", userId).Count(&deviceCount).Error; err != nil {
|
||||
l.Errorw("failed to count user devices",
|
||||
logger.Field("user_id", userId),
|
||||
logger.Field("error", err.Error()),
|
||||
)
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "count devices failed: %v", err.Error())
|
||||
}
|
||||
|
||||
// Check if limit reached
|
||||
if deviceCount >= deviceLimit {
|
||||
l.Errorw("device limit reached",
|
||||
logger.Field("user_id", userId),
|
||||
logger.Field("device_count", deviceCount),
|
||||
logger.Field("device_limit", deviceLimit),
|
||||
)
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "device limit reached: maximum %d devices allowed", deviceLimit)
|
||||
}
|
||||
|
||||
l.Infow("device limit check passed",
|
||||
logger.Field("user_id", userId),
|
||||
logger.Field("device_count", deviceCount),
|
||||
logger.Field("device_limit", deviceLimit),
|
||||
)
|
||||
}
|
||||
|
||||
err := l.svcCtx.UserModel.Transaction(l.ctx, func(db *gorm.DB) error {
|
||||
// Create device auth method
|
||||
authMethod := &user.AuthMethods{
|
||||
@ -147,6 +177,37 @@ func (l *BindDeviceLogic) createDeviceForUser(identifier, ip, userAgent string,
|
||||
|
||||
func (l *BindDeviceLogic) rebindDeviceToNewUser(deviceInfo *user.Device, ip, userAgent string, newUserId int64) error {
|
||||
oldUserId := deviceInfo.UserId
|
||||
|
||||
// Check device limit for new user
|
||||
deviceLimit := l.svcCtx.Config.Register.DeviceLimit
|
||||
if deviceLimit > 0 {
|
||||
// Count new user's current devices (excluding the one being rebound)
|
||||
var deviceCount int64
|
||||
if err := l.svcCtx.DB.Model(&user.Device{}).Where("user_id = ? AND id != ?", newUserId, deviceInfo.Id).Count(&deviceCount).Error; err != nil {
|
||||
l.Errorw("failed to count new user devices",
|
||||
logger.Field("user_id", newUserId),
|
||||
logger.Field("error", err.Error()),
|
||||
)
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "count devices failed: %v", err.Error())
|
||||
}
|
||||
|
||||
// Check if limit reached
|
||||
if deviceCount >= deviceLimit {
|
||||
l.Errorw("device limit reached for new user",
|
||||
logger.Field("user_id", newUserId),
|
||||
logger.Field("device_count", deviceCount),
|
||||
logger.Field("device_limit", deviceLimit),
|
||||
)
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "device limit reached: maximum %d devices allowed", deviceLimit)
|
||||
}
|
||||
|
||||
l.Infow("device limit check passed for rebinding",
|
||||
logger.Field("user_id", newUserId),
|
||||
logger.Field("device_count", deviceCount),
|
||||
logger.Field("device_limit", deviceLimit),
|
||||
)
|
||||
}
|
||||
|
||||
var users []*user.User
|
||||
err := l.svcCtx.DB.Where("id in (?)", []int64{oldUserId, newUserId}).Find(&users).Error
|
||||
if err != nil {
|
||||
|
||||
@ -1836,6 +1836,7 @@ type RedemptionCode struct {
|
||||
SubscribePlan int64 `json:"subscribe_plan"`
|
||||
UnitTime string `json:"unit_time"`
|
||||
Quantity int64 `json:"quantity"`
|
||||
Status int64 `json:"status"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at"`
|
||||
}
|
||||
@ -1860,6 +1861,7 @@ type RegisterConfig struct {
|
||||
EnableIpRegisterLimit bool `json:"enable_ip_register_limit"`
|
||||
IpRegisterLimit int64 `json:"ip_register_limit"`
|
||||
IpRegisterLimitDuration int64 `json:"ip_register_limit_duration"`
|
||||
DeviceLimit int64 `json:"device_limit"`
|
||||
}
|
||||
|
||||
type RegisterLog struct {
|
||||
@ -2318,6 +2320,11 @@ type ToggleNodeStatusRequest struct {
|
||||
Enable *bool `json:"enable"`
|
||||
}
|
||||
|
||||
type ToggleRedemptionCodeStatusRequest struct {
|
||||
Id int64 `json:"id" validate:"required"`
|
||||
Status int64 `json:"status" validate:"oneof=0 1"`
|
||||
}
|
||||
|
||||
type ToggleUserSubscribeStatusRequest struct {
|
||||
UserSubscribeId int64 `json:"user_subscribe_id"`
|
||||
}
|
||||
@ -2494,6 +2501,7 @@ type UpdateRedemptionCodeRequest struct {
|
||||
SubscribePlan int64 `json:"subscribe_plan,omitempty"`
|
||||
UnitTime string `json:"unit_time,omitempty" validate:"omitempty,oneof=day month quarter half_year year"`
|
||||
Quantity int64 `json:"quantity,omitempty"`
|
||||
Status int64 `json:"status,omitempty" validate:"omitempty,oneof=0 1"`
|
||||
}
|
||||
|
||||
type UpdateServerRequest struct {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user