package repository import ( "context" "encoding/json" "errors" "fmt" "time" redislib "gateway/internal/library/redis" memberdomain "gateway/internal/model/member/domain" domrepo "gateway/internal/model/member/domain/repository" "github.com/zeromicro/go-zero/core/stores/redis" ) type redisStepUpStore struct { client *redis.Redis } // NewRedisStepUpStore creates a Redis-backed step-up session store. func NewRedisStepUpStore(client *redislib.Client) domrepo.StepUpStore { if client == nil || client.Zero() == nil { panic("member: redis client is required for step-up store") } return &redisStepUpStore{client: client.Zero()} } func (s *redisStepUpStore) Save(ctx context.Context, session *domrepo.StepUpSession, ttl time.Duration) error { if session == nil || session.TokenID == "" { return fmt.Errorf("member: step-up token id is required") } raw, err := json.Marshal(session) if err != nil { return fmt.Errorf("member: marshal step-up session: %w", err) } seconds := int(ttl.Seconds()) if seconds < 1 { seconds = 1 } return s.client.SetexCtx(ctx, memberdomain.GetStepUpRedisKey(session.TokenID), string(raw), seconds) } func (s *redisStepUpStore) Get(ctx context.Context, tokenID string) (*domrepo.StepUpSession, error) { val, err := s.client.GetCtx(ctx, memberdomain.GetStepUpRedisKey(tokenID)) if errors.Is(err, redis.Nil) { return nil, memberdomain.ErrStepUpNotFound } if err != nil { return nil, err } var session domrepo.StepUpSession if err := json.Unmarshal([]byte(val), &session); err != nil { return nil, fmt.Errorf("member: unmarshal step-up session: %w", err) } return &session, nil } func (s *redisStepUpStore) Delete(ctx context.Context, tokenID string) error { _, err := s.client.DelCtx(ctx, memberdomain.GetStepUpRedisKey(tokenID)) return err } var _ domrepo.StepUpStore = (*redisStepUpStore)(nil)