Files
OpenFlare/openflare-server/internal/service/cap.go
T
2026-06-06 16:50:24 +08:00

69 lines
1.8 KiB
Go

package service
import (
"context"
"log/slog"
"time"
"github.com/go-redis/redis/v8"
"github.com/rain-kl/openflare/openflare-server/internal/common"
"github.com/rain-kl/openflare/openflare-server/internal/utils/cap"
)
// RedisCapStore wraps the shared Redis client to implement the cap.Store interface
type RedisCapStore struct{}
func (s *RedisCapStore) Get(ctx context.Context, key string) (string, bool, error) {
val, err := common.RDB.Get(ctx, key).Result()
if err != nil {
if err == redis.Nil {
return "", false, nil
}
return "", false, err
}
return val, true, nil
}
func (s *RedisCapStore) Set(ctx context.Context, key string, val string, ttl time.Duration) error {
return common.RDB.Set(ctx, key, val, ttl).Err()
}
func (s *RedisCapStore) Delete(ctx context.Context, key string) error {
return common.RDB.Del(ctx, key).Err()
}
// CapManager is the global CAPTCHA manager instance
var CapManager *cap.Manager
// InitCap initializes the global CAPTCHA manager
func InitCap() {
var store cap.Store
if common.RedisEnabled {
store = &RedisCapStore{}
slog.Info("CAPTCHA service initialized with Redis store")
} else {
store = cap.NewMemoryStore(1 * time.Minute)
slog.Info("CAPTCHA service initialized with Memory store")
}
secret := common.JWTSecret
if secret == "" {
secret = common.SessionSecret
}
secretBytes := []byte(secret)
if len(secretBytes) < 16 {
// CAPTCHA JWT verification requires a key of at least 16 bytes
padding := make([]byte, 16-len(secretBytes))
secretBytes = append(secretBytes, padding...)
}
CapManager = cap.NewManager(cap.Config{
Secret: secretBytes,
ChallengeCount: 50,
ChallengeSize: 32,
ChallengeDifficulty: 4,
ChallengeTTL: 10 * time.Minute,
TokenTTL: 20 * time.Minute,
}, store)
}