79 lines
2.2 KiB
Go
79 lines
2.2 KiB
Go
package captcha
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/redis/go-redis/v9"
|
|
|
|
"github.com/perfect-panel/server/pkg/xerr"
|
|
)
|
|
|
|
// VerifyInput holds the captcha fields from a login/register/reset request.
|
|
type VerifyInput struct {
|
|
CaptchaId string
|
|
CaptchaCode string
|
|
CfToken string
|
|
SliderToken string
|
|
IP string
|
|
}
|
|
|
|
// VerifyCaptcha validates the captcha according to captchaType.
|
|
// Returns nil when captchaType is empty / unrecognised (i.e. captcha disabled).
|
|
func VerifyCaptcha(
|
|
ctx context.Context,
|
|
redisClient *redis.Client,
|
|
captchaType string,
|
|
turnstileSecret string,
|
|
input VerifyInput,
|
|
) error {
|
|
switch captchaType {
|
|
case string(CaptchaTypeLocal):
|
|
if input.CaptchaId == "" || input.CaptchaCode == "" {
|
|
return errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "captcha required")
|
|
}
|
|
svc := NewService(Config{
|
|
Type: CaptchaTypeLocal,
|
|
RedisClient: redisClient,
|
|
})
|
|
valid, err := svc.Verify(ctx, input.CaptchaId, input.CaptchaCode, input.IP)
|
|
if err != nil {
|
|
return errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "verify captcha error")
|
|
}
|
|
if !valid {
|
|
return errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "invalid captcha")
|
|
}
|
|
|
|
case string(CaptchaTypeTurnstile):
|
|
if input.CfToken == "" {
|
|
return errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "captcha required")
|
|
}
|
|
svc := NewService(Config{
|
|
Type: CaptchaTypeTurnstile,
|
|
TurnstileSecret: turnstileSecret,
|
|
})
|
|
valid, err := svc.Verify(ctx, input.CfToken, "", input.IP)
|
|
if err != nil {
|
|
return errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "verify captcha error")
|
|
}
|
|
if !valid {
|
|
return errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "invalid captcha")
|
|
}
|
|
|
|
case string(CaptchaTypeSlider):
|
|
if input.SliderToken == "" {
|
|
return errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "slider captcha required")
|
|
}
|
|
sliderSvc := NewSliderService(redisClient)
|
|
valid, err := sliderSvc.VerifySliderToken(ctx, input.SliderToken)
|
|
if err != nil {
|
|
return errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "verify captcha error")
|
|
}
|
|
if !valid {
|
|
return errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "invalid slider captcha")
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|