98 lines
2.4 KiB
Go
98 lines
2.4 KiB
Go
package routes
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/gin-gonic/gin"
|
|
"golang.org/x/crypto/bcrypt"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
"udemy_httpserver/models"
|
|
)
|
|
|
|
func registerUser(c *gin.Context) {
|
|
var user struct {
|
|
models.User
|
|
PasswordConfirm string `json:"password_confirm"`
|
|
}
|
|
err := c.ShouldBind(&user)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
candidateUser, err := models.FindOneByEmail(strings.ToLower(user.Email))
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
if candidateUser != nil {
|
|
c.JSON(http.StatusConflict, gin.H{"error": fmt.Sprintf("user with email %s already exists", user.Email)})
|
|
return
|
|
}
|
|
|
|
if user.Password != user.PasswordConfirm {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "password_confirm must match password"})
|
|
return
|
|
}
|
|
|
|
err = user.New()
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
jwt, err := setAuthCookie(c, &user.User)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
user.Password = ""
|
|
c.JSON(http.StatusCreated, gin.H{"user": user.User, "token": jwt})
|
|
}
|
|
|
|
func Login(c *gin.Context) {
|
|
var loginDTO struct {
|
|
Email string `binding:"required" json:"email"`
|
|
Password string `binding:"required" json:"password"`
|
|
}
|
|
err := c.ShouldBind(&loginDTO)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
user, err := models.FindOneByEmail(strings.ToLower(loginDTO.Email))
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(loginDTO.Password))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid password or email"})
|
|
return
|
|
}
|
|
|
|
token, err := setAuthCookie(c, user)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"jwt": token})
|
|
|
|
}
|
|
|
|
func setAuthCookie(c *gin.Context, user *models.User) (string, error) {
|
|
JWToken, err := user.GetJWToken()
|
|
expirationDelta, err := time.ParseDuration(os.Getenv("AUTH_EXPIRATION"))
|
|
if err != nil {
|
|
fmt.Println("Error parsing AUTH_EXPIRATION")
|
|
return "", err
|
|
}
|
|
|
|
cookieExpiration := time.Now().Add(expirationDelta).Unix()
|
|
c.SetCookie("Authorization", JWToken, int(cookieExpiration), "", "", true, true)
|
|
return JWToken, nil
|
|
}
|