chore: update session and challenge repo -- using Redis for caching session and challenge verifying -- added api handler docs

This commit is contained in:
2025-09-09 13:31:41 +03:30
parent dee9ce2f64
commit 6bf6a8ffc2
20 changed files with 1077 additions and 193 deletions
+34 -11
View File
@@ -17,14 +17,15 @@ import (
type AuthService interface {
GenerateChallenge(ctx context.Context, pubKey string) (*domain.Challenge, error)
Authenticate(ctx context.Context, pubKey string, signature string, challenge *domain.Challenge, chainID uint, ipAddress, userAgent string) (*UserToken, error)
Authenticate(ctx context.Context, pubKey string, signature string, chainID uint, ipAddress, userAgent string) (*UserToken, error)
}
type authService struct {
userRepo domain.UserRepo
sessionRepo domain.SessionRepo
challengeExp uint
cfg config.JWT
userRepo domain.UserRepo
sessionRepo domain.SessionRepo
challengeRepo domain.ChallengeRepo
challengeExp uint
cfg config.JWT
}
type UserToken struct {
@@ -36,14 +37,16 @@ type UserToken struct {
func NewAuthService(
userRepo domain.UserRepo,
sessionRepo domain.SessionRepo,
challengeRepo domain.ChallengeRepo,
challengeExp uint,
cfg config.JWT,
) AuthService {
return &authService{
userRepo: userRepo,
sessionRepo: sessionRepo,
challengeExp: challengeExp,
cfg: cfg,
userRepo: userRepo,
sessionRepo: sessionRepo,
challengeRepo: challengeRepo,
challengeExp: challengeExp,
cfg: cfg,
}
}
@@ -54,19 +57,32 @@ func (s *authService) GenerateChallenge(ctx context.Context, pubKey string) (*do
}
challenge := &domain.Challenge{
Message: uuid.New(),
Message: uuid.New().String(),
TimeStamp: time.Now().UTC(),
ExpiresAt: time.Now().Add(time.Duration(s.challengeExp) * time.Minute),
}
// Save challenge to Redis
err = s.challengeRepo.Create(ctx, pubKey, challenge)
if err != nil {
return nil, fmt.Errorf("failed to save challenge: %w", err)
}
return challenge, nil
}
func (s *authService) Authenticate(ctx context.Context, pubKey string, signature string, challenge *domain.Challenge, chainID uint, ipAddress, userAgent string) (*UserToken, error) {
func (s *authService) Authenticate(ctx context.Context, pubKey string, signature string, chainID uint, ipAddress, userAgent string) (*UserToken, error) {
_, err := common.IsValidPublicKey(pubKey)
if err != nil {
return nil, fmt.Errorf("invalid public key: %w", err)
}
// Retrieve challenge from Redis
challenge, err := s.challengeRepo.GetByPubKey(ctx, pubKey)
if err != nil {
return nil, fmt.Errorf("failed to retrieve challenge: %w", err)
}
isValid, err := challenge.Verify(pubKey, signature)
if err != nil {
return nil, fmt.Errorf("signature verification failed: %w", err)
@@ -75,6 +91,13 @@ func (s *authService) Authenticate(ctx context.Context, pubKey string, signature
if !isValid {
return nil, errors.New("invalid signature")
}
// Delete the challenge after successful verification to prevent replay attacks
err = s.challengeRepo.Delete(ctx, pubKey)
if err != nil {
return nil, fmt.Errorf("failed to delete challenge: %w", err)
}
user, err := s.userRepo.GetByPubKey(ctx, pubKey)
if err != nil {
return nil, err