package handlers import ( "net/http" "strings" "time" "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/toyffee/party-mix/internal/models" "golang.org/x/crypto/bcrypt" "gorm.io/gorm" ) type registerReq struct { Username string `json:"username" binding:"required,min=3,max=50"` Email string `json:"email" binding:"required,email"` Password string `json:"password" binding:"required,min=6"` } func Register(db *gorm.DB) gin.HandlerFunc { return func(c *gin.Context) { var req registerReq if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } hash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "internal error"}) return } user := models.User{ ID: uuid.NewString(), Username: req.Username, Email: strings.ToLower(req.Email), PasswordHash: string(hash), CreatedAt: time.Now(), } if err := db.Create(&user).Error; err != nil { if strings.Contains(err.Error(), "duplicate key") || strings.Contains(err.Error(), "unique") { c.JSON(http.StatusConflict, gin.H{"error": "username or email already taken"}) return } c.JSON(http.StatusInternalServerError, gin.H{"error": "could not create user"}) return } c.JSON(http.StatusCreated, user) } } type loginReq struct { Email string `json:"email" binding:"required"` Password string `json:"password" binding:"required"` } func Login(db *gorm.DB, jwtSecret string) gin.HandlerFunc { return func(c *gin.Context) { var req loginReq if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } var user models.User if err := db.Where("email = ?", strings.ToLower(req.Email)).First(&user).Error; err != nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid credentials"}) return } if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(req.Password)); err != nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid credentials"}) return } token, err := generateToken(user.ID, jwtSecret) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "could not generate token"}) return } c.JSON(http.StatusOK, gin.H{ "token": token, "user": user, }) } } func Me(db *gorm.DB) gin.HandlerFunc { return func(c *gin.Context) { userID := currentUserID(c) var user models.User if err := db.First(&user, "id = ?", userID).Error; err != nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "user not found"}) return } c.JSON(http.StatusOK, user) } }