133 lines
2.9 KiB
Go
133 lines
2.9 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.Preload("Avatar").Preload("Posts.Files").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
|
|
}
|