feat: add kyc layer service

This commit is contained in:
2025-09-14 16:17:29 +03:30
parent 667d2ce2f4
commit 2da912739b
6 changed files with 159 additions and 59 deletions
+47 -6
View File
@@ -5,6 +5,7 @@ import (
"backend/internal/domain"
"backend/pkg/jwt"
"backend/pkg/validate/common"
"backend/pkg/zohal"
"context"
"errors"
"fmt"
@@ -24,8 +25,9 @@ type authService struct {
userRepo domain.UserRepo
sessionRepo domain.SessionRepo
challengeRepo domain.ChallengeRepo
zohal *zohal.Zohal
challengeExp uint
cfg config.JWT
cfg config.Config
}
type UserToken struct {
@@ -39,13 +41,15 @@ func NewAuthService(
sessionRepo domain.SessionRepo,
challengeRepo domain.ChallengeRepo,
challengeExp uint,
cfg config.JWT,
zohal *zohal.Zohal,
cfg config.Config,
) AuthService {
return &authService{
userRepo: userRepo,
sessionRepo: sessionRepo,
challengeRepo: challengeRepo,
challengeExp: challengeExp,
zohal: zohal,
cfg: cfg,
}
}
@@ -108,7 +112,7 @@ func (s *authService) Authenticate(ctx context.Context, pubKey string, signature
return nil, fmt.Errorf("failed to update user: %w", err)
}
expiresAt := time.Now().Add(time.Duration(s.cfg.TokenExpMinutes) * time.Minute)
expiresAt := time.Now().Add(time.Duration(s.cfg.JWT.TokenExpMinutes) * time.Minute)
session := domain.NewSession(user.ID, user.PubKey, expiresAt)
err = s.sessionRepo.Create(ctx, session)
@@ -116,28 +120,31 @@ func (s *authService) Authenticate(ctx context.Context, pubKey string, signature
return nil, fmt.Errorf("failed to create session: %w", err)
}
//FIXME: KYC level will be set to 1
claims := &jwt.UserClaims{
UserID: uint(user.ID.ID()),
KYCLevel: int(user.KYCLevel),
Sections: []string{},
}
claims.ExpiresAt = jwt2.NewNumericDate(expiresAt)
claims.IssuedAt = jwt2.NewNumericDate(time.Now())
authToken, err := jwt.CreateToken([]byte(s.cfg.TokenSecret), claims)
authToken, err := jwt.CreateToken([]byte(s.cfg.JWT.TokenSecret), claims)
if err != nil {
return nil, err
}
refreshExpiresAt := time.Now().Add(time.Duration(s.cfg.RefreshTokenExpMinutes) * time.Minute)
refreshExpiresAt := time.Now().Add(time.Duration(s.cfg.JWT.RefreshTokenExpMinutes) * time.Minute)
refreshClaims := &jwt.UserClaims{
UserID: uint(user.ID.ID()),
KYCLevel: int(user.KYCLevel),
Sections: []string{"refresh"},
}
refreshClaims.ExpiresAt = jwt2.NewNumericDate(refreshExpiresAt)
refreshClaims.IssuedAt = jwt2.NewNumericDate(time.Now())
refreshToken, err := jwt.CreateToken([]byte(s.cfg.TokenSecret), refreshClaims)
refreshToken, err := jwt.CreateToken([]byte(s.cfg.JWT.TokenSecret), refreshClaims)
if err != nil {
return nil, fmt.Errorf("failed to create refresh token: %w", err)
}
@@ -148,3 +155,37 @@ func (s *authService) Authenticate(ctx context.Context, pubKey string, signature
ExpiresAt: expiresAt.Unix(),
}, nil
}
func (s *authService) VerifyKYC(ctx context.Context, userID, nationalID, birthDate string) error {
uID, err := uuid.Parse(userID)
if err != nil {
return fmt.Errorf("invalid user ID format: %w", err)
}
user, err := s.userRepo.GetByID(ctx, uID)
if err != nil {
return fmt.Errorf("failed to get user: %w", err)
}
shahkarResp, err := s.zohal.Shahkar(ctx, user.PhoneNumber, user.NationalID)
if err != nil {
return fmt.Errorf("shahkar verification failed: %w", err)
}
identityResp, err := s.zohal.GetPerson(ctx, nationalID, birthDate)
if err != nil {
return fmt.Errorf("identity verification failed: %w", err)
}
if shahkarResp.StatusCode == 200 && identityResp.StatusCode == 200 {
user.UpdateKYCLevel(domain.KYCLevel1)
err = s.userRepo.Update(ctx, user)
if err != nil {
return fmt.Errorf("failed to update user KYC level: %w", err)
}
return nil
}
return fmt.Errorf("KYC verification failed - shahkar status: %d, identity status: %d",
shahkarResp.StatusCode, identityResp.StatusCode)
}