hi-server/pkg/captcha/service.go
2026-03-23 02:42:12 +08:00

71 lines
2.2 KiB
Go

package captcha
import (
"context"
"github.com/redis/go-redis/v9"
)
type CaptchaType string
const (
CaptchaTypeLocal CaptchaType = "local"
CaptchaTypeTurnstile CaptchaType = "turnstile"
CaptchaTypeSlider CaptchaType = "slider"
)
// Service defines the captcha service interface
type Service interface {
// Generate generates a new captcha
// For local captcha: returns id and base64 image
// For turnstile: returns empty strings
// For slider: returns id, background image, and block image (in image field as JSON)
Generate(ctx context.Context) (id string, image string, err error)
// Verify verifies the captcha
// For local captcha: token is captcha id, code is user input
// For turnstile: token is cf-turnstile-response, code is ignored
// For slider: use VerifySlider instead
Verify(ctx context.Context, token string, code string, ip string) (bool, error)
// GetType returns the captcha type
GetType() CaptchaType
}
// SliderService extends Service with slider-specific verification
type SliderService interface {
Service
// VerifySlider verifies slider position and trail, returns a one-time token on success
VerifySlider(ctx context.Context, id string, x, y int, trail string) (token string, err error)
// VerifySliderToken verifies the one-time token issued after slider verification
VerifySliderToken(ctx context.Context, token string) (bool, error)
// GenerateSlider returns id, background image base64, block image base64
GenerateSlider(ctx context.Context) (id string, bgImage string, blockImage string, err error)
}
// Config holds the configuration for captcha service
type Config struct {
Type CaptchaType
RedisClient *redis.Client
TurnstileSecret string
}
// NewService creates a new captcha service based on the config
func NewService(config Config) Service {
switch config.Type {
case CaptchaTypeTurnstile:
return newTurnstileService(config.TurnstileSecret)
case CaptchaTypeSlider:
return newSliderService(config.RedisClient)
case CaptchaTypeLocal:
fallthrough
default:
return newLocalService(config.RedisClient)
}
}
// NewSliderService creates a slider captcha service
func NewSliderService(redisClient *redis.Client) SliderService {
return newSliderService(redisClient)
}