package controllers import ( "azote-backend/initializers" "azote-backend/models" "errors" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt" "github.com/google/uuid" "golang.org/x/crypto/bcrypt" "gorm.io/gorm" "net/http" "os" "time" ) func Signup(c *gin.Context) { var body struct { Username string DisplayName string Email string Password string } if err := c.Bind(&body); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request format"}) return } if body.Username == "" || body.Email == "" || body.Password == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "Missing required fields"}) return } hashedPassword, err := bcrypt.GenerateFromPassword([]byte(body.Password), bcrypt.DefaultCost) if err != nil { c.Status(http.StatusInternalServerError) } user := models.User{ Username: body.Username, DisplayName: body.DisplayName, Email: body.Email, Password: string(hashedPassword), } result := initializers.DB.Create(&user) if result.Error != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": "An account already exists with that email.", }) return } tokenString, err := createToken(user.ID) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": err, }) return } c.JSON(http.StatusAccepted, gin.H{ "user": user, "token": tokenString, }) } func Login(c *gin.Context) { var body struct { Email string Password string } if err := c.Bind(&body); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request format"}) return } if body.Email == "" || body.Password == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "Missing required fields"}) return } var user models.User result := initializers.DB.First(&user, "email = ?", body.Email) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { c.JSON(http.StatusBadRequest, gin.H{"error": "Email/Password is invalid."}) } else { c.JSON(http.StatusInternalServerError, gin.H{"error": "Database error"}) } return } err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(body.Password)) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Email/Password is invalid."}) return } tokenString, err := createToken(user.ID) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": err, }) return } c.JSON(http.StatusAccepted, gin.H{ "user": user, "token": tokenString, }) } func ValidateToken(c *gin.Context) { c.AbortWithStatus(http.StatusAccepted) } func createToken(userId uuid.UUID) (string, error) { token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "bearer": userId, "expiresAt": time.Now().Add(time.Hour * 24 * 30).Unix(), }) tokenString, err := token.SignedString([]byte(os.Getenv("JWT_SECRET"))) if err != nil { return "", errors.New("could not create token") } return tokenString, nil }