From 57423aaedf0c6f981080927ed86f1d73b9037d82 Mon Sep 17 00:00:00 2001 From: darius Date: Sun, 19 May 2024 23:56:53 +0200 Subject: [PATCH] login added mostly done --- api/apiRoutes.go | 9 +++++-- api/handlers/authHandler.go | 14 +++++++--- api/handlers/mainHandler.go | 23 +++++++++++++++- database/query/authQuery.go | 2 +- go.mod | 2 ++ go.sum | 4 +++ go.work.sum | 2 ++ main.go | 19 ++++++++++++-- web/components/inputs.go | 42 ++++++++++++++++++++++++++++++ web/components/login.go | 23 ++++++++++++++++ web/components/navbar.go | 3 ++- web/handlers/aboutPageHandler.go | 2 +- web/handlers/loginPageHandler.go | 22 ++++++++++++++++ web/handlers/pageTemplates.go | 1 + web/handlers/projectPageHandler.go | 2 +- web/webRoutes.go | 1 + 16 files changed, 158 insertions(+), 13 deletions(-) create mode 100644 web/components/inputs.go create mode 100644 web/components/login.go create mode 100644 web/handlers/loginPageHandler.go diff --git a/api/apiRoutes.go b/api/apiRoutes.go index 5c6512b..f528da7 100644 --- a/api/apiRoutes.go +++ b/api/apiRoutes.go @@ -10,11 +10,16 @@ func ApiRoutes() *http.ServeMux { // Take incoming requests and dispatch them to the matching webHandler mux := http.NewServeMux() - // Register the routes and webHandler + // routes mux.HandleFunc("/", handlers.CatchAllHandler) - mux.HandleFunc("POST /register", handlers.CreateUser) + mux.HandleFunc("GET /check", handlers.CheckRoleHandler) + + //user mux.HandleFunc("GET /user/{id}", handlers.GetUser) + + //auth mux.HandleFunc("POST /login", handlers.Login) + mux.HandleFunc("POST /register", handlers.CreateUser) return mux } diff --git a/api/handlers/authHandler.go b/api/handlers/authHandler.go index 09d6c3f..7cde534 100644 --- a/api/handlers/authHandler.go +++ b/api/handlers/authHandler.go @@ -17,7 +17,7 @@ func Login(w http.ResponseWriter, r *http.Request) { if isHtmx == "true" { u = &ent.User{ - Name: r.PostFormValue("name"), + Email: r.PostFormValue("email"), Password: r.PostFormValue("password"), } } else { @@ -35,12 +35,18 @@ func Login(w http.ResponseWriter, r *http.Request) { if bcrypt.CheckPasswordHash(u.Password, User.Password) { - jwtToken := jwt.CreateUserJWT(u.Name, u.ID, string(u.Role)) + jwtToken := jwt.CreateUserJWT(User.Name, User.ID, string(User.Role)) if jwtToken != "" { - w.Header().Set("HX-Location", "/") - cookie := &http.Cookie{Name: "jwt", Value: jwtToken, HttpOnly: true, Secure: true, SameSite: http.SameSiteStrictMode} + cookie := &http.Cookie{Name: "jwt", + Value: jwtToken, + //HttpOnly: true, + //Secure: true, + //SameSite: http.SameSiteNoneMode, + //Expires: time.Now().Add(24 * time.Hour), + } + http.SetCookie(w, cookie) w.WriteHeader(http.StatusOK) diff --git a/api/handlers/mainHandler.go b/api/handlers/mainHandler.go index 1fb157e..8656519 100644 --- a/api/handlers/mainHandler.go +++ b/api/handlers/mainHandler.go @@ -1,6 +1,10 @@ package handlers -import "net/http" +import ( + "net/http" + "portfolio/api/service/jwt" + "strconv" +) func CatchAllHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusGone) @@ -9,3 +13,20 @@ func CatchAllHandler(w http.ResponseWriter, r *http.Request) { InternalServerErrorHandler(w, err) } } + +func CheckRoleHandler(w http.ResponseWriter, r *http.Request) { + jwtCookie, _ := r.Cookie("jwt") + + if jwtCookie != nil { + uid, audience, err := jwt.VerifyJWT(jwtCookie.Value) + if err != nil { + InternalServerErrorHandler(w, err) + return + } + w.WriteHeader(http.StatusOK) + w.Write([]byte("id: " + strconv.Itoa(uid) + "\naudience: " + audience)) + return + } + w.WriteHeader(http.StatusUnprocessableEntity) + w.Write([]byte("Cookie not found")) +} diff --git a/database/query/authQuery.go b/database/query/authQuery.go index a459a38..af20e27 100644 --- a/database/query/authQuery.go +++ b/database/query/authQuery.go @@ -12,7 +12,7 @@ import ( func GetLogin(ctx context.Context, U *ent.User) (*ent.User, error) { u, err := database.Client.User. Query(). - Where(user.Name(U.Name)). + Where(user.Email(U.Email)). Only(ctx) if err != nil { return nil, fmt.Errorf("failed querying user: %w", err) diff --git a/go.mod b/go.mod index 66ffc30..5cf9ae0 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/joho/godotenv v1.5.1 github.com/lib/pq v1.10.9 github.com/maragudk/gomponents v0.20.2 + github.com/maragudk/gomponents-htmx v0.5.0 github.com/willoma/bulma-gomponents v0.11.1 github.com/willoma/gomplements v0.6.1 golang.org/x/crypto v0.23.0 @@ -23,6 +24,7 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/hcl/v2 v2.19.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/rs/cors v1.11.0 // indirect github.com/zclconf/go-cty v1.14.2 // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/text v0.15.0 // indirect diff --git a/go.sum b/go.sum index 0e6d193..8d3fa24 100644 --- a/go.sum +++ b/go.sum @@ -36,12 +36,16 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/maragudk/gomponents v0.20.2 h1:39FhnBNNCJzqNcD9Hmvp/5xj0otweFoyvVgFG6kXoy0= github.com/maragudk/gomponents v0.20.2/go.mod h1:nHkNnZL6ODgMBeJhrZjkMHVvNdoYsfmpKB2/hjdQ0Hg= +github.com/maragudk/gomponents-htmx v0.5.0 h1:sWtiRa72YmymgxccjTNZW3h0akKsZvnhYke9RQiS9dk= +github.com/maragudk/gomponents-htmx v0.5.0/go.mod h1:XgI7WE6ECWlyeVQ9Ix3R6aoKS4HtCSYtuQ4iH27GVDE= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= +github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= diff --git a/go.work.sum b/go.work.sum index 952ec8d..f622113 100644 --- a/go.work.sum +++ b/go.work.sum @@ -27,6 +27,8 @@ github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LF github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/maragudk/is v0.1.0 h1:obq9anZNmOYcaNbeT0LMyjIexdNeYTw/TLAPD/BnZHA= +github.com/maragudk/is v0.1.0/go.mod h1:W/r6+TpnISu+a88OLXQy5JQGCOhXQXXLD2e5b4xMn5c= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= diff --git a/main.go b/main.go index 2d5e05d..637c733 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "github.com/joho/godotenv" + "github.com/rs/cors" "log" "net/http" "portfolio/api" @@ -23,11 +24,25 @@ func main() { //init web routes webMux := web.WebRoutes() // Run web server - go http.ListenAndServe(":4000", webMux) + go http.ListenAndServe(":4000", cors.AllowAll().Handler(webMux)) + + c := cors.New(cors.Options{ + AllowedOrigins: []string{"*"}, + AllowedMethods: []string{ + http.MethodHead, + http.MethodGet, + http.MethodPost, + http.MethodPut, + http.MethodPatch, + http.MethodDelete, + }, + AllowedHeaders: []string{"*"}, + AllowCredentials: true, + }) //init api routes apiMux := api.ApiRoutes() //run api server - http.ListenAndServe(":4001", apiMux) + http.ListenAndServe(":4001", c.Handler(apiMux)) } diff --git a/web/components/inputs.go b/web/components/inputs.go new file mode 100644 index 0000000..8179d5a --- /dev/null +++ b/web/components/inputs.go @@ -0,0 +1,42 @@ +package components + +import ( + "github.com/delaneyj/gomponents-iconify/iconify/mdi" + g "github.com/maragudk/gomponents" + b "github.com/willoma/bulma-gomponents" + e "github.com/willoma/gomplements" +) + +func Email(valid bool, invalid bool, color e.Element) e.Element { + return b.Field( + b.Label("Email"), + b.Control( + b.IconsLeft, + b.InputEmail( + e.Name("email"), + color, + e.Placeholder("Email input"), + ), + b.Icon(mdi.Email(), b.Left), + ), + g.If(invalid, b.Help(b.Danger, "This email is invalid")), + g.If(valid, b.Help(b.Success, "This email is valid")), + ) +} + +func Password(valid bool, invalid bool, color e.Element) e.Element { + return b.Field( + b.Label("Email"), + b.Control( + b.IconsLeft, + b.InputPassword( + e.Name("password"), + color, + e.Placeholder("password input"), + ), + b.Icon(mdi.FormTextboxPassword(), b.Left), + ), + g.If(invalid, b.Help(b.Danger, "This password is invalid")), + g.If(valid, b.Help(b.Success, "This password is valid")), + ) +} diff --git a/web/components/login.go b/web/components/login.go new file mode 100644 index 0000000..a6d445f --- /dev/null +++ b/web/components/login.go @@ -0,0 +1,23 @@ +package components + +import ( + g "github.com/maragudk/gomponents" + hx "github.com/maragudk/gomponents-htmx" + . "github.com/maragudk/gomponents/html" + b "github.com/willoma/bulma-gomponents" +) + +func Login() g.Node { + return FormEl(hx.Post("http://localhost:4001/login"), + b.Section( + Email(false, false, nil), + Password(false, false, nil), + b.Field( + b.Grouped, + b.Control( + b.Button(b.Link, "login"), + ), + ), + ), + ) +} diff --git a/web/components/navbar.go b/web/components/navbar.go index 885cd4b..f1444fc 100644 --- a/web/components/navbar.go +++ b/web/components/navbar.go @@ -35,7 +35,8 @@ func Navbar() g.Node { b.NavbarEnd( b.NavbarItem( b.Buttons( - b.ButtonA( + b.ButtonAHref( + "/login", b.Primary, "Log in", ), diff --git a/web/handlers/aboutPageHandler.go b/web/handlers/aboutPageHandler.go index d7ac1e4..9af2ce4 100644 --- a/web/handlers/aboutPageHandler.go +++ b/web/handlers/aboutPageHandler.go @@ -8,7 +8,7 @@ import ( func AboutPageHandler(w http.ResponseWriter, r *http.Request) { - err := Page("Homepage", createAboutBody(w, r)).Render(w) + err := Page("About page", createAboutBody(w, r)).Render(w) if err != nil { return } diff --git a/web/handlers/loginPageHandler.go b/web/handlers/loginPageHandler.go new file mode 100644 index 0000000..7cf08b1 --- /dev/null +++ b/web/handlers/loginPageHandler.go @@ -0,0 +1,22 @@ +package handlers + +import ( + g "github.com/maragudk/gomponents" + . "github.com/maragudk/gomponents/html" + "net/http" + "portfolio/web/components" +) + +func LoginPageHandler(w http.ResponseWriter, r *http.Request) { + + err := Page("login page", createLoginBody(w, r)).Render(w) + if err != nil { + return + } + +} + +func createLoginBody(w http.ResponseWriter, r *http.Request) g.Node { + + return Body(components.Login()) +} diff --git a/web/handlers/pageTemplates.go b/web/handlers/pageTemplates.go index 6581a15..029ba42 100644 --- a/web/handlers/pageTemplates.go +++ b/web/handlers/pageTemplates.go @@ -14,6 +14,7 @@ func Page(title string, body g.Node) g.Node { Language: "en", Head: []g.Node{ Script(Src("https://cdn.tailwindcss.com?plugins=typography")), + Script(Src("https://unpkg.com/htmx.org")), Link(Rel("icon"), Type("image/x-icon"), Href("assets/images/favicon.ico")), //Link(Rel("stylesheet"), Href("https://cdn.jsdelivr.net/npm/bulma@1.0.0/css/bulma.min.css")), Link(Rel("stylesheet"), Href("assets/css/style.css")), diff --git a/web/handlers/projectPageHandler.go b/web/handlers/projectPageHandler.go index c91c1a7..70ca87f 100644 --- a/web/handlers/projectPageHandler.go +++ b/web/handlers/projectPageHandler.go @@ -10,7 +10,7 @@ import ( func ProjectPageHandler(w http.ResponseWriter, r *http.Request) { - err := Page("Homepage", createProjectBody(w, r)).Render(w) + err := Page("Project page", createProjectBody(w, r)).Render(w) if err != nil { return } diff --git a/web/webRoutes.go b/web/webRoutes.go index de3432e..2b9607e 100644 --- a/web/webRoutes.go +++ b/web/webRoutes.go @@ -14,6 +14,7 @@ func WebRoutes() *http.ServeMux { mux.HandleFunc("/", handlers.HomePageHandler) mux.HandleFunc("/projects", handlers.ProjectPageHandler) mux.HandleFunc("/about", handlers.AboutPageHandler) + mux.HandleFunc("/login", handlers.LoginPageHandler) mux.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("./web/assets")))) return mux