Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop
This commit is contained in:
commit
eccd674bc5
1
go.mod
1
go.mod
|
@ -28,7 +28,6 @@ require (
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go/compute v1.20.1 // indirect
|
cloud.google.com/go/compute v1.20.1 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||||
github.com/474420502/execute v0.2.2 // indirect
|
|
||||||
github.com/DataDog/zstd v1.4.5 // indirect
|
github.com/DataDog/zstd v1.4.5 // indirect
|
||||||
github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect
|
github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect
|
||||||
github.com/VictoriaMetrics/metrics v1.18.1 // indirect
|
github.com/VictoriaMetrics/metrics v1.18.1 // indirect
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -35,8 +35,6 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
|
||||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
github.com/474420502/execute v0.2.2 h1:Hzzb/HFa/urRvi3xWe+p/DnJgRyxXFVyEBEXbbITy/E=
|
|
||||||
github.com/474420502/execute v0.2.2/go.mod h1:wkKeKBIXYp7T844eU1YS2nPvFj8lra4VRcQYnWyXej4=
|
|
||||||
github.com/474420502/passer v0.0.1 h1:ZWnt7hpFzsYDV7LHSEyLvLUvW5mRxrnDmgFdIl17q3w=
|
github.com/474420502/passer v0.0.1 h1:ZWnt7hpFzsYDV7LHSEyLvLUvW5mRxrnDmgFdIl17q3w=
|
||||||
github.com/474420502/passer v0.0.1/go.mod h1:MmnnrF9d51sPkFzdRq2pQtxQKqyjburVM1LjMbOCezE=
|
github.com/474420502/passer v0.0.1/go.mod h1:MmnnrF9d51sPkFzdRq2pQtxQKqyjburVM1LjMbOCezE=
|
||||||
github.com/474420502/random v0.4.1 h1:HUUyLXRWMijVb7CJoEC16f0aFQOW25Lkr80Mut6PoKU=
|
github.com/474420502/random v0.4.1 h1:HUUyLXRWMijVb7CJoEC16f0aFQOW25Lkr80Mut6PoKU=
|
||||||
|
|
|
@ -2,6 +2,7 @@ package logic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fusenapi/utils/check"
|
||||||
"log"
|
"log"
|
||||||
"net/smtp"
|
"net/smtp"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -9,8 +10,35 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var TimeLimit *check.TimeLimit[string]
|
||||||
var EmailManager *EmailSender
|
var EmailManager *EmailSender
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
|
||||||
|
TimeLimit = check.NewTimelimit[string](time.Second * 25)
|
||||||
|
|
||||||
|
// Initialize the email manager
|
||||||
|
EmailManager = &EmailSender{
|
||||||
|
EmailTasks: make(chan *EmailFormat, 10),
|
||||||
|
Auth: smtp.PlainAuth(
|
||||||
|
"",
|
||||||
|
"support@fusenpack.com",
|
||||||
|
"wfbjpdgvaozjvwah",
|
||||||
|
"smtp.gmail.com",
|
||||||
|
),
|
||||||
|
FromEmail: "support@fusenpack.com",
|
||||||
|
emailSending: make(map[string]*EmailTask, 10),
|
||||||
|
ResendTimeLimit: time.Minute * 1,
|
||||||
|
semaphore: make(chan struct{}, 10), // Initialize semaphore with a capacity of 10
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start processing email tasks
|
||||||
|
go EmailManager.ProcessEmailTasks()
|
||||||
|
|
||||||
|
// Start clearing expired tasks
|
||||||
|
go EmailManager.ClearExpiredTasks()
|
||||||
|
}
|
||||||
|
|
||||||
type EmailFormat struct {
|
type EmailFormat struct {
|
||||||
TargetEmail string // 发送的目标email
|
TargetEmail string // 发送的目标email
|
||||||
CompanyName string // fs公司名
|
CompanyName string // fs公司名
|
||||||
|
@ -110,30 +138,6 @@ func (m *EmailSender) ClearExpiredTasks() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
|
|
||||||
// Initialize the email manager
|
|
||||||
EmailManager = &EmailSender{
|
|
||||||
EmailTasks: make(chan *EmailFormat, 10),
|
|
||||||
Auth: smtp.PlainAuth(
|
|
||||||
"",
|
|
||||||
"support@fusenpack.com",
|
|
||||||
"wfbjpdgvaozjvwah",
|
|
||||||
"smtp.gmail.com",
|
|
||||||
),
|
|
||||||
FromEmail: "support@fusenpack.com",
|
|
||||||
emailSending: make(map[string]*EmailTask, 10),
|
|
||||||
ResendTimeLimit: time.Minute * 1,
|
|
||||||
semaphore: make(chan struct{}, 10), // Initialize semaphore with a capacity of 10
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start processing email tasks
|
|
||||||
go EmailManager.ProcessEmailTasks()
|
|
||||||
|
|
||||||
// Start clearing expired tasks
|
|
||||||
go EmailManager.ClearExpiredTasks()
|
|
||||||
}
|
|
||||||
|
|
||||||
const emailTemplate = `Subject: Your {{.CompanyName}} Account Confirmation
|
const emailTemplate = `Subject: Your {{.CompanyName}} Account Confirmation
|
||||||
|
|
||||||
Dear
|
Dear
|
||||||
|
|
|
@ -47,6 +47,10 @@ func (l *UserEmailRegisterLogic) UserEmailRegister(req *types.RequestEmailRegist
|
||||||
return resp.SetStatus(basic.CodeOAuthEmailErr)
|
return resp.SetStatus(basic.CodeOAuthEmailErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !TimeLimit.Is(req.Email) {
|
||||||
|
return resp.SetStatus(basic.CodeEmailTimeShortErr)
|
||||||
|
}
|
||||||
|
|
||||||
token, err := l.svcCtx.OAuthTokenManger.Decrypt(req.RegisterToken)
|
token, err := l.svcCtx.OAuthTokenManger.Decrypt(req.RegisterToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
|
|
|
@ -46,6 +46,10 @@ func (l *UserRegisterLogic) UserRegister(req *types.RequestUserRegister, userinf
|
||||||
return resp.SetStatus(basic.CodeEmailExistsErr)
|
return resp.SetStatus(basic.CodeEmailExistsErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !TimeLimit.Is(req.Email) {
|
||||||
|
return resp.SetStatus(basic.CodeEmailTimeShortErr)
|
||||||
|
}
|
||||||
|
|
||||||
token := &auth.RegisterToken{
|
token := &auth.RegisterToken{
|
||||||
OperateType: auth.OpTypeRegister,
|
OperateType: auth.OpTypeRegister,
|
||||||
GuestId: userinfo.GuestId,
|
GuestId: userinfo.GuestId,
|
||||||
|
|
|
@ -52,10 +52,11 @@ var (
|
||||||
CodeS3PutSizeLimitErr = &StatusResponse{5061, "s3 over limit size error"} // s3 超过文件大小限制 错误
|
CodeS3PutSizeLimitErr = &StatusResponse{5061, "s3 over limit size error"} // s3 超过文件大小限制 错误
|
||||||
CodeS3CategoryErr = &StatusResponse{5062, "s3 category not exists error"} // s3 类别不存在 错误
|
CodeS3CategoryErr = &StatusResponse{5062, "s3 category not exists error"} // s3 类别不存在 错误
|
||||||
|
|
||||||
CodeEmailNotFoundErr = &StatusResponse{5050, "email not found"} // 未找到email
|
CodeEmailNotFoundErr = &StatusResponse{5050, "email not found"} // 未找到email
|
||||||
CodeUserIdNotFoundErr = &StatusResponse{5051, "user not found"} // 未找到用户
|
CodeUserIdNotFoundErr = &StatusResponse{5051, "user not found"} // 未找到用户
|
||||||
CodePasswordErr = &StatusResponse{5052, "invalid password"} // 无效密码
|
CodePasswordErr = &StatusResponse{5052, "invalid password"} // 无效密码
|
||||||
CodeEmailExistsErr = &StatusResponse{5053, "email exists"} // email存在
|
CodeEmailExistsErr = &StatusResponse{5053, "email exists"} // email存在
|
||||||
|
CodeEmailTimeShortErr = &StatusResponse{5053, "email with the time of resend is too short"} // email存在
|
||||||
|
|
||||||
CodeSafeValueRangeErr = &StatusResponse{5040, "value not in range"} // 值不在范围内
|
CodeSafeValueRangeErr = &StatusResponse{5040, "value not in range"} // 值不在范围内
|
||||||
CodeTemplateErr = &StatusResponse{5040, "template parsed error"} // 模板解析错误
|
CodeTemplateErr = &StatusResponse{5040, "template parsed error"} // 模板解析错误
|
||||||
|
|
|
@ -1,7 +1,53 @@
|
||||||
|
// Timeup是一个限制某个值的重复频率的工具
|
||||||
|
// 通过内部计时器实现限制同一个值的访问频率不超过指定时间间隔
|
||||||
package check
|
package check
|
||||||
|
|
||||||
import "sync"
|
import (
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
type LimitAfter struct {
|
// TimeLimit结构体包含需要限频的映射表,以及时间间隔
|
||||||
sync.Map
|
// 使用sync.Mutex保证对字典的线程安全访问
|
||||||
|
type TimeLimit[T comparable] struct {
|
||||||
|
mu sync.Mutex
|
||||||
|
dict map[T]struct{}
|
||||||
|
dur time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTimelimit构造函数,接收限频的时间间隔
|
||||||
|
// 并初始化内部字典和间隔字段
|
||||||
|
func NewTimelimit[T comparable](dur time.Duration) *TimeLimit[T] {
|
||||||
|
return &TimeLimit[T]{
|
||||||
|
dict: make(map[T]struct{}),
|
||||||
|
dur: dur,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithTime方法用于更新限频的时间间隔
|
||||||
|
func (tup *TimeLimit[T]) WithTime(dur time.Duration) *TimeLimit[T] {
|
||||||
|
tup.mu.Lock()
|
||||||
|
defer tup.mu.Unlock()
|
||||||
|
tup.dur = dur
|
||||||
|
return tup
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is方法检查传入值是否是一个新的值
|
||||||
|
// 首先会查询字典,如果存在则表示在间隔内已经访问过
|
||||||
|
// 否则将其添加到字典,并启动一个定时器在间隔后删除
|
||||||
|
// 返回true表示新值,false表示重复值
|
||||||
|
func (tup *TimeLimit[T]) Is(v T) bool {
|
||||||
|
tup.mu.Lock()
|
||||||
|
defer tup.mu.Unlock()
|
||||||
|
|
||||||
|
if _, ok := tup.dict[v]; ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
tup.dict[v] = struct{}{}
|
||||||
|
time.AfterFunc(tup.dur, func() {
|
||||||
|
tup.mu.Lock()
|
||||||
|
defer tup.mu.Unlock()
|
||||||
|
delete(tup.dict, v)
|
||||||
|
})
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user