azote-backend/controllers/authController.go

129 lines
2.8 KiB
Go

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 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
}