From f70d3e9994aa449dd6f7061c3afa658563fd30bc Mon Sep 17 00:00:00 2001 From: Gary Murphy Date: Tue, 2 May 2023 02:11:01 +0100 Subject: [PATCH 1/3] Backend authentication endpoints --- src/PanoptesFrontend/Pages/Register.razor | 3 + .../Services/AccountService.cs | 6 +- src/backend/cmd/main.go | 147 ++++++++++++++---- src/backend/go.mod | 13 +- src/backend/go.sum | 37 +++-- 5 files changed, 154 insertions(+), 52 deletions(-) diff --git a/src/PanoptesFrontend/Pages/Register.razor b/src/PanoptesFrontend/Pages/Register.razor index f548edb..9d07928 100644 --- a/src/PanoptesFrontend/Pages/Register.razor +++ b/src/PanoptesFrontend/Pages/Register.razor @@ -1,6 +1,7 @@ @page "/account/register" @using PanoptesFrontend.Data.Account; @using PanoptesFrontend.Services; +@using System.Text.Json; @inject IAccountService AccountService @@ -33,6 +34,8 @@ private async void OnValidSubmit() { Console.WriteLine("Method called"); + var user = JsonSerializer.Serialize(model); + Console.WriteLine(user); await AccountService.Register(model); } } \ No newline at end of file diff --git a/src/PanoptesFrontend/Services/AccountService.cs b/src/PanoptesFrontend/Services/AccountService.cs index a50067e..67e6008 100644 --- a/src/PanoptesFrontend/Services/AccountService.cs +++ b/src/PanoptesFrontend/Services/AccountService.cs @@ -25,16 +25,16 @@ public class AccountService : IAccountService public async Task Register(AddUser model){ // endpoint doesnt exist yet - await httpService.PostAsync("http://localhost:8080/user/register", model); + await httpService.PostAsync("http://localhost:10000/user/register", model); } public async Task Login(LoginUser model){ // endpoint doesnt exist yet - await httpService.PostAsync("http://localhost:8080/user/authenticate", model); + await httpService.PostAsync("http://localhost:10000/user/login", model); } public async Task Logout(User model){ // endpoint doesnt exist yet - await httpService.PostAsync("http://localhost:8080/user/logout", model); + await httpService.PostAsync("http://localhost:10000/user/logout", model); } } \ No newline at end of file diff --git a/src/backend/cmd/main.go b/src/backend/cmd/main.go index ea487a1..66c5cd3 100644 --- a/src/backend/cmd/main.go +++ b/src/backend/cmd/main.go @@ -3,11 +3,13 @@ package main import ( "database/sql" - "encoding/json" + _"encoding/json" "fmt" "io/ioutil" "log" "net/http" + "github.com/dgrijalva/jwt-go" + "golang.org/x/crypto/bcrypt" "github.com/labstack/echo/v4" "gitlab.computing.dcu.ie/murphg62/2023-ca400-murphg62-byrnm257/src/backend/pkg/database" @@ -23,6 +25,7 @@ const ( ) var db, err = database.ConnectDB(host, port, user, password, dbname) +var jwtSecret = []byte("fAHr+Hlho9qhCePEuMxLVG2i/1tiEqtocAWkcYRJx0s=") type Schema struct { Name string `json:"Name"` @@ -35,6 +38,11 @@ type Module struct { Container string `json:"Container"` } +type User struct { + Username string `json:"Username"` + Password string `json:"Password"` +} + func homePage(c echo.Context) error { return c.String(http.StatusOK, "Welcome to the home page!") @@ -80,44 +88,131 @@ func getStats(c echo.Context) error { } -func GetModules(db *sql.DB) http.HandlerFunc{ - return func(w http.ResponseWriter, r *http.Request) { - if r.Method == "GET" { - var Modules []Module - rows, err := db.Query("Select name, container_name FROM Module") - if err != nil { - panic(err) - } - defer rows.Close() - - for rows.Next() { - var module Module - if err := rows.Scan(&module.Name, &module.Container); err != nil { - panic(err) - } - Modules = append(Modules, module) - } +func GetModules(db *sql.DB) echo.HandlerFunc { + return func(c echo.Context) error { + modules := make([]Module, 0) + rows, err := db.Query("SELECT name, container_name FROM Module") + if err != nil { + return err + } + defer rows.Close() - w.Header().Set("Content-Type", "application/json") - if err := json.NewEncoder(w).Encode(Modules); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } - } - } + for rows.Next() { + var module Module + if err := rows.Scan(&module.Name, &module.Container); err != nil { + return err + } + modules = append(modules, module) + } + + return c.JSON(http.StatusOK, modules) + } } +func RegisterUser(db *sql.DB) echo.HandlerFunc { + return func(c echo.Context) error { + user := new(User) + if err := c.Bind(user); err != nil { + return err + } + + // Check if user already exists + var count int + if err := db.QueryRow("SELECT COUNT(*) FROM users WHERE name = $1", user.Username).Scan(&count); err != nil { + return err + } + if count > 0 { + return c.JSON(http.StatusBadRequest, map[string]string{"error": "Username already in use"}) + } + + // Hash password + hashedPassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost) + if err != nil { + return err + } + + // Insert new user into database + _, err = db.Exec("INSERT INTO users(name, password) VALUES ($1, $2)", user.Username, string(hashedPassword)) + if err != nil { + return err + } + + return c.JSON(http.StatusOK, map[string]string{"message": "User created"}) + } +} + + +func LoginUser(db *sql.DB, jwtSecret []byte) echo.HandlerFunc { + return func(c echo.Context) error { + login := new(User) + if err := c.Bind(login); err != nil { + return err + } + + // Check if user exists + var user User + if err := db.QueryRow("SELECT name, password FROM users WHERE name = $1", login.Username).Scan(&user.Username, &user.Password); err != nil { + if err == sql.ErrNoRows { + return c.JSON(http.StatusBadRequest, map[string]string{"error": "Invalid username or password"}) + } + return err + } + + if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(login.Password)); err != nil { + return c.JSON(http.StatusBadRequest, map[string]string{"error": "Invalid username or password"}) + } + + // Generate JWT token + token := jwt.New(jwt.SigningMethodHS256) + claims := token.Claims.(jwt.MapClaims) + claims["name"] = user.Username + tokenString, err := token.SignedString(jwtSecret) + if err != nil { + return err + } + + return c.JSON(http.StatusOK, map[string]string{"token": tokenString}) + } +} + +func LogoutUser() echo.HandlerFunc { + return func(c echo.Context) error { + // Clear JWT token cookie + cookie := &http.Cookie{ + Name: "jwt", + Value: "", + HttpOnly: true, + Path: "/", + } + http.SetCookie(c.Response().Writer, cookie) + + return c.NoContent(http.StatusOK) + } +} + + func main() { if err != nil { panic(err) } db.Exec(`CREATE TABLE IF NOT EXISTS Module ( name VARCHAR(64), - container_name VARCHAR(64) - )`) + container_name VARCHAR(64)); + + CREATE TABLE IF NOT EXISTS users ( + id SERIAL PRIMARY KEY, + name VARCHAR(64) UNIQUE NOT NULL, + password VARCHAR(255) NOT NULL + ) + `) e := echo.New() e.GET("/", homePage) e.GET("/:container/schema", getSchema) e.GET("/:container/stats", getStats) + e.GET("/modules", GetModules(db)) + e.POST("/user/register", RegisterUser(db)) + e.POST("/user/login", LoginUser(db, jwtSecret)) + e.POST("/user/logout", LogoutUser()) e.Logger.Fatal(e.Start(":10000")) defer db.Close() } diff --git a/src/backend/go.mod b/src/backend/go.mod index f18123d..aacd066 100644 --- a/src/backend/go.mod +++ b/src/backend/go.mod @@ -12,15 +12,16 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect + github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect github.com/labstack/gommon v0.4.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - golang.org/x/crypto v0.6.0 // indirect - golang.org/x/net v0.7.0 // indirect - golang.org/x/sys v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect + golang.org/x/crypto v0.8.0 // indirect + golang.org/x/net v0.9.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/src/backend/go.sum b/src/backend/go.sum index 2be4c4a..521cb41 100644 --- a/src/backend/go.sum +++ b/src/backend/go.sum @@ -2,8 +2,9 @@ github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20O github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M= @@ -12,22 +13,6 @@ github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8 github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/lib/pq v1.10.8 h1:3fdt97i/cwSU83+E0hZTC/Xpc9mTZxc6UWSCRcSbxiE= github.com/lib/pq v1.10.8/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -35,9 +20,16 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= @@ -45,18 +37,29 @@ github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQ github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From fba938fa2ce7837b19f844d7f0264b5aff822c0c Mon Sep 17 00:00:00 2001 From: Gary Murphy Date: Tue, 2 May 2023 19:47:01 +0100 Subject: [PATCH 2/3] updated service to save and delete json token --- src/PanoptesFrontend/PanoptesFrontend.csproj | 1 + src/PanoptesFrontend/Program.cs | 6 ++++-- .../Services/AccountService.cs | 21 ++++++++++++------- src/PanoptesFrontend/Services/HttpService.cs | 12 +++++------ 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/PanoptesFrontend/PanoptesFrontend.csproj b/src/PanoptesFrontend/PanoptesFrontend.csproj index 9c62f3a..7b8342f 100644 --- a/src/PanoptesFrontend/PanoptesFrontend.csproj +++ b/src/PanoptesFrontend/PanoptesFrontend.csproj @@ -8,6 +8,7 @@ + diff --git a/src/PanoptesFrontend/Program.cs b/src/PanoptesFrontend/Program.cs index 8349c9f..66258be 100644 --- a/src/PanoptesFrontend/Program.cs +++ b/src/PanoptesFrontend/Program.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; using PanoptesFrontend.Services; +using Blazored.LocalStorage; var builder = WebApplication.CreateBuilder(args); @@ -8,8 +9,9 @@ var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); builder.Services.AddHttpClient(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddBlazoredLocalStorage(); var app = builder.Build(); diff --git a/src/PanoptesFrontend/Services/AccountService.cs b/src/PanoptesFrontend/Services/AccountService.cs index 67e6008..21a3915 100644 --- a/src/PanoptesFrontend/Services/AccountService.cs +++ b/src/PanoptesFrontend/Services/AccountService.cs @@ -1,8 +1,7 @@ using PanoptesFrontend.Data.Account; using PanoptesFrontend.Data; -using Microsoft.AspNetCore.Components; -using System.Collections.Generic; -using System.Threading.Tasks; +using Blazored.LocalStorage; +using System.Text.Json; namespace PanoptesFrontend.Services; @@ -17,24 +16,30 @@ public interface IAccountService public class AccountService : IAccountService { private IHttpService httpService; + private ILocalStorageService localStorage; - public AccountService(IHttpService httpService) { + public AccountService(IHttpService httpService, ILocalStorageService localStorage) { this.httpService = httpService; + this.localStorage = localStorage; } public async Task Register(AddUser model){ - // endpoint doesnt exist yet await httpService.PostAsync("http://localhost:10000/user/register", model); } public async Task Login(LoginUser model){ - // endpoint doesnt exist yet - await httpService.PostAsync("http://localhost:10000/user/login", model); + var response = await httpService.PostAsync("http://localhost:10000/user/login", model); + + var jsonDoc = JsonDocument.Parse(response); + var token = jsonDoc.RootElement.GetProperty("token").GetString(); + + // Save the JWT token to local storage + await localStorage.SetItemAsync("authToken", token); } public async Task Logout(User model){ - // endpoint doesnt exist yet await httpService.PostAsync("http://localhost:10000/user/logout", model); + await localStorage.RemoveItemAsync("authToken"); } } \ No newline at end of file diff --git a/src/PanoptesFrontend/Services/HttpService.cs b/src/PanoptesFrontend/Services/HttpService.cs index 1b60c6b..30171a8 100644 --- a/src/PanoptesFrontend/Services/HttpService.cs +++ b/src/PanoptesFrontend/Services/HttpService.cs @@ -8,7 +8,7 @@ using System.Text.Json; public interface IHttpService { Task GetAsync(string endpoint); - Task PostAsync(string endpoint, object value); + Task PostAsync(string endpoint, object value); } public class HttpService : IHttpService { @@ -32,11 +32,9 @@ public class HttpService : IHttpService { } } - public async Task PostAsync(string endpoint, object value){ - var request = await httpClient.PostAsJsonAsync(endpoint, value); - - request.EnsureSuccessStatusCode(); - - return request.StatusCode; + public async Task PostAsync(string endpoint, object value){ + var response = await httpClient.PostAsJsonAsync(endpoint, value); + response.EnsureSuccessStatusCode(); + return await response.Content.ReadAsStringAsync(); } } \ No newline at end of file From e5e0a5b1068aa839a77c44437294578f7f8243a6 Mon Sep 17 00:00:00 2001 From: Gary Murphy Date: Tue, 2 May 2023 20:04:42 +0100 Subject: [PATCH 3/3] fixed merge conflict --- src/PanoptesFrontend/PanoptesFrontend.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/PanoptesFrontend/PanoptesFrontend.csproj b/src/PanoptesFrontend/PanoptesFrontend.csproj index 7b8342f..5a8076c 100644 --- a/src/PanoptesFrontend/PanoptesFrontend.csproj +++ b/src/PanoptesFrontend/PanoptesFrontend.csproj @@ -10,6 +10,10 @@ + + + +