Files
qwqcode cf7725edba refactor(go): bump the module version and support go install (#979)
BREAKING CHANGE: The original Go module name was `github.com/ArtalkJS/Artalk`, which has now been modified to `github.com/artalkjs/artalk/v2` (all lowercase). This change may affect the CI pipeline or other areas if you are compiling the Artalk server and have specified the fixed Go module name. Regarding the original `-ldflags -X github.com/ArtalkJS/Artalk/internal/config.Version` and `CommitHash` definitions, please remove them, as they are now obsolete. The `Version` has been hardcoded into the Go code, and the `CommitHash` is now read from the Go build info via runtime/debug’s vcs.revision value. This change only affects the server developers and does not impact the frontend UI client.
2024-09-18 21:43:43 +08:00

83 lines
1.8 KiB
Go

package common
import (
"fmt"
"github.com/artalkjs/artalk/v2/internal/captcha"
"github.com/artalkjs/artalk/v2/internal/core"
"github.com/artalkjs/artalk/v2/internal/i18n"
"github.com/artalkjs/artalk/v2/server/middleware/limiter"
"github.com/gofiber/fiber/v2"
)
func GetLimiter(c *fiber.Ctx) (lmt *limiter.Limiter, err error) {
l, ok := c.Locals("limiter").(*limiter.Limiter)
if l == nil || !ok {
return nil, RespError(c, 500, "limiter is not initialize, but middleware is used")
}
return l, nil
}
func NewCaptchaChecker(app *core.App, c *fiber.Ctx) captcha.Checker {
user, _ := GetUserByReq(app, c)
return captcha.NewCaptchaChecker(&captcha.CheckerConf{
CaptchaConf: app.Conf().Captcha,
User: captcha.User{
ID: fmt.Sprint(user.ID),
IP: c.IP(),
},
})
}
func LimiterGuard(app *core.App, handler fiber.Handler) fiber.Handler {
return func(c *fiber.Ctx) error {
limiter, err := GetLimiter(c)
if err != nil {
return err
}
// 关闭验证码功能,直接 Skip
if !app.Conf().Captcha.Enabled {
return handler(c)
}
// 管理员直接忽略
if CheckIsAdminReq(app, c) {
return handler(c)
}
// 检测是否需要验证码
ip := c.IP()
if limiter.IsPass(ip) {
// 无需验证码
err := handler(c)
if c.Method() != fiber.MethodOptions { // 忽略 Options 请求
limiter.Log(ip) // 记录操作
}
return err
} else {
// create new captcha checker instance
cap := NewCaptchaChecker(app, c)
// response need captcha check
respData := Map{
"need_captcha": true,
}
switch cap.Type() {
case captcha.Image:
// 图片验证码
img, _ := cap.Get()
respData["img_data"] = string(img)
case captcha.IFrame:
// iFrame 验证模式
respData["iframe"] = true
}
return RespError(c, 403, i18n.T("Captcha required"), respData)
}
}
}