diff options
| -rw-r--r-- | errors/errors.go | 7 | ||||
| -rw-r--r-- | main.go | 2 | ||||
| -rw-r--r-- | user/user.go | 10 | ||||
| -rw-r--r-- | user/validators.go | 83 | 
4 files changed, 88 insertions, 14 deletions
diff --git a/errors/errors.go b/errors/errors.go index c16bd52..0d88490 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -1,5 +1,5 @@  /* openbills - Server for web based Libre Billing Software - * Copyright (C) 2023  Vidhu Kant Sharma <vidhukant@vidhukant.com> + * Copyright (C) 2023-2024  Vidhu Kant Sharma <vidhukant@vidhukant.com>   *   * This program is free software: you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by @@ -31,6 +31,9 @@ var (  	ErrEmptyContactName       = errors.New("Contact Name Cannot Be Empty")  	ErrInvalidGSTIN           = errors.New("Invalid GSTIN")  	ErrInvalidEmail           = errors.New("Invalid E-Mail Address") +  ErrEmptyEmail             = errors.New("E-Mail Address Cannot Be Empty") +  ErrInvalidUsername        = errors.New("Invalid Username") +  ErrEmptyUsername          = errors.New("Username Cannot Be Empty")  	ErrInvalidPhone           = errors.New("Invalid Phone Number")  	ErrInvalidWebsite         = errors.New("Invalid Website URL")  	ErrEmptyBrandName         = errors.New("Brand Name Cannot Be Empty") @@ -38,6 +41,8 @@ var (  	ErrInvalidGSTPercentage   = errors.New("Invalid GST Percentage")  	ErrPasswordTooShort       = errors.New("Password Is Too Short")  	ErrPasswordTooLong        = errors.New("Password Is Too Long") +	ErrUsernameTooShort       = errors.New("Username Is Too Short") +	ErrUsernameTooLong        = errors.New("Username Is Too Long")  	ErrInvalidLoginMethod     = errors.New("Login Method Can Only Be 'email' Or 'username'")  	// 401 @@ -38,7 +38,7 @@ import (  	"log"  ) -const OPENBILLS_VERSION = "v0.4.0" +const OPENBILLS_VERSION = "v0.5.0"  func init() {  	if !viper.GetBool("debug_mode") { diff --git a/user/user.go b/user/user.go index ee36e95..401ebe7 100644 --- a/user/user.go +++ b/user/user.go @@ -1,5 +1,5 @@  /* openbills - Server for web based Libre Billing Software - * Copyright (C) 2023  Vidhu Kant Sharma <vidhukant@vidhukant.com> + * Copyright (C) 2023-2024  Vidhu Kant Sharma <vidhukant@vidhukant.com>   *   * This program is free software: you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by @@ -20,6 +20,7 @@ package user  import (  	d "vidhukant.com/openbills/db"  	e "vidhukant.com/openbills/errors" +  u "vidhukant.com/openbills/util"  	"golang.org/x/crypto/bcrypt"  	"gorm.io/gorm"  	"github.com/spf13/viper" @@ -38,8 +39,13 @@ func init() {  type User struct {  	gorm.Model +  u.Address +  FullName   string +  Gstin      string +  Phone      string +  Email      string +  Website    string  	Username   string -	Email      string  	Password   string  	IsVerified bool  } diff --git a/user/validators.go b/user/validators.go index 647da06..b54457f 100644 --- a/user/validators.go +++ b/user/validators.go @@ -1,5 +1,5 @@  /* openbills - Server for web based Libre Billing Software - * Copyright (C) 2023  Vidhu Kant Sharma <vidhukant@vidhukant.com> + * Copyright (C) 2023-2024  Vidhu Kant Sharma <vidhukant@vidhukant.com>   *   * This program is free software: you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by @@ -19,10 +19,10 @@ package user  import (  	"strings" -	"net/mail"  	e "errors"  	"github.com/spf13/viper"  	"vidhukant.com/openbills/errors" +	"vidhukant.com/openbills/util"  )  func validatePassword(pass string) error { @@ -39,6 +39,26 @@ func validatePassword(pass string) error {  	return nil  } +func validateUsername(username string) error { +	// check if username is too short +	if len(username) < viper.GetInt("username.min_username_length") { +		return errors.ErrUsernameTooShort +	} + +	// check if username is too long +	if len(username) > viper.GetInt("username.max_username_length") { +		return errors.ErrUsernameTooLong +	} + +  for _, char := range username { +    if !strings.Contains(username, string(char)) { +      return errors.ErrInvalidUsername +    } +  } + +  return nil +} +  // NOTE: very inefficient and really really really dumb but it works  // TODO: find a better (or even a remotely good) way  func validateUserField(field, value string) error { @@ -57,8 +77,14 @@ func validateUserField(field, value string) error {  			switch(field) {  			case "username":  				return errors.ErrNonUniqueUsername +      case "phone": +        return errors.ErrNonUniquePhone  			case "email":  				return errors.ErrNonUniqueEmail +      case "website": +        return errors.ErrNonUniqueWebsite +      case "gstin": +        return errors.ErrNonUniqueGSTIN  			default:  				return e.New(field + " is not unique")  			} @@ -71,20 +97,57 @@ func validateUserField(field, value string) error {  func (u *User) validate() error {  	u.Username = strings.TrimSpace(u.Username)  	u.Email = strings.TrimSpace(u.Email) +  u.Phone = strings.TrimSpace(u.Phone) +  u.Website = strings.TrimSpace(u.Website) +  u.Gstin = strings.TrimSpace(u.Gstin)  	u.IsVerified = false  	// TODO: validate username length and stuff +   +  // don't validate if GSTIN is empty +  if u.Gstin != "" && !util.ValidateGstin(u.Gstin) { +    return errors.ErrInvalidGSTIN +  } -	var err error +  // don't validate if phone is empty +  if u.Phone != "" && !util.ValidatePhone(u.Phone) { +    return errors.ErrInvalidPhone +  } -	// validate email -	_, err = mail.ParseAddress(u.Email) -	if err != nil { -		return errors.ErrInvalidEmail -	} +  // don't validate if website is empty +  if u.Website != "" && !util.ValidateWebsite(u.Website) { +    return errors.ErrInvalidWebsite +  } + +  // don't accept empty email +  if u.Email == "" { +    return errors.ErrEmptyEmail +  } else { +    // validate email +    if !util.ValidateEmail(u.Email) { +      return errors.ErrInvalidEmail +    } +  } + +  // don't accept empty username +  if u.Username == "" { +    return errors.ErrEmptyUsername +  } else { +    // validate username +    err := validateUsername(u.Username) +    if err != nil { +      return err +    } +  } + +  // validate password +  err := validatePassword(u.Password) +  if err != nil { +    return err +  } -	for _, i := range [][]string{{"username", u.Username}, {"email", u.Email}} { -		err = validateUserField(i[0], i[1]) +	for _, i := range [][]string{{"username", u.Username}, {"email", u.Email}, {"website", u.Website}, {"gstin", u.Gstin}, {"phone", u.Phone}} { +    err := validateUserField(i[0], i[1])  		if err != nil {  			return err  		}  |