package handler import ( "BE-MiniERP/config" "BE-MiniERP/database" "BE-MiniERP/modules/auth/models" "BE-MiniERP/modules/auth/repository" "BE-MiniERP/modules/auth/service" "github.com/gofiber/fiber/v2" "github.com/golang-jwt/jwt/v4" ) type AuthHandler struct { Repo *repository.UserRepository } func NewAuthHandler() *AuthHandler { return &AuthHandler{ Repo: repository.NewUserRepository(database.DB), } } func (h *AuthHandler) Register(c *fiber.Ctx) error { var input struct { Username string `json:"username"` Password string `json:"password"` Role string `json:"role"` } if err := c.BodyParser(&input); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "invalid input"}) } hash, err := service.HashPassword(input.Password) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to hash password"}) } user := &models.User{ Username: input.Username, PasswordHash: hash, Role: input.Role, } if err := h.Repo.Create(user); err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to create user"}) } return c.JSON(fiber.Map{"message": "user registered"}) } func (h *AuthHandler) Login(c *fiber.Ctx) error { var input struct { Username string `json:"username"` Password string `json:"password"` } if err := c.BodyParser(&input); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "invalid input"}) } user, err := h.Repo.FindByUsername(input.Username) if err != nil || !service.CheckPasswordHash(input.Password, user.PasswordHash) { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "invalid credentials"}) } token, err := service.GenerateJWT(user.ID, user.Role) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to generate token"}) } refreshToken, err := service.GenerateRefreshToken(user.ID) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to generate refresh token"}) } return c.JSON(fiber.Map{"token": token, "refresh_token": refreshToken, "role": user.Role}) } func (h *AuthHandler) GetUser(c *fiber.Ctx) error { userID := c.Locals("user_id") // diset dari middleware if userID == nil { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "unauthorized"}) } user, err := h.Repo.FindByID(userID.(uint)) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to fetch user"}) } return c.JSON(user) } func (h *AuthHandler) RefreshToken(c *fiber.Ctx) error { var input struct { RefreshToken string `json:"refresh_token"` } if err := c.BodyParser(&input); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "invalid input"}) } token, err := jwt.Parse(input.RefreshToken, func(token *jwt.Token) (interface{}, error) { return []byte(config.GetConfig().JWTSecret), nil }) if err != nil || !token.Valid { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "invalid or expired refresh token"}) } claims, ok := token.Claims.(jwt.MapClaims) if !ok || claims["user_id"] == nil { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "invalid claims"}) } userID := uint(claims["user_id"].(float64)) user, err := h.Repo.FindByID(userID) if err != nil { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "user not found"}) } newAccessToken, err := service.GenerateJWT(user.ID, user.Role) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to generate new token"}) } return c.JSON(fiber.Map{ "token": newAccessToken, }) }