| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- package repository
- import (
- "context"
- "crypto/rand"
- "encoding/base64"
- "encoding/json"
- "fmt"
- "strings"
- "time"
- "github.com/Wei-Shaw/sub2api/internal/service"
- "github.com/redis/go-redis/v9"
- )
- const passkeySessionPrefix = "passkey:session:"
- type passkeySessionStore struct {
- redis *redis.Client
- }
- func NewPasskeySessionStore(redisClient *redis.Client) service.PasskeySessionStore {
- return &passkeySessionStore{redis: redisClient}
- }
- func (s *passkeySessionStore) Store(
- ctx context.Context,
- session *service.PasskeySession,
- ttl time.Duration,
- ) (string, error) {
- if session == nil || ttl <= 0 {
- return "", fmt.Errorf("invalid passkey session")
- }
- random := make([]byte, 32)
- if _, err := rand.Read(random); err != nil {
- return "", fmt.Errorf("generate passkey session token: %w", err)
- }
- token := base64.RawURLEncoding.EncodeToString(random)
- payload, err := json.Marshal(session)
- if err != nil {
- return "", fmt.Errorf("encode passkey session: %w", err)
- }
- if err = s.redis.Set(ctx, passkeySessionPrefix+token, payload, ttl).Err(); err != nil {
- return "", fmt.Errorf("store passkey session: %w", err)
- }
- return token, nil
- }
- func (s *passkeySessionStore) Consume(
- ctx context.Context,
- token string,
- ) (*service.PasskeySession, error) {
- token = strings.TrimSpace(token)
- if token == "" || len(token) > 128 {
- return nil, service.ErrPasskeySession
- }
- payload, err := s.redis.GetDel(ctx, passkeySessionPrefix+token).Bytes()
- if err == redis.Nil {
- return nil, service.ErrPasskeySession
- }
- if err != nil {
- return nil, fmt.Errorf("consume passkey session: %w", err)
- }
- var session service.PasskeySession
- if err = json.Unmarshal(payload, &session); err != nil {
- return nil, service.ErrPasskeySession
- }
- return &session, nil
- }
|