diff --git a/.gitignore b/.gitignore index 3f89f1f..c41712d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ *.env -helpers.txt \ No newline at end of file +helpers.txt +# Build artifacts +backend/systopher-backend +systopher-backend \ No newline at end of file diff --git a/backend/backend b/backend/backend new file mode 100755 index 0000000..3537c3d Binary files /dev/null and b/backend/backend differ diff --git a/backend/go.mod b/backend/go.mod index 1baf8da..c8dd29c 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -9,6 +9,7 @@ require ( github.com/gofiber/jwt/v3 v3.3.2 github.com/gofiber/websocket/v2 v2.1.0 github.com/golang-jwt/jwt/v4 v4.4.2 + github.com/google/uuid v1.6.0 github.com/joho/godotenv v1.4.0 github.com/lib/pq v1.10.7 golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 diff --git a/backend/go.sum b/backend/go.sum index 153a28c..40a9253 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -24,6 +24,8 @@ github.com/gofiber/websocket/v2 v2.1.0/go.mod h1:9DgZTZfxVWT6549+k869HqUdZK0RIL1 github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/h12w/go-socks5 v0.0.0-20200522160539-76189e178364 h1:5XxdakFhqd9dnXoAZy1Mb2R/DZ6D1e+0bGC/JhucGYI= github.com/h12w/go-socks5 v0.0.0-20200522160539-76189e178364/go.mod h1:eDJQioIyy4Yn3MVivT7rv/39gAJTrA7lgmYr8EW950c= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= diff --git a/backend/handlers/signup.go b/backend/handlers/signup.go index 9ae4ae8..5f18494 100644 --- a/backend/handlers/signup.go +++ b/backend/handlers/signup.go @@ -15,42 +15,60 @@ func Signup(c *fiber.Ctx) error { if err := c.BodyParser(user); err != nil { fmt.Println(err) return c.Status(500).JSON(errors.InternalServerError.Merror()) - } else { - if user.Username == "" || user.Email == "" || user.Password == "" { - return c.Status(400).JSON(errors.InvalidData.Merror()) + } + + // Validate input data + if user.Username == "" || user.Email == "" || user.Password == "" { + return c.Status(400).JSON(errors.InvalidData.Merror()) + } + + // Comprehensive validation using UserCheckers + if validationError := helpers.UserCheckers(user); validationError.Err != nil { + return c.Status(400).JSON(validationError) + } + + // Hash password + hash, err := helpers.HashPassword(user.Password) + if err != nil { + fmt.Println(err) + return c.Status(fiber.StatusInternalServerError).JSON(errors.InternalServerError.Merror()) + } + + // Generate UUID for user + u_id := helpers.GenerateUUIDForUser() + + // Create user in database + if err = helpers.CreateUser(user.Email, hash, user.Username, u_id); err != nil { + if strings.HasSuffix(err.Error(), "\"users_email_key\"") { + return c.Status(409).JSON(errors.EmailTaken.Merror()) } - if hash, err := helpers.HashPassword(user.Password); err != nil { - fmt.Println(err) - return c.Status(fiber.StatusInternalServerError).JSON(errors.InternalServerError.Merror()) - } else { - u_id := helpers.GenerateId("USER-") - if err = helpers.CreateUser(user.Email, hash, user.Username, u_id); err != nil { - if strings.HasSuffix(err.Error(), "\"users_email_key\"") { - return c.Status(409).JSON(errors.EmailTaken.Merror()) - - } - if strings.HasSuffix(err.Error(), "\"users_username_key\"") { - return c.Status(409).JSON(errors.UsernameTaken.Merror()) - } - return c.Status(fiber.StatusInternalServerError).JSON(errors.InternalServerError.Merror()) - } else { - sent, err := helpers.SendOtp(user.Email) - if err != nil { - fmt.Println(err) - return c.Status(500).JSON(errors.InternalServerError.Merror()) - } - success := helpers.SaveOtp(user.Email, sent) - if success { - err := helpers.SetUserId(u_id, user.Email) - if err != nil { - return c.Status(fiber.StatusInternalServerError).JSON(errors.InternalServerError.Merror()) - } - return c.Status(200).JSON(fiber.Map{ - "message": "User created, verify to continue", - }) - } - return c.Status(500).JSON(errors.InternalServerError.Merror()) - } + if strings.HasSuffix(err.Error(), "\"users_username_key\"") { + return c.Status(409).JSON(errors.UsernameTaken.Merror()) } + fmt.Println(err) + return c.Status(fiber.StatusInternalServerError).JSON(errors.InternalServerError.Merror()) } + + // Send OTP for email verification + sent, err := helpers.SendOtp(user.Email) + if err != nil { + fmt.Println(err) + return c.Status(500).JSON(errors.InternalServerError.Merror()) + } + + // Save OTP and set user ID in Redis + success := helpers.SaveOtp(user.Email, sent) + if !success { + return c.Status(500).JSON(errors.InternalServerError.Merror()) + } + + err = helpers.SetUserId(u_id, user.Email) + if err != nil { + fmt.Println(err) + return c.Status(fiber.StatusInternalServerError).JSON(errors.InternalServerError.Merror()) + } + + return c.Status(200).JSON(fiber.Map{ + "message": "User created, verify to continue", + }) } diff --git a/backend/helpers/user_helper.go b/backend/helpers/user_helper.go index 5e96761..0e71c0c 100644 --- a/backend/helpers/user_helper.go +++ b/backend/helpers/user_helper.go @@ -6,6 +6,7 @@ import ( "github.com/axrav/Systopher/backend/db" "github.com/axrav/Systopher/backend/errors" "github.com/axrav/Systopher/backend/models" + "github.com/google/uuid" ) func GetUserData(email string) *models.UserData { @@ -71,6 +72,10 @@ func CreateUser(email string, hash string, username string, u_id string) error { return nil } +func GenerateUUIDForUser() string { + return uuid.New().String() +} + func SetUserId(u_id string, email string) error { err := db.RedisClient.Set(db.Ctx, u_id, email, 0).Err() if err != nil {