package handlers import ( "net/http" "sheetless-server/database" "sheetless-server/models" "time" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" "golang.org/x/crypto/bcrypt" ) var jwtSecret = []byte("your-secret-key") // In production, use environment variable type RegisterRequest struct { Username string `json:"username" binding:"required"` Email string `json:"email" binding:"required,email"` Password string `json:"password" binding:"required,min=6"` } type LoginRequest struct { Username string `json:"username" binding:"required"` Password string `json:"password" binding:"required"` } func Register(c *gin.Context) { var req RegisterRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // Check if user already exists var existingUser models.User if err := database.DB.Where("username = ? OR email = ?", req.Username, req.Email).First(&existingUser).Error; err == nil { c.JSON(http.StatusConflict, gin.H{"error": "User already exists"}) return } // Hash password hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to hash password"}) return } // Create user user := models.User{ Username: req.Username, Email: req.Email, Password: string(hashedPassword), } if err := database.DB.Create(&user).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create user"}) return } c.JSON(http.StatusCreated, gin.H{"message": "User created successfully"}) } func Login(c *gin.Context) { var req LoginRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // Find user var user models.User if err := database.DB.Where("username = ?", req.Username).First(&user).Error; err != nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid credentials"}) return } // Check password if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password)); err != nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid credentials"}) return } // Generate JWT token token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "user_id": user.ID, "exp": time.Now().Add(time.Hour * 24).Unix(), }) tokenString, err := token.SignedString(jwtSecret) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate token"}) return } c.JSON(http.StatusOK, gin.H{"token": tokenString}) }