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"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
"github.com/danielgtaylor/huma/v2"
|
"github.com/danielgtaylor/huma/v2"
|
||||||
"github.com/forfarm/backend/internal/domain"
|
"github.com/forfarm/backend/internal/domain"
|
||||||
"github.com/forfarm/backend/internal/utilities"
|
"github.com/forfarm/backend/internal/utilities"
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
|
validation "github.com/go-ozzo/ozzo-validation/v4"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (a *api) registerAuthRoutes(_ chi.Router, api huma.API) {
|
func (a *api) registerAuthRoutes(_ chi.Router, api huma.API) {
|
||||||
tags := []string{"auth"}
|
tags := []string{"auth"}
|
||||||
|
|
||||||
prefix := "/auth"
|
prefix := "/auth"
|
||||||
|
|
||||||
huma.Register(api, huma.Operation{
|
huma.Register(api, huma.Operation{
|
||||||
@ -58,10 +59,37 @@ type RegisterOutput struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
func (a *api) registerHandler(ctx context.Context, input *RegisterInput) (*RegisterOutput, error) {
|
||||||
resp := &RegisterOutput{}
|
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)
|
_, err := a.userRepo.GetByEmail(ctx, input.Body.Email)
|
||||||
if err == domain.ErrNotFound {
|
if err == domain.ErrNotFound {
|
||||||
@ -78,7 +106,12 @@ func (a *api) registerHandler(ctx context.Context, input *RegisterInput) (*Regis
|
|||||||
return nil, err
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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) {
|
func (a *api) loginHandler(ctx context.Context, input *LoginInput) (*LoginOutput, error) {
|
||||||
resp := &LoginOutput{}
|
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)
|
user, err := a.userRepo.GetByEmail(ctx, input.Body.Email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify password hash
|
|
||||||
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(input.Body.Password)); err != nil {
|
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(input.Body.Password)); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user