update: completely register with otp request
This commit is contained in:
parent
14d9c9c563
commit
298b0de725
|
|
@ -13,41 +13,37 @@ type AuthHandler struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAuthHandler(authService services.AuthService) *AuthHandler {
|
func NewAuthHandler(authService services.AuthService) *AuthHandler {
|
||||||
return &AuthHandler{
|
return &AuthHandler{authService}
|
||||||
authService: authService,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *AuthHandler) Register(c *fiber.Ctx) error {
|
func (h *AuthHandler) RegisterUser(c *fiber.Ctx) error {
|
||||||
var request dto.RegisterRequest
|
var req dto.RegisterRequest
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
if err := c.BodyParser(&request); err != nil {
|
return utils.ErrorResponse(c, "Invalid request body")
|
||||||
return utils.ValidationErrorResponse(c, map[string][]string{"body": {"invalid request body"}})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if errors, valid := request.Validate(); !valid {
|
if errors, valid := req.Validate(); !valid {
|
||||||
return utils.ValidationErrorResponse(c, errors)
|
return utils.ValidationErrorResponse(c, errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := h.authService.RegisterUser(&request)
|
err := h.authService.RegisterUser(&req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return utils.ErrorResponse(c, err.Error())
|
return utils.ErrorResponse(c, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.SuccessResponse(c, nil, "OTP has been sent to your phone")
|
return utils.SuccessResponse(c, nil, "Kode OTP telah dikirimkan ke nomor WhatsApp anda")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *AuthHandler) VerifyOTP(c *fiber.Ctx) error {
|
func (h *AuthHandler) VerifyOTP(c *fiber.Ctx) error {
|
||||||
var request dto.VerifyOTPRequest
|
var req dto.VerifyOTPRequest
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
if err := c.BodyParser(&request); err != nil {
|
return utils.ErrorResponse(c, "Invalid request body")
|
||||||
return utils.ValidationErrorResponse(c, map[string][]string{"body": {"invalid request body"}})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err := h.authService.VerifyOTP(&request)
|
response, err := h.authService.VerifyOTP(&req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return utils.ErrorResponse(c, err.Error())
|
return utils.ErrorResponse(c, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.SuccessResponse(c, nil, "User successfully registered")
|
return utils.SuccessResponse(c, response, "Registration successful")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,14 @@
|
||||||
package repositories
|
package repositories
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"rijig/model"
|
"rijig/model"
|
||||||
|
|
||||||
"github.com/go-redis/redis/v8"
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserRepository interface {
|
type UserRepository interface {
|
||||||
SaveUser(user *model.User) (*model.User, error)
|
CreateUser(user *model.User) (*model.User, error)
|
||||||
FindByPhone(phone string) (*model.User, error)
|
GetUserByPhone(phone string) (*model.User, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type userRepository struct {
|
type userRepository struct {
|
||||||
|
|
@ -22,83 +16,20 @@ type userRepository struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUserRepository(db *gorm.DB) UserRepository {
|
func NewUserRepository(db *gorm.DB) UserRepository {
|
||||||
return &userRepository{db: db}
|
return &userRepository{db}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *userRepository) SaveUser(user *model.User) (*model.User, error) {
|
func (r *userRepository) CreateUser(user *model.User) (*model.User, error) {
|
||||||
if err := r.db.Create(user).Error; err != nil {
|
if err := r.db.Create(user).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *userRepository) FindByPhone(phone string) (*model.User, error) {
|
func (r *userRepository) GetUserByPhone(phone string) (*model.User, error) {
|
||||||
var user model.User
|
var user model.User
|
||||||
if err := r.db.Where("phone = ?", phone).First(&user).Error; err != nil {
|
if err := r.db.Where("phone = ?", phone).First(&user).Error; err != nil {
|
||||||
if err == gorm.ErrRecordNotFound {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &user, nil
|
return &user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type RedisRepository interface {
|
|
||||||
StoreData(key string, data interface{}, expiration time.Duration) error
|
|
||||||
GetData(key string) (interface{}, error) // Mengembalikan interface{}
|
|
||||||
DeleteData(key string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type redisRepository struct {
|
|
||||||
client *redis.Client
|
|
||||||
ctx context.Context
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRedisRepository membuat instance baru dari redisRepository
|
|
||||||
func NewRedisRepository(client *redis.Client) RedisRepository {
|
|
||||||
return &redisRepository{
|
|
||||||
client: client,
|
|
||||||
ctx: context.Background(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// StoreData menyimpan data ke dalam Redis (dalam format JSON)
|
|
||||||
func (r *redisRepository) StoreData(key string, data interface{}, expiration time.Duration) error {
|
|
||||||
// Marshaling data ke JSON
|
|
||||||
jsonData, err := json.Marshal(data)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to marshal data: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simpan JSON ke Redis
|
|
||||||
err = r.client.Set(r.ctx, key, jsonData, expiration).Err()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to store data in Redis: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetData mengambil data dari Redis berdasarkan key
|
|
||||||
func (r *redisRepository) GetData(key string) (interface{}, error) {
|
|
||||||
val, err := r.client.Get(r.ctx, key).Result()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to get data from Redis: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal data JSON kembali ke objek
|
|
||||||
var data interface{}
|
|
||||||
err = json.Unmarshal([]byte(val), &data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to unmarshal data: %v", err)
|
|
||||||
}
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteData menghapus data di Redis berdasarkan key
|
|
||||||
func (r *redisRepository) DeleteData(key string) error {
|
|
||||||
err := r.client.Del(r.ctx, key).Err()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to delete data from Redis: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,140 +1,142 @@
|
||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
"rijig/config"
|
"rijig/config"
|
||||||
"rijig/dto"
|
"rijig/dto"
|
||||||
"rijig/internal/repositories"
|
"rijig/internal/repositories"
|
||||||
"rijig/model"
|
"rijig/model"
|
||||||
|
"rijig/utils"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt/v5"
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AuthService interface {
|
type AuthService interface {
|
||||||
RegisterUser(request *dto.RegisterRequest) error
|
RegisterUser(req *dto.RegisterRequest) error
|
||||||
VerifyOTP(request *dto.VerifyOTPRequest) error
|
VerifyOTP(req *dto.VerifyOTPRequest) (*dto.UserDataResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type authService struct {
|
type authService struct {
|
||||||
userRepo repositories.UserRepository
|
userRepo repositories.UserRepository
|
||||||
roleRepo repositories.RoleRepository
|
roleRepo repositories.RoleRepository
|
||||||
redisRepo repositories.RedisRepository
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAuthService(userRepo repositories.UserRepository, roleRepo repositories.RoleRepository, redisRepo repositories.RedisRepository) AuthService {
|
func NewAuthService(userRepo repositories.UserRepository, roleRepo repositories.RoleRepository) AuthService {
|
||||||
return &authService{
|
return &authService{userRepo, roleRepo}
|
||||||
userRepo: userRepo,
|
|
||||||
roleRepo: roleRepo,
|
|
||||||
redisRepo: redisRepo,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *authService) RegisterUser(request *dto.RegisterRequest) error {
|
func (s *authService) RegisterUser(req *dto.RegisterRequest) error {
|
||||||
|
|
||||||
if request.RoleID == "" {
|
userID := uuid.New().String()
|
||||||
return fmt.Errorf("role_id cannot be empty")
|
|
||||||
|
user := &model.User{
|
||||||
|
Phone: req.Phone,
|
||||||
|
RoleID: req.RoleID,
|
||||||
}
|
}
|
||||||
|
|
||||||
role, err := s.roleRepo.FindByID(request.RoleID)
|
err := utils.SetJSONData("user:"+userID, user, 10*time.Minute)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("role not found: %v", err)
|
return err
|
||||||
}
|
|
||||||
if role == nil {
|
|
||||||
return fmt.Errorf("role with ID %s not found", request.RoleID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
existingUser, err := s.userRepo.FindByPhone(request.Phone)
|
err = utils.SetStringData("user_phone:"+req.Phone, userID, 10*time.Minute)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to check existing user: %v", err)
|
return err
|
||||||
}
|
|
||||||
if existingUser != nil {
|
|
||||||
return fmt.Errorf("phone number already registered")
|
|
||||||
}
|
|
||||||
|
|
||||||
temporaryData := &model.User{
|
|
||||||
Phone: request.Phone,
|
|
||||||
RoleID: request.RoleID,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = s.redisRepo.StoreData(request.Phone, temporaryData, 1*time.Hour)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to store registration data in Redis: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
otp := generateOTP()
|
otp := generateOTP()
|
||||||
err = s.redisRepo.StoreData("otp:"+request.Phone, otp, 10*time.Minute)
|
|
||||||
|
err = config.SendWhatsAppMessage(req.Phone, fmt.Sprintf("Your OTP is: %s", otp))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to store OTP in Redis: %v", err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = config.SendWhatsAppMessage(request.Phone, fmt.Sprintf("Your OTP is: %s", otp))
|
err = utils.SetStringData("otp:"+req.Phone, otp, 10*time.Minute)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to send OTP via WhatsApp: %v", err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("OTP sent to phone number: %s", request.Phone)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *authService) VerifyOTP(request *dto.VerifyOTPRequest) error {
|
func (s *authService) VerifyOTP(req *dto.VerifyOTPRequest) (*dto.UserDataResponse, error) {
|
||||||
|
storedOTP, err := utils.GetStringData("otp:" + req.Phone)
|
||||||
storedOTP, err := s.redisRepo.GetData("otp:" + request.Phone)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to retrieve OTP from Redis: %v", err)
|
return nil, err
|
||||||
}
|
|
||||||
if storedOTP != request.OTP {
|
|
||||||
return fmt.Errorf("invalid OTP")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
temporaryData, err := s.redisRepo.GetData(request.Phone)
|
if storedOTP == "" {
|
||||||
|
return nil, errors.New("OTP expired or not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
if storedOTP != req.OTP {
|
||||||
|
return nil, errors.New("invalid OTP")
|
||||||
|
}
|
||||||
|
|
||||||
|
userID, err := utils.GetStringData("user_phone:" + req.Phone)
|
||||||
|
if err != nil || userID == "" {
|
||||||
|
return nil, errors.New("user data not found in Redis")
|
||||||
|
}
|
||||||
|
|
||||||
|
userData, err := utils.GetJSONData("user:" + userID)
|
||||||
|
if err != nil || userData == nil {
|
||||||
|
return nil, errors.New("user data not found in Redis")
|
||||||
|
}
|
||||||
|
|
||||||
|
user := &model.User{
|
||||||
|
Phone: userData["phone"].(string),
|
||||||
|
RoleID: userData["roleId"].(string),
|
||||||
|
}
|
||||||
|
|
||||||
|
createdUser, err := s.userRepo.CreateUser(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get registration data from Redis: %v", err)
|
return nil, err
|
||||||
}
|
|
||||||
if temporaryData == "" {
|
|
||||||
return fmt.Errorf("no registration data found for phone: %s", request.Phone)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
temporaryDataStr, ok := temporaryData.(string)
|
role, err := s.roleRepo.FindByID(createdUser.RoleID)
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("failed to assert data to string")
|
|
||||||
}
|
|
||||||
|
|
||||||
temporaryDataBytes := []byte(temporaryDataStr)
|
|
||||||
|
|
||||||
var user model.User
|
|
||||||
err = json.Unmarshal(temporaryDataBytes, &user)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to unmarshal registration data: %v", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = s.userRepo.SaveUser(&user)
|
token, err := generateJWTToken(createdUser.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to save user to database: %v", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.redisRepo.DeleteData(request.Phone)
|
return &dto.UserDataResponse{
|
||||||
if err != nil {
|
UserID: createdUser.ID,
|
||||||
return fmt.Errorf("failed to delete registration data from Redis: %v", err)
|
UserRole: role.RoleName,
|
||||||
}
|
Token: token,
|
||||||
|
}, nil
|
||||||
err = s.redisRepo.DeleteData("otp:" + request.Phone)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to delete OTP from Redis: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateOTP() string {
|
func generateOTP() string {
|
||||||
|
|
||||||
return fmt.Sprintf("%06d", RandomInt(100000, 999999))
|
|
||||||
}
|
|
||||||
|
|
||||||
func RandomInt(min, max int) int {
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
return rand.Intn(max-min+1) + min
|
otp := fmt.Sprintf("%06d", rand.Intn(1000000))
|
||||||
|
return otp
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateJWTToken(userID string) (string, error) {
|
||||||
|
|
||||||
|
expirationTime := time.Now().Add(24 * time.Hour)
|
||||||
|
|
||||||
|
claims := &jwt.RegisteredClaims{
|
||||||
|
Issuer: userID,
|
||||||
|
ExpiresAt: jwt.NewNumericDate(expirationTime),
|
||||||
|
}
|
||||||
|
|
||||||
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||||
|
|
||||||
|
secretKey := config.GetSecretKey()
|
||||||
|
|
||||||
|
signedToken, err := token.SignedString([]byte(secretKey))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return signedToken, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,48 +7,15 @@ import (
|
||||||
"rijig/internal/services"
|
"rijig/internal/services"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
// "gorm.io/gorm"
|
|
||||||
// "rijig/middleware"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func AuthRouter(api fiber.Router) {
|
func AuthRouter(api fiber.Router) {
|
||||||
// userRepo := repositories.NewUserRepository(config.DB)
|
|
||||||
// roleRepo := repositories.NewRoleRepository(config.DB)
|
|
||||||
// userService := services.NewUserService(userRepo, roleRepo, secretKey)
|
|
||||||
// userHandler := handler.NewUserHandler(userService)
|
|
||||||
|
|
||||||
// api.Post("/login", userHandler.Login)
|
|
||||||
// api.Post("/register", userHandler.Register)
|
|
||||||
// api.Post("/logout", middleware.AuthMiddleware, userHandler.Logout)
|
|
||||||
// userRepo := repositories.NewUserRepository(config.DB)
|
|
||||||
// authService := services.NewAuthService(userRepo, secretKey)
|
|
||||||
|
|
||||||
// // Inisialisasi handler
|
|
||||||
// authHandler := handler.NewAuthHandler(authService)
|
|
||||||
|
|
||||||
// // Endpoint OTP
|
|
||||||
// authRoutes := api.Group("/auth")
|
|
||||||
// authRoutes.Post("/send-otp", authHandler.SendOTP)
|
|
||||||
// authRoutes.Post("/verify-otp", authHandler.VerifyOTP)
|
|
||||||
// userRepo := repositories.NewUserRepository(config.DB)
|
|
||||||
// authService := services.NewAuthService(userRepo)
|
|
||||||
|
|
||||||
// authHandler := handler.NewAuthHandler(authService)
|
|
||||||
|
|
||||||
// // Routes
|
|
||||||
// api.Post("/register", authHandler.Register)
|
|
||||||
// api.Post("/verify-otp", authHandler.VerifyOTP)
|
|
||||||
userRepo := repositories.NewUserRepository(config.DB)
|
userRepo := repositories.NewUserRepository(config.DB)
|
||||||
roleRepo := repositories.NewRoleRepository(config.DB)
|
roleRepo := repositories.NewRoleRepository(config.DB)
|
||||||
redisRepo := repositories.NewRedisRepository(config.RedisClient)
|
authService := services.NewAuthService(userRepo, roleRepo)
|
||||||
|
|
||||||
// Setup Service
|
|
||||||
authService := services.NewAuthService(userRepo, roleRepo, redisRepo)
|
|
||||||
|
|
||||||
// Setup Handler
|
|
||||||
authHandler := handler.NewAuthHandler(authService)
|
authHandler := handler.NewAuthHandler(authService)
|
||||||
|
|
||||||
// Define Routes
|
api.Post("/register", authHandler.RegisterUser)
|
||||||
api.Post("/register", authHandler.Register) // Route untuk registrasi
|
|
||||||
api.Post("/verify-otp", authHandler.VerifyOTP)
|
api.Post("/verify-otp", authHandler.VerifyOTP)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -124,18 +124,43 @@ func GetStringData(key string) (string, error) {
|
||||||
return val, nil
|
return val, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func StoreOTPInRedis(phone, otpCode string, expirationTime time.Duration) error {
|
// func SetStringData(key, value string, expiration time.Duration) error {
|
||||||
err := config.RedisClient.Set(config.Ctx, phone, otpCode, expirationTime).Err()
|
// if expiration == 0 {
|
||||||
if err != nil {
|
// expiration = defaultExpiration
|
||||||
return fmt.Errorf("failed to store OTP in Redis: %v", err)
|
// }
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetOTPFromRedis(phone string) (string, error) {
|
// err := config.RedisClient.Set(ctx, key, value, expiration).Err()
|
||||||
otpCode, err := config.RedisClient.Get(config.Ctx, phone).Result()
|
// if err != nil {
|
||||||
if err != nil {
|
// return fmt.Errorf("Error setting string data in Redis with key: %s: %v", key, err)
|
||||||
return "", fmt.Errorf("failed to get OTP from Redis: %v", err)
|
// }
|
||||||
}
|
|
||||||
return otpCode, nil
|
// log.Printf("String data stored in Redis with key: %s", key)
|
||||||
}
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// GetStringData retrieves a string value from Redis by key
|
||||||
|
// func GetStringData(key string) (string, error) {
|
||||||
|
// val, err := config.RedisClient.Get(ctx, key).Result()
|
||||||
|
// if err == redis.Nil {
|
||||||
|
// return "", nil
|
||||||
|
// } else if err != nil {
|
||||||
|
// return "", fmt.Errorf("Error retrieving string data from Redis with key: %s: %v", key, err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return val, nil
|
||||||
|
// }
|
||||||
|
// func StoreOTPInRedis(phone, otpCode string, expirationTime time.Duration) error {
|
||||||
|
// err := config.RedisClient.Set(config.Ctx, phone, otpCode, expirationTime).Err()
|
||||||
|
// if err != nil {
|
||||||
|
// return fmt.Errorf("failed to store OTP in Redis: %v", err)
|
||||||
|
// }
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func GetOTPFromRedis(phone string) (string, error) {
|
||||||
|
// otpCode, err := config.RedisClient.Get(config.Ctx, phone).Result()
|
||||||
|
// if err != nil {
|
||||||
|
// return "", fmt.Errorf("failed to get OTP from Redis: %v", err)
|
||||||
|
// }
|
||||||
|
// return otpCode, nil
|
||||||
|
// }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue