diff --git a/cmd/ngodeyuk/main.go b/cmd/ngodeyuk/main.go deleted file mode 100644 index f1192be..0000000 --- a/cmd/ngodeyuk/main.go +++ /dev/null @@ -1,27 +0,0 @@ -package main - -import ( - "fmt" - "log" - "ngodeyuk-core/config" - courseRouter "ngodeyuk-core/internal/courses/router" - helloRouter "ngodeyuk-core/internal/hello/router" - userRouter "ngodeyuk-core/internal/users/router" - - "github.com/gin-gonic/gin" -) - -func main() { - db, err := config.InitDB() - if err != nil { - log.Fatal("Failed to connect database") - } - - r := gin.Default() - helloRouter.HelloRouter(r) - userRouter.UserRouter(r, db) - courseRouter.CourseRouter(r, db) - - fmt.Println("Server is running at http://localhost:2000") - log.Fatal(r.Run(":2000")) -} diff --git a/cmd/web/main.go b/cmd/web/main.go new file mode 100644 index 0000000..ab1b99a --- /dev/null +++ b/cmd/web/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "fmt" + "log" + + "github.com/gin-gonic/gin" + "github.com/joho/godotenv" + + "ngodeyuk-core/database" + "ngodeyuk-core/internal/infrastructure/routes" +) + +func main() { + route := gin.Default() + err := godotenv.Load() + if err != nil { + log.Fatalf("error load .env file: %v", err) + } + + db, err := database.InitDB() + if err != nil { + panic("failed to connect database.") + } + routes.UserRoutes(route, db) + + fmt.Println("Server is running at http://localhost:2000") + log.Fatal(route.Run(":2000")) +} diff --git a/config/database.go b/database/config.go similarity index 97% rename from config/database.go rename to database/config.go index 2517b74..6ff1c75 100644 --- a/config/database.go +++ b/database/config.go @@ -1,4 +1,4 @@ -package config +package database import ( "log" diff --git a/migrations/20240723045005_create_initial_schema.down.sql b/database/migrations/20240723045005_create_initial_schema.down.sql similarity index 100% rename from migrations/20240723045005_create_initial_schema.down.sql rename to database/migrations/20240723045005_create_initial_schema.down.sql diff --git a/migrations/20240723045005_create_initial_schema.up.sql b/database/migrations/20240723045005_create_initial_schema.up.sql similarity index 100% rename from migrations/20240723045005_create_initial_schema.up.sql rename to database/migrations/20240723045005_create_initial_schema.up.sql diff --git a/go.mod b/go.mod index a7c3d79..943cab1 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,8 @@ go 1.22.4 require github.com/gin-gonic/gin v1.10.0 +require github.com/golang-jwt/jwt/v5 v5.2.1 // indirect + require ( github.com/bytedance/sonic v1.11.6 // indirect github.com/bytedance/sonic/loader v0.1.1 // indirect diff --git a/go.sum b/go.sum index b475e66..87d4281 100644 --- a/go.sum +++ b/go.sum @@ -27,6 +27,8 @@ github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBEx github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= diff --git a/internal/courses/handlers/course_handler.go b/internal/courses/handlers/course_handler.go deleted file mode 100644 index c11a303..0000000 --- a/internal/courses/handlers/course_handler.go +++ /dev/null @@ -1,33 +0,0 @@ -package handlers - -import ( - "net/http" - "ngodeyuk-core/internal/courses/services" - "ngodeyuk-core/pkg/dto" - - "github.com/gin-gonic/gin" -) - -type CourseHandler struct { - courseService services.CourseService -} - -func NewCourseHandler(courseService services.CourseService) *CourseHandler { - return &CourseHandler{courseService: courseService} -} - -func (h *CourseHandler) CreateCourse(c *gin.Context) { - var courseDTO dto.CreateCourseDTO - if err := c.ShouldBindJSON(&courseDTO); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) - return - } - - course, err := h.courseService.CreateCourse(courseDTO) - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) - return - } - - c.JSON(http.StatusOK, course) -} diff --git a/internal/courses/router/course_router.go b/internal/courses/router/course_router.go deleted file mode 100644 index eb58fe4..0000000 --- a/internal/courses/router/course_router.go +++ /dev/null @@ -1,16 +0,0 @@ -package router - -import ( - "ngodeyuk-core/internal/courses/handlers" - "ngodeyuk-core/internal/courses/services" - - "github.com/gin-gonic/gin" - "gorm.io/gorm" -) - -func CourseRouter(r *gin.Engine, db *gorm.DB) { - couseService := services.NewCourseService(db) - userHandler := handlers.NewCourseHandler(couseService) - - r.POST("api/course/create", userHandler.CreateCourse) -} diff --git a/internal/courses/services/course_service.go b/internal/courses/services/course_service.go deleted file mode 100644 index 6d29e2c..0000000 --- a/internal/courses/services/course_service.go +++ /dev/null @@ -1,29 +0,0 @@ -package services - -import ( - "ngodeyuk-core/pkg/dto" - "ngodeyuk-core/pkg/models" - - "gorm.io/gorm" -) - -type CourseService interface { - CreateCourse(dto.CreateCourseDTO) (models.Course, error) -} - -type courseService struct { - db *gorm.DB -} - -func NewCourseService(db *gorm.DB) CourseService { - return &courseService{db} -} - -func (s *courseService) CreateCourse(courseDTO dto.CreateCourseDTO) (models.Course, error) { - course := models.Course{ - Title: courseDTO.Title, - Img: courseDTO.Img, - } - err := s.db.Create(&course).Error - return course, err -} diff --git a/pkg/dto/user_dto.go b/internal/domain/dtos/user_dto.go similarity index 55% rename from pkg/dto/user_dto.go rename to internal/domain/dtos/user_dto.go index fdcec36..4e2c42e 100644 --- a/pkg/dto/user_dto.go +++ b/internal/domain/dtos/user_dto.go @@ -1,7 +1,7 @@ -package dto +package dtos type RegisterDTO struct { - Name string `json:"name" binding:"required"` + Name string `json:"name" binding:"required"` Username string `json:"username" binding:"required"` Password string `json:"password" binding:"required"` } @@ -10,8 +10,3 @@ type LoginDTO struct { Username string `json:"username" binding:"required"` Password string `json:"password" binding:"required"` } - -type ChangePasswordDTO struct { - OldPassword string `json:"old_password" binding:"required"` - NewPassword string `json:"new_password" binding:"required"` -} diff --git a/pkg/models/challenge.go b/internal/domain/models/challenge.go similarity index 100% rename from pkg/models/challenge.go rename to internal/domain/models/challenge.go diff --git a/pkg/models/challenge_option.go b/internal/domain/models/challenge_option.go similarity index 100% rename from pkg/models/challenge_option.go rename to internal/domain/models/challenge_option.go diff --git a/pkg/models/challenge_progress.go b/internal/domain/models/challenge_progress.go similarity index 100% rename from pkg/models/challenge_progress.go rename to internal/domain/models/challenge_progress.go diff --git a/pkg/models/course.go b/internal/domain/models/course.go similarity index 100% rename from pkg/models/course.go rename to internal/domain/models/course.go diff --git a/pkg/models/lesson.go b/internal/domain/models/lesson.go similarity index 100% rename from pkg/models/lesson.go rename to internal/domain/models/lesson.go diff --git a/pkg/models/unit.go b/internal/domain/models/unit.go similarity index 100% rename from pkg/models/unit.go rename to internal/domain/models/unit.go diff --git a/pkg/models/user.go b/internal/domain/models/user.go similarity index 100% rename from pkg/models/user.go rename to internal/domain/models/user.go diff --git a/internal/domain/repositories/user_repository.go b/internal/domain/repositories/user_repository.go new file mode 100644 index 0000000..bca1a45 --- /dev/null +++ b/internal/domain/repositories/user_repository.go @@ -0,0 +1,41 @@ +package repositories + +import ( + "gorm.io/gorm" + + "ngodeyuk-core/internal/domain/models" +) + +type UserRepository interface { + Create(user *models.User) error + FindByUsername(username string) (*models.User, error) + Update(user *models.User) error +} + +type userRepository struct { + db *gorm.DB +} + +func NewUserRepository(db *gorm.DB) UserRepository { + return &userRepository{db} +} + +func (repository *userRepository) Create(user *models.User) error { + return repository.db.Create(user).Error +} + +func (repository *userRepository) FindByUsername(username string) (*models.User, error) { + var user models.User + err := repository.db.Where("username = ?", username).First(&user).Error + if err != nil { + return nil, err + } + return &user, nil +} + +func (repository *userRepository) Update(user *models.User) error { + if err := repository.db.Save(user).Error; err != nil { + return err + } + return nil +} diff --git a/internal/hello/handlers/hello.go b/internal/hello/handlers/hello.go deleted file mode 100644 index f1c2d1f..0000000 --- a/internal/hello/handlers/hello.go +++ /dev/null @@ -1,15 +0,0 @@ -package handlers - -import ( - "net/http" - "ngodeyuk-core/internal/hello/services" - - "github.com/gin-gonic/gin" -) - -func HelloHandler(c *gin.Context) { - message := services.GetHelloMessage() - c.JSON(http.StatusOK, gin.H{ - "message": message, - }) -} diff --git a/internal/hello/router/hello_router.go b/internal/hello/router/hello_router.go deleted file mode 100644 index bf1172b..0000000 --- a/internal/hello/router/hello_router.go +++ /dev/null @@ -1,11 +0,0 @@ -package router - -import ( - "ngodeyuk-core/internal/hello/handlers" - - "github.com/gin-gonic/gin" -) - -func HelloRouter(r *gin.Engine) { - r.GET("api/hello", handlers.HelloHandler) -} diff --git a/internal/hello/services/hello.go b/internal/hello/services/hello.go deleted file mode 100644 index 987bd2b..0000000 --- a/internal/hello/services/hello.go +++ /dev/null @@ -1,7 +0,0 @@ -package services - -import "ngodeyuk-core/pkg/utils" - -func GetHelloMessage() string { - return utils.GetHelloMessage() -} diff --git a/internal/infrastructure/handlers/user_handler.go b/internal/infrastructure/handlers/user_handler.go new file mode 100644 index 0000000..668b046 --- /dev/null +++ b/internal/infrastructure/handlers/user_handler.go @@ -0,0 +1,61 @@ +package handlers + +import ( + "net/http" + + "github.com/gin-gonic/gin" + + "ngodeyuk-core/internal/domain/dtos" + "ngodeyuk-core/internal/services" +) + +type UserHandler interface { + Register(c *gin.Context) + Login(c *gin.Context) +} + +type userHandler struct { + service services.UserService +} + +func NewUserHandler(service services.UserService) UserHandler { + return &userHandler{service} +} + +func (handler *userHandler) Register(ctx *gin.Context) { + var input dtos.RegisterDTO + if err := ctx.ShouldBindJSON(&input); err != nil { + ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + err := handler.service.Register(&input) + if err != nil { + ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + ctx.JSON(http.StatusCreated, gin.H{ + "data": gin.H{ + "name": input.Name, + "username": input.Username, + }, + }) +} + +func (handler *userHandler) Login(ctx *gin.Context) { + var input dtos.LoginDTO + if err := ctx.ShouldBindJSON(&input); err != nil { + ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + token, err := handler.service.Login(&input) + if err != nil { + ctx.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()}) + return + } + + ctx.JSON(http.StatusOK, gin.H{ + "token": token, + }) +} diff --git a/internal/infrastructure/routes/routes.go b/internal/infrastructure/routes/routes.go new file mode 100644 index 0000000..fa0e48d --- /dev/null +++ b/internal/infrastructure/routes/routes.go @@ -0,0 +1,19 @@ +package routes + +import ( + "github.com/gin-gonic/gin" + "gorm.io/gorm" + + "ngodeyuk-core/internal/domain/repositories" + "ngodeyuk-core/internal/infrastructure/handlers" + "ngodeyuk-core/internal/services" +) + +func UserRoutes(route *gin.Engine, db *gorm.DB) { + repository := repositories.NewUserRepository(db) + service := services.NewUserService(repository) + handler := handlers.NewUserHandler(service) + + route.POST("auth/register", handler.Register) + route.POST("auth/login", handler.Login) +} diff --git a/internal/services/user_service.go b/internal/services/user_service.go new file mode 100644 index 0000000..0388361 --- /dev/null +++ b/internal/services/user_service.go @@ -0,0 +1,68 @@ +package services + +import ( + "os" + "time" + + "github.com/golang-jwt/jwt/v5" + "golang.org/x/crypto/bcrypt" + + "ngodeyuk-core/internal/domain/dtos" + "ngodeyuk-core/internal/domain/models" + "ngodeyuk-core/internal/domain/repositories" +) + +type UserService interface { + Register(dto *dtos.RegisterDTO) error + Login(dto *dtos.LoginDTO) (string, error) +} + +type userService struct { + repository repositories.UserRepository +} + +func NewUserService(repository repositories.UserRepository) UserService { + return &userService{repository} +} + +func (service *userService) Register(dto *dtos.RegisterDTO) error { + hashedPassword, err := bcrypt.GenerateFromPassword( + []byte(dto.Password), + bcrypt.DefaultCost, + ) + if err != nil { + return err + } + + user := &models.User{ + Name: dto.Name, + Username: dto.Username, + Password: string(hashedPassword), + } + + return service.repository.Create(user) +} + +func (service *userService) Login(dto *dtos.LoginDTO) (string, error) { + user, err := service.repository.FindByUsername(dto.Username) + if err != nil { + return "", err + } + + err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(dto.Password)) + if err != nil { + return "", err + } + + token := jwt.New(jwt.SigningMethodHS256) + claims := token.Claims.(jwt.MapClaims) + claims["username"] = dto.Username + claims["exp"] = time.Now().Add(time.Hour * 24).Unix() + + tokenString, err := token.SignedString([]byte(os.Getenv("JWT_SECRET_KEY"))) + if err != nil { + return "", err + } + + return tokenString, nil +} diff --git a/internal/users/handlers/user_handler.go b/internal/users/handlers/user_handler.go deleted file mode 100644 index c0a8bbc..0000000 --- a/internal/users/handlers/user_handler.go +++ /dev/null @@ -1,93 +0,0 @@ -package handlers - -import ( - "net/http" - "ngodeyuk-core/internal/users/services" - "ngodeyuk-core/pkg/dto" - "ngodeyuk-core/pkg/utils" - - "github.com/gin-gonic/gin" -) - -type UserHandler interface { - RegisterUser(c *gin.Context) - LoginUser(c *gin.Context) - ChangePassword(c *gin.Context) -} - -type userHandler struct { - userService services.UserService -} - -func NewUserHandler(userService services.UserService) UserHandler { - return &userHandler{userService} -} - -func (h *userHandler) RegisterUser(c *gin.Context) { - var registerDTO dto.RegisterDTO - if err := c.ShouldBindJSON(®isterDTO); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) - return - } - - user, err := h.userService.RegisterUser(registerDTO) - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) - return - } - - c.JSON(http.StatusCreated, gin.H{ - "message": "register successfully", - "data": gin.H{ - "Name": user.Name, - "Username": user.Username, - }, - }) -} - -func (h *userHandler) LoginUser(c *gin.Context) { - var inputDTO dto.LoginDTO - if err := c.ShouldBindJSON(&inputDTO); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) - return - } - - user, err := h.userService.LoginUser(inputDTO) - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) - return - } - - token, err := utils.GenerateJWT(user.UserId) - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate token"}) - return - } - - c.JSON(http.StatusOK, gin.H{ - "message": "login successfully", - "token": token, - }) -} - -func (h *userHandler) ChangePassword(c *gin.Context) { - var inputDTO dto.ChangePasswordDTO - if err := c.ShouldBindJSON(&inputDTO); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) - return - } - - userID, exists := c.Get("user_id") - if !exists { - c.JSON(http.StatusInternalServerError, gin.H{"error": "User ID not found in context"}) - return - } - - err := h.userService.ChangePassword(userID.(uint), inputDTO) - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) - return - } - - c.JSON(http.StatusOK, gin.H{"message": "password changed successfully"}) -} diff --git a/internal/users/router/user_router.go b/internal/users/router/user_router.go deleted file mode 100644 index cdf035b..0000000 --- a/internal/users/router/user_router.go +++ /dev/null @@ -1,24 +0,0 @@ -package router - -import ( - "ngodeyuk-core/internal/users/handlers" - "ngodeyuk-core/internal/users/services" - "ngodeyuk-core/pkg/middlewares" - - "github.com/gin-gonic/gin" - "gorm.io/gorm" -) - -func UserRouter(r *gin.Engine, db *gorm.DB) { - userService := services.NewUserService(db) - userHandler := handlers.NewUserHandler(userService) - - r.POST("api/register", userHandler.RegisterUser) - r.POST("api/login", userHandler.LoginUser) - - protected := r.Group("/") - protected.Use(middlewares.AuthMiddleware()) - { - protected.PUT("api/change-password", userHandler.ChangePassword) - } -} diff --git a/internal/users/services/user_service.go b/internal/users/services/user_service.go deleted file mode 100644 index 4242ac6..0000000 --- a/internal/users/services/user_service.go +++ /dev/null @@ -1,90 +0,0 @@ -package services - -import ( - "errors" - "ngodeyuk-core/pkg/dto" - "ngodeyuk-core/pkg/models" - - "golang.org/x/crypto/bcrypt" - "gorm.io/gorm" -) - -type UserService interface { - RegisterUser(dto.RegisterDTO) (models.User, error) - LoginUser(dto.LoginDTO) (models.User, error) - ChangePassword(userID uint, input dto.ChangePasswordDTO) error -} - -type userService struct { - db *gorm.DB -} - -func NewUserService(db *gorm.DB) UserService { - return &userService{db} -} - -func (s *userService) RegisterUser(registerDTO dto.RegisterDTO) (models.User, error) { - hashedPassword, err := bcrypt.GenerateFromPassword([]byte(registerDTO.Password), bcrypt.DefaultCost) - if err != nil { - return models.User{}, err - } - - user := models.User{ - Name: registerDTO.Name, - Username: registerDTO.Username, - Password: string(hashedPassword), - } - - if err := s.db.Create(&user).Error; err != nil { - return models.User{}, err - } - - return user, nil -} - -func (s *userService) LoginUser(input dto.LoginDTO) (models.User, error) { - var user models.User - - username := input.Username - password := input.Password - - err := s.db.Where("username = ?", username).Find(&user).Error - if err != nil { - return user, err - } - - if user.UserId == "" { - return user, errors.New("no user found on that username") - } - - err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)) - if err != nil { - return user, err - } - - return user, nil -} - -func (s *userService) ChangePassword(userID uint, input dto.ChangePasswordDTO) error { - var user models.User - - err := s.db.Where("user_id = ?", userID).Find(&user).Error - if err != nil { - return err - } - - err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(input.OldPassword)) - if err != nil { - return errors.New("incorrect old password") - } - - newPasswordHash, err := bcrypt.GenerateFromPassword([]byte(input.NewPassword), bcrypt.DefaultCost) - if err != nil { - return err - } - - user.Password = string(newPasswordHash) - s.db.Save(&user) - - return nil -} diff --git a/pkg/dto/course_dto.go b/pkg/dto/course_dto.go deleted file mode 100644 index 6ee8d20..0000000 --- a/pkg/dto/course_dto.go +++ /dev/null @@ -1,6 +0,0 @@ -package dto - -type CreateCourseDTO struct { - Title string `json:"title" binding:"required"` - Img string `json:"img" binding:"required"` -} diff --git a/pkg/middlewares/auth_middleware.go b/pkg/middlewares/auth_middleware.go deleted file mode 100644 index 5992c27..0000000 --- a/pkg/middlewares/auth_middleware.go +++ /dev/null @@ -1,51 +0,0 @@ -package middlewares - -import ( - "net/http" - "ngodeyuk-core/pkg/utils" - "strings" - - "github.com/dgrijalva/jwt-go" - "github.com/gin-gonic/gin" -) - -func AuthMiddleware() gin.HandlerFunc { - return func(c *gin.Context) { - authHeader := c.GetHeader("Authorization") - if authHeader == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Request does not contain an access token"}) - c.Abort() - return - } - - tokenString := strings.TrimSpace(strings.Replace(authHeader, "Bearer", "", 1)) - if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Request does not contain a valid token"}) - c.Abort() - return - } - - token, err := utils.VerifyJWT(tokenString) - if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) - c.Abort() - return - } - - if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { - userID, ok := claims["user_id"].(float64) - if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token claims"}) - c.Abort() - return - } - c.Set("user_id", uint(userID)) - } else { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token claims"}) - c.Abort() - return - } - - c.Next() - } -} diff --git a/pkg/utils/hello.go b/pkg/utils/hello.go deleted file mode 100644 index 7b579cd..0000000 --- a/pkg/utils/hello.go +++ /dev/null @@ -1,5 +0,0 @@ -package utils - -func GetHelloMessage() string { - return "Hello, World!" -} diff --git a/pkg/utils/jwt.go b/pkg/utils/jwt.go deleted file mode 100644 index 6d720e8..0000000 --- a/pkg/utils/jwt.go +++ /dev/null @@ -1,53 +0,0 @@ -package utils - -import ( - "os" - "time" - - "github.com/dgrijalva/jwt-go" - "github.com/joho/godotenv" -) - -var jwtSecret []byte - -func init() { - godotenv.Load() - jwtSecretString := os.Getenv("JWT_SECRET_KEY") - if jwtSecretString == "" { - panic("environment variable is required") - } - jwtSecret = []byte(jwtSecretString) -} - -func GenerateJWT(userID string) (string, error) { - token := jwt.New(jwt.SigningMethodHS256) - claims := token.Claims.(jwt.MapClaims) - claims["user_id"] = userID - claims["exp"] = time.Now().Add(time.Hour * 24).Unix() - - signedToken, err := token.SignedString(jwtSecret) - if err != nil { - return "", err - } - - return signedToken, nil -} - -func VerifyJWT(tokenString string) (*jwt.Token, error) { - token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { - if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { - return nil, jwt.ErrSignatureInvalid - } - return jwtSecret, nil - }) - - if err != nil { - return nil, err - } - - if !token.Valid { - return nil, jwt.ErrSignatureInvalid - } - - return token, nil -} diff --git a/tests/hello_test.go b/tests/hello_test.go deleted file mode 100644 index 949d9d6..0000000 --- a/tests/hello_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package tests - -import ( - "ngodeyuk-core/pkg/utils" - "testing" -) - -func TestGetHelloMessage(t *testing.T) { - expected := "Hello, World!" - if msg := utils.GetHelloMessage(); msg != expected { - t.Errorf("Expected %s but got %s", expected, msg) - } -}