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 }