| package repository |
|
|
| import ( |
| "context" |
| "encoding/json" |
| "time" |
|
|
| "github.com/Wei-Shaw/sub2api/internal/service" |
| "github.com/redis/go-redis/v9" |
| ) |
|
|
| const ( |
| verifyCodeKeyPrefix = "verify_code:" |
| passwordResetKeyPrefix = "password_reset:" |
| passwordResetSentAtKeyPrefix = "password_reset_sent:" |
| ) |
|
|
| |
| func verifyCodeKey(email string) string { |
| return verifyCodeKeyPrefix + email |
| } |
|
|
| |
| func passwordResetKey(email string) string { |
| return passwordResetKeyPrefix + email |
| } |
|
|
| |
| func passwordResetSentAtKey(email string) string { |
| return passwordResetSentAtKeyPrefix + email |
| } |
|
|
| type emailCache struct { |
| rdb *redis.Client |
| } |
|
|
| func NewEmailCache(rdb *redis.Client) service.EmailCache { |
| return &emailCache{rdb: rdb} |
| } |
|
|
| func (c *emailCache) GetVerificationCode(ctx context.Context, email string) (*service.VerificationCodeData, error) { |
| key := verifyCodeKey(email) |
| val, err := c.rdb.Get(ctx, key).Result() |
| if err != nil { |
| return nil, err |
| } |
| var data service.VerificationCodeData |
| if err := json.Unmarshal([]byte(val), &data); err != nil { |
| return nil, err |
| } |
| return &data, nil |
| } |
|
|
| func (c *emailCache) SetVerificationCode(ctx context.Context, email string, data *service.VerificationCodeData, ttl time.Duration) error { |
| key := verifyCodeKey(email) |
| val, err := json.Marshal(data) |
| if err != nil { |
| return err |
| } |
| return c.rdb.Set(ctx, key, val, ttl).Err() |
| } |
|
|
| func (c *emailCache) DeleteVerificationCode(ctx context.Context, email string) error { |
| key := verifyCodeKey(email) |
| return c.rdb.Del(ctx, key).Err() |
| } |
|
|
| |
|
|
| func (c *emailCache) GetPasswordResetToken(ctx context.Context, email string) (*service.PasswordResetTokenData, error) { |
| key := passwordResetKey(email) |
| val, err := c.rdb.Get(ctx, key).Result() |
| if err != nil { |
| return nil, err |
| } |
| var data service.PasswordResetTokenData |
| if err := json.Unmarshal([]byte(val), &data); err != nil { |
| return nil, err |
| } |
| return &data, nil |
| } |
|
|
| func (c *emailCache) SetPasswordResetToken(ctx context.Context, email string, data *service.PasswordResetTokenData, ttl time.Duration) error { |
| key := passwordResetKey(email) |
| val, err := json.Marshal(data) |
| if err != nil { |
| return err |
| } |
| return c.rdb.Set(ctx, key, val, ttl).Err() |
| } |
|
|
| func (c *emailCache) DeletePasswordResetToken(ctx context.Context, email string) error { |
| key := passwordResetKey(email) |
| return c.rdb.Del(ctx, key).Err() |
| } |
|
|
| |
|
|
| func (c *emailCache) IsPasswordResetEmailInCooldown(ctx context.Context, email string) bool { |
| key := passwordResetSentAtKey(email) |
| exists, err := c.rdb.Exists(ctx, key).Result() |
| return err == nil && exists > 0 |
| } |
|
|
| func (c *emailCache) SetPasswordResetEmailCooldown(ctx context.Context, email string, ttl time.Duration) error { |
| key := passwordResetSentAtKey(email) |
| return c.rdb.Set(ctx, key, "1", ttl).Err() |
| } |
|
|