From e768c99db06aa5d4fa9711e8cfcc312118340a81 Mon Sep 17 00:00:00 2001 From: Adriano Caloiaro Date: Sat, 29 Jul 2023 08:06:30 -0600 Subject: [PATCH] User creation validation --- content/users/create.md | 51 +++++++++++--- content/users/login.md | 16 ++--- go.mod | 8 +-- go.sum | 2 + partials/users/login.html | 19 ------ partials/users/new_user_validation.html | 60 +++++++++++++++++ server.go | 67 ++++++++++++++++++- themes/terminal/assets/css/form.scss | 18 ++++- .../terminal/layouts/shortcodes/include.html | 4 ++ 9 files changed, 198 insertions(+), 47 deletions(-) create mode 100644 partials/users/new_user_validation.html create mode 100644 themes/terminal/layouts/shortcodes/include.html diff --git a/content/users/create.md b/content/users/create.md index 1514642..7be3b79 100644 --- a/content/users/create.md +++ b/content/users/create.md @@ -6,21 +6,50 @@ title: Create Account
- - +
+ + + - - + + + - - + + + - - -
-
- + + + +
+
+ +
diff --git a/content/users/login.md b/content/users/login.md index eb6c036..1c20abf 100644 --- a/content/users/login.md +++ b/content/users/login.md @@ -5,17 +5,17 @@ title: Log in
-
+
- - - - -
-
-
+ + + + +
+
+
diff --git a/go.mod b/go.mod index 31971ba..6c76d3b 100644 --- a/go.mod +++ b/go.mod @@ -2,13 +2,13 @@ module github.com/acaloiaro/garbage_speak go 1.20 -replace github.com/acaloiaro/neoq v0.17.0 => /home/adriano/git/neoq - require ( - github.com/acaloiaro/neoq v0.17.0 + github.com/acaloiaro/neoq v0.18.0 github.com/alexedwards/scs/pgxstore v0.0.0-20230327161757-10d4299e3b24 github.com/alexedwards/scs/v2 v2.5.1 github.com/georgysavva/scany/v2 v2.0.0 + github.com/go-chi/chi/v5 v5.0.10 + github.com/go-chi/cors v1.2.1 github.com/gofrs/uuid v4.4.0+incompatible github.com/golang-migrate/migrate/v4 v4.16.2 github.com/jackc/pgx-gofrs-uuid v0.0.0-20230224015001-1d428863c2e2 @@ -17,8 +17,6 @@ require ( ) require ( - github.com/go-chi/chi/v5 v5.0.10 // indirect - github.com/go-chi/cors v1.2.1 // indirect github.com/gofrs/uuid/v5 v5.0.0 // indirect github.com/guregu/null v4.0.0+incompatible // indirect github.com/hashicorp/errwrap v1.1.0 // indirect diff --git a/go.sum b/go.sum index 0024b3d..23db9f7 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/acaloiaro/neoq v0.18.0 h1:WKTDNEL/sH5hlwd/7Kgbqb4kKdvNVdzNNjfKRtt3v5k= +github.com/acaloiaro/neoq v0.18.0/go.mod h1:uLI2JfC2V9p+H5lx5s0SUsjxIYLm8JDhi6VkyURMvLM= github.com/alexedwards/scs/pgxstore v0.0.0-20230327161757-10d4299e3b24 h1:l8+ZTNz/s7fbpTz/oeUmXCL39Rn49SRaXnj2/LZzCos= github.com/alexedwards/scs/pgxstore v0.0.0-20230327161757-10d4299e3b24/go.mod h1:KTB1slYgIU/BBa4MWA5IdET31OsbPQBM7dqDw5klIt4= github.com/alexedwards/scs/v2 v2.5.1 h1:EhAz3Kb3OSQzD8T+Ub23fKsiuvE0GzbF5Lgn0uTwM3Y= diff --git a/partials/users/login.html b/partials/users/login.html index 23910e7..09c002f 100644 --- a/partials/users/login.html +++ b/partials/users/login.html @@ -1,24 +1,5 @@ - -
-

Sign In

-
diff --git a/partials/users/new_user_validation.html b/partials/users/new_user_validation.html new file mode 100644 index 0000000..3af1d0c --- /dev/null +++ b/partials/users/new_user_validation.html @@ -0,0 +1,60 @@ + + + +{{ with .UsernameError }} +
{{ . }}
+{{ end }} + + + + +{{ with .EmailError }} +
{{ . }}
+{{ end }} + + + + +{{ with .PasswordError }} +
{{ . }}
+{{ end }} + + + + +{{ with .PasswordConfirmationError }} +
{{ . }}
+{{ end }} + +
+
+ + diff --git a/server.go b/server.go index ee2b8ed..ac9843d 100644 --- a/server.go +++ b/server.go @@ -162,6 +162,7 @@ func main() { r.Get("/garbage_bin", garbageBin) r.Get("/nav/user_items", navUserItems) r.Route("/users", func(r chi.Router) { + r.Post("/new_user_validation", newUserValidationHandler) r.Get("/create", newAccountHandler) r.Post("/login", loginHandler) r.Post("/create", createAccount) @@ -175,8 +176,72 @@ func main() { } } -// loginHandler renders the login page +// newUserValidationHandler checks whether a username is available during account creation +func newUserValidationHandler(w http.ResponseWriter, r *http.Request) { + tmplVars := map[string]any{"ApiBaseUrl": apiURL()} + tmpl := template.Must(template.ParseFiles("partials/users/new_user_validation.html")) + errCnt := 0 + if err := r.ParseForm(); err != nil { + ise(err, w) + return + } + + username := r.PostForm.Get("username") + email := r.PostForm.Get("email") + password := r.PostForm.Get("password") + passwordConfirmation := r.PostForm.Get("password_confirmation") + + tmplVars["Username"] = username + tmplVars["Email"] = email + tmplVars["Password"] = password + tmplVars["PasswordConfirmation"] = passwordConfirmation + + log.Println("vars", tmplVars) + + if len(username) == 0 { + tmplVars["UsernameError"] = "Please choose a username" + errCnt += 1 + } else if len(username) > 0 { + var userID string + db.QueryRow(r.Context(), "SELECT id FROM users WHERE username = $1", username).Scan(&userID) + if userID != "" { + tmplVars["UsernameError"] = fmt.Sprintf("Username '%s' is unavailable. Choose a different username.", username) + errCnt += 1 + } + } + + if (len(email) > 0 && len(email) < 4) || (len(email) >= 4 && !strings.Contains(email, "@")) { + tmplVars["EmailError"] = "Please enter a valid email address." + errCnt += 1 + } + + if len(password) > 0 && len(password) < 8 { + tmplVars["PasswordError"] = "Please choose a password greater than 8 characters" + errCnt += 1 + } + + if len(password) > 0 && len(passwordConfirmation) > 0 && password != passwordConfirmation { + tmplVars["PasswordConfirmationError"] = "Passwords do not match" + errCnt += 1 + } + + tmplVars["ErrorCount"] = errCnt + + var buff = bytes.NewBufferString("") + err := tmpl.Execute(buff, tmplVars) + if err != nil { + ise(err, w) + return + } + + log.Println("respones", buff.String()) + w.Header().Add("Content-Type", "text/html") + w.WriteHeader(http.StatusOK) + w.Write(buff.Bytes()) +} + +// loginHandler renders the login page func loginHandler(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { ise(err, w) diff --git a/themes/terminal/assets/css/form.scss b/themes/terminal/assets/css/form.scss index 317df78..5a511de 100644 --- a/themes/terminal/assets/css/form.scss +++ b/themes/terminal/assets/css/form.scss @@ -42,7 +42,7 @@ input { } } -.auth-wrapper{ +.auth-wrapper { height: 100%; display: flex; align-items: center; @@ -50,9 +50,7 @@ input { } .auth-wrapper .auth-form { - max-width: 450px; width: 100%; - padding: 0 20px; } .auth-wrapper h1{margin-bottom: 20px;} @@ -62,3 +60,17 @@ label { margin: 0.5rem 0; } +.error-message { + color: red; +} + +.htmx-indicator { + display: inline-block; +} + +button:disabled, +button[disabled]{ + border: 1px solid #999999; + background-color: #cccccc; + color: #666666; +} diff --git a/themes/terminal/layouts/shortcodes/include.html b/themes/terminal/layouts/shortcodes/include.html new file mode 100644 index 0000000..577f98e --- /dev/null +++ b/themes/terminal/layouts/shortcodes/include.html @@ -0,0 +1,4 @@ +{{ $file := .Get 0 }} +{{ $file | readFile | safeHTML }} + +