forked from baron/baron-sso
93 lines
2.4 KiB
Go
93 lines
2.4 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/go-redis/redis/v8"
|
|
)
|
|
|
|
var ctx = context.Background()
|
|
|
|
type RedisService struct {
|
|
Client *redis.Client
|
|
}
|
|
|
|
// NewRedisService creates and returns a new RedisService
|
|
func NewRedisService() (*RedisService, error) {
|
|
redisAddr := os.Getenv("REDIS_ADDR")
|
|
if redisAddr == "" {
|
|
redisAddr = "localhost:6389" // Fallback for local dev without Docker
|
|
}
|
|
|
|
rdb := redis.NewClient(&redis.Options{
|
|
Addr: redisAddr,
|
|
})
|
|
|
|
// Ping the server to check the connection
|
|
if _, err := rdb.Ping(ctx).Result(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// [DEV-FIX] Disable stop-writes-on-bgsave-error to allow writes even if persistence fails
|
|
// This is common in dev docker environments with permission issues.
|
|
rdb.ConfigSet(ctx, "stop-writes-on-bgsave-error", "no")
|
|
|
|
return &RedisService{Client: rdb}, nil
|
|
}
|
|
|
|
func (s *RedisService) Ping(ctx context.Context) error {
|
|
if s.Client == nil {
|
|
return os.ErrInvalid
|
|
}
|
|
return s.Client.Ping(ctx).Err()
|
|
}
|
|
|
|
// StoreVerificationCode saves the SMS verification code with a 3-minute expiration
|
|
func (s *RedisService) StoreVerificationCode(phone, code string) error {
|
|
// Key format: "sms_verify:01012345678"
|
|
key := "sms_verify:" + phone
|
|
expiration := 3 * time.Minute
|
|
err := s.Client.Set(ctx, key, code, expiration).Err()
|
|
return err
|
|
}
|
|
|
|
// GetVerificationCode retrieves the SMS verification code
|
|
func (s *RedisService) GetVerificationCode(phone string) (string, error) {
|
|
key := "sms_verify:" + phone
|
|
code, err := s.Client.Get(ctx, key).Result()
|
|
if err == redis.Nil {
|
|
// Key does not exist (expired or incorrect phone number)
|
|
return "", nil
|
|
} else if err != nil {
|
|
return "", err
|
|
}
|
|
return code, nil
|
|
}
|
|
|
|
// DeleteVerificationCode removes the verification code after successful verification
|
|
func (s *RedisService) DeleteVerificationCode(phone string) error {
|
|
key := "sms_verify:" + phone
|
|
return s.Client.Del(ctx, key).Err()
|
|
}
|
|
|
|
// Set stores a key-value pair with expiration
|
|
func (s *RedisService) Set(key string, value string, expiration time.Duration) error {
|
|
return s.Client.Set(ctx, key, value, expiration).Err()
|
|
}
|
|
|
|
// Get retrieves a value by key
|
|
func (s *RedisService) Get(key string) (string, error) {
|
|
val, err := s.Client.Get(ctx, key).Result()
|
|
if err == redis.Nil {
|
|
return "", nil
|
|
}
|
|
return val, err
|
|
}
|
|
|
|
// Delete removes a key
|
|
func (s *RedisService) Delete(key string) error {
|
|
return s.Client.Del(ctx, key).Err()
|
|
}
|