mirror of
https://github.com/ForFarmTeam/ForFarm.git
synced 2025-12-19 14:04:08 +01:00
feat: add validation of input data in auth
This commit is contained in:
parent
5b77d27dcb
commit
69fa65ccf1
@ -4,17 +4,18 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"regexp"
|
||||
|
||||
"github.com/danielgtaylor/huma/v2"
|
||||
"github.com/forfarm/backend/internal/domain"
|
||||
"github.com/forfarm/backend/internal/utilities"
|
||||
"github.com/go-chi/chi/v5"
|
||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func (a *api) registerAuthRoutes(_ chi.Router, api huma.API) {
|
||||
tags := []string{"auth"}
|
||||
|
||||
prefix := "/auth"
|
||||
|
||||
huma.Register(api, huma.Operation{
|
||||
@ -34,34 +35,61 @@ func (a *api) registerAuthRoutes(_ chi.Router, api huma.API) {
|
||||
|
||||
type LoginInput struct {
|
||||
Body struct {
|
||||
Email string `json:"email" example:" Email address of the user"`
|
||||
Password string `json:"password" example:" Password of the user"`
|
||||
Email string `json:"email" example:"Email address of the user"`
|
||||
Password string `json:"password" example:"Password of the user"`
|
||||
}
|
||||
}
|
||||
|
||||
type LoginOutput struct {
|
||||
Body struct {
|
||||
Token string `json:"token" example:" JWT token for the user"`
|
||||
Token string `json:"token" example:"JWT token for the user"`
|
||||
}
|
||||
}
|
||||
|
||||
type RegisterInput struct {
|
||||
Body struct {
|
||||
Email string `json:"email" example:" Email address of the user"`
|
||||
Password string `json:"password" example:" Password of the user"`
|
||||
Email string `json:"email" example:"Email address of the user"`
|
||||
Password string `json:"password" example:"Password of the user"`
|
||||
}
|
||||
}
|
||||
|
||||
type RegisterOutput struct {
|
||||
Body struct {
|
||||
Token string `json:"token" example:" JWT token for the user"`
|
||||
Token string `json:"token" example:"JWT token for the user"`
|
||||
}
|
||||
}
|
||||
|
||||
func validateEmail(email string) error {
|
||||
return validation.Validate(email,
|
||||
validation.Required.Error("email is required"),
|
||||
validation.Match(regexp.MustCompile(`^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,}$`)).Error("invalid email format"),
|
||||
)
|
||||
}
|
||||
|
||||
func validatePassword(password string) error {
|
||||
return validation.Validate(password,
|
||||
validation.Required.Error("password is required"),
|
||||
validation.Length(8, 0).Error("password must be at least 8 characters long"),
|
||||
validation.Match(regexp.MustCompile(`[A-Z]`)).Error("password must contain at least one uppercase letter"),
|
||||
validation.Match(regexp.MustCompile(`[a-z]`)).Error("password must contain at least one lowercase letter"),
|
||||
validation.Match(regexp.MustCompile(`[0-9]`)).Error("password must contain at least one numeral"),
|
||||
validation.Match(regexp.MustCompile(`[\W_]`)).Error("password must contain at least one special character"),
|
||||
)
|
||||
}
|
||||
|
||||
func (a *api) registerHandler(ctx context.Context, input *RegisterInput) (*RegisterOutput, error) {
|
||||
resp := &RegisterOutput{}
|
||||
|
||||
// TODO: Validate input data
|
||||
if input == nil {
|
||||
return nil, errors.New("invalid input")
|
||||
}
|
||||
|
||||
if err := validateEmail(input.Body.Email); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validatePassword(input.Body.Password); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err := a.userRepo.GetByEmail(ctx, input.Body.Email)
|
||||
if err == domain.ErrNotFound {
|
||||
@ -78,7 +106,12 @@ func (a *api) registerHandler(ctx context.Context, input *RegisterInput) (*Regis
|
||||
return nil, err
|
||||
}
|
||||
|
||||
token, err := utilities.CreateJwtToken(input.Body.Email)
|
||||
user, err := a.userRepo.GetByEmail(ctx, input.Body.Email)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
token, err := utilities.CreateJwtToken(user.UUID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -93,14 +126,25 @@ func (a *api) registerHandler(ctx context.Context, input *RegisterInput) (*Regis
|
||||
func (a *api) loginHandler(ctx context.Context, input *LoginInput) (*LoginOutput, error) {
|
||||
resp := &LoginOutput{}
|
||||
|
||||
// TODO: Validate input data
|
||||
if input == nil {
|
||||
return nil, errors.New("invalid input")
|
||||
}
|
||||
if input.Body.Email == "" {
|
||||
return nil, errors.New("email field is required")
|
||||
}
|
||||
if input.Body.Password == "" {
|
||||
return nil, errors.New("password field is required")
|
||||
}
|
||||
|
||||
if err := validateEmail(input.Body.Email); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
user, err := a.userRepo.GetByEmail(ctx, input.Body.Email)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// verify password hash
|
||||
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(input.Body.Password)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user