package handlers import ( "encoding/json" "net/http" "server/database" "server/helper" ) type signupRequest struct { Email string Password string } func Signup(writer http.ResponseWriter, request *http.Request) { if request.Method != "POST" { helper.WriteErrorJson("expected POST method", writer, http.StatusBadRequest) return } var signup_request signupRequest err := json.NewDecoder(request.Body).Decode(&signup_request) if err != nil { helper.WriteErrorJson(err.Error(), writer, http.StatusBadRequest) return } if len(signup_request.Email) < 3 || len(signup_request.Email) > 254 { helper.WriteErrorJson("invalid email address", writer, http.StatusBadRequest) return } if len(signup_request.Password) < 8 { helper.WriteErrorJson("password too short", writer, http.StatusBadRequest) return } if len(signup_request.Password) > 64 { helper.WriteErrorJson("password too long", writer, http.StatusBadRequest) return } user, err := database.MaybeGetUser(signup_request.Email) if err != nil { helper.WriteInternalErrorJson(err, writer) return } if user != nil { helper.WriteErrorJson("a user with that email already exists", writer, http.StatusForbidden) return } salt, err := helper.GenerateSalt() if err != nil { helper.WriteInternalErrorJson(err, writer) return } hash, err := helper.GenerateHash(signup_request.Password, salt) if err != nil { helper.WriteInternalErrorJson(err, writer) return } uid, err := database.WriteNewUser(signup_request.Email, hash, salt) if err != nil { helper.WriteInternalErrorJson(err, writer) return } err = helper.IssueToken(uid, writer) if err != nil { helper.WriteInternalErrorJson(err, writer) return } }