From 376de282f26a113b9d7d19eef34e5944b159f0ee Mon Sep 17 00:00:00 2001 From: leandrofars Date: Sat, 23 Dec 2023 11:23:20 -0300 Subject: [PATCH 01/15] fix(security): jwt package --- backend/services/controller/go.mod | 6 ++-- backend/services/controller/go.sum | 5 ++-- .../controller/internal/api/auth/auth.go | 28 ++++++++++++------- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/backend/services/controller/go.mod b/backend/services/controller/go.mod index 9841213..792664d 100755 --- a/backend/services/controller/go.mod +++ b/backend/services/controller/go.mod @@ -3,8 +3,9 @@ module github.com/leandrofars/oktopus go 1.18 require ( - github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/eclipse/paho.golang v0.10.0 + github.com/go-stomp/stomp v2.1.4+incompatible + github.com/golang-jwt/jwt/v5 v5.2.0 github.com/google/uuid v1.3.0 github.com/googollee/go-socket.io v1.7.0 github.com/gorilla/mux v1.8.0 @@ -13,11 +14,11 @@ require ( go.mongodb.org/mongo-driver v1.11.3 golang.org/x/crypto v0.14.0 golang.org/x/net v0.17.0 + golang.org/x/sys v0.13.0 google.golang.org/protobuf v1.28.1 ) require ( - github.com/go-stomp/stomp v2.1.4+incompatible // indirect github.com/gofrs/uuid v4.0.0+incompatible // indirect github.com/golang/snappy v0.0.1 // indirect github.com/gomodule/redigo v1.8.4 // indirect @@ -30,6 +31,5 @@ require ( github.com/xdg-go/stringprep v1.0.3 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect - golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect ) diff --git a/backend/services/controller/go.sum b/backend/services/controller/go.sum index c6c36ac..c4ef347 100644 --- a/backend/services/controller/go.sum +++ b/backend/services/controller/go.sum @@ -1,14 +1,14 @@ 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.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/eclipse/paho.golang v0.10.0 h1:oUGPjRwWcZQRgDD9wVDV7y7i7yBSxts3vcvcNJo8B4Q= github.com/eclipse/paho.golang v0.10.0/go.mod h1:rhrV37IEwauUyx8FHrvmXOKo+QRKng5ncoN1vJiJMcs= github.com/go-stomp/stomp v2.1.4+incompatible h1:D3SheUVDOz9RsjVWkoh/1iCOwD0qWjyeTZMUZ0EXg2Y= github.com/go-stomp/stomp v2.1.4+incompatible/go.mod h1:VqCtqNZv1226A1/79yh+rMiFUcfY3R109np+7ke4n0c= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= +github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -85,6 +85,7 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/backend/services/controller/internal/api/auth/auth.go b/backend/services/controller/internal/api/auth/auth.go index e1a2712..d93eeda 100644 --- a/backend/services/controller/internal/api/auth/auth.go +++ b/backend/services/controller/internal/api/auth/auth.go @@ -2,9 +2,12 @@ package auth import ( "errors" - "github.com/dgrijalva/jwt-go" + "fmt" + "log" "os" "time" + + "github.com/golang-jwt/jwt/v5" ) func getJwtKey() []byte { @@ -18,16 +21,17 @@ func getJwtKey() []byte { type JWTClaim struct { Username string `json:"username"` Email string `json:"email"` - jwt.StandardClaims + jwt.RegisteredClaims } func GenerateJWT(email string, username string) (tokenString string, err error) { expirationTime := time.Now().Add(4 * time.Hour) claims := &JWTClaim{ - Email: email, - Username: username, - StandardClaims: jwt.StandardClaims{ - ExpiresAt: expirationTime.Unix(), + username, + email, + jwt.RegisteredClaims{ + ExpiresAt: jwt.NewNumericDate(expirationTime), + Issuer: "Oktopus", }, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) @@ -40,21 +44,25 @@ func ValidateToken(signedToken string) (email string, err error) { signedToken, &JWTClaim{}, func(token *jwt.Token) (interface{}, error) { + // Don't forget to validate the alg is what you expect: + if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { + return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) + } + + // hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key") return getJwtKey(), nil }, ) if err != nil { + log.Println(err) return } + claims, ok := token.Claims.(*JWTClaim) if !ok { err = errors.New("couldn't parse claims") return } - if claims.ExpiresAt < time.Now().Local().Unix() { - err = errors.New("token expired") - return - } email = claims.Email From b15ab6b5f0ad7c9bcd7bcffec8cef4f7f6b31828 Mon Sep 17 00:00:00 2001 From: leandrofars Date: Sat, 23 Dec 2023 11:23:54 -0300 Subject: [PATCH 02/15] feat: nginx config for landing site --- devops/nginx/nginx.conf | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/devops/nginx/nginx.conf b/devops/nginx/nginx.conf index 597e147..c548171 100644 --- a/devops/nginx/nginx.conf +++ b/devops/nginx/nginx.conf @@ -34,6 +34,44 @@ http { # for more information. include /etc/nginx/conf.d/*.conf; + server { + if ($host = oktopus.app.br) { + return 301 https://$host$request_uri; + } + listen 80; + listen [::]:80; + server_name oktopus.app.br; + return 404; + } + + server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name oktopus.app.br; + root /usr/share/nginx/html; + + # Load configuration files for the default server block. + include /etc/nginx/default.d/*.conf; + + ssl_certificate "/etc/letsencrypt/live/oktopus.app.br/fullchain.pem"; + ssl_certificate_key "/etc/letsencrypt/live/oktopus.app.br/privkey.pem"; + ssl_session_cache shared:SSL:1m; + ssl_session_timeout 10m; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + + error_page 404 /404.html; + location = /404.html { + } + + location / { + proxy_pass http://127.0.0.1:3001; + proxy_read_timeout 60; + proxy_connect_timeout 60; + proxy_redirect off; + } + } + server { if ($host = oktopustr369.com) { return 301 https://$host$request_uri; From c8e0b3ef007dd74f3d5251ed5847d544f1e58643 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 23 Dec 2023 14:59:51 +0000 Subject: [PATCH 03/15] chore(deps): bump golang.org/x/crypto in /backend/services/controller Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.14.0 to 0.17.0. - [Commits](https://github.com/golang/crypto/compare/v0.14.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- backend/services/controller/go.mod | 8 ++++---- backend/services/controller/go.sum | 13 +++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) mode change 100755 => 100644 backend/services/controller/go.mod diff --git a/backend/services/controller/go.mod b/backend/services/controller/go.mod old mode 100755 new mode 100644 index 9841213..f6ab081 --- a/backend/services/controller/go.mod +++ b/backend/services/controller/go.mod @@ -5,19 +5,20 @@ go 1.18 require ( github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/eclipse/paho.golang v0.10.0 + github.com/go-stomp/stomp v2.1.4+incompatible github.com/google/uuid v1.3.0 github.com/googollee/go-socket.io v1.7.0 github.com/gorilla/mux v1.8.0 github.com/joho/godotenv v1.5.1 github.com/rs/cors v1.9.0 go.mongodb.org/mongo-driver v1.11.3 - golang.org/x/crypto v0.14.0 + golang.org/x/crypto v0.17.0 golang.org/x/net v0.17.0 + golang.org/x/sys v0.15.0 google.golang.org/protobuf v1.28.1 ) require ( - github.com/go-stomp/stomp v2.1.4+incompatible // indirect github.com/gofrs/uuid v4.0.0+incompatible // indirect github.com/golang/snappy v0.0.1 // indirect github.com/gomodule/redigo v1.8.4 // indirect @@ -30,6 +31,5 @@ require ( github.com/xdg-go/stringprep v1.0.3 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/text v0.14.0 // indirect ) diff --git a/backend/services/controller/go.sum b/backend/services/controller/go.sum index c6c36ac..402cf48 100644 --- a/backend/services/controller/go.sum +++ b/backend/services/controller/go.sum @@ -60,8 +60,8 @@ github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7Jul go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= @@ -71,13 +71,13 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -85,6 +85,7 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From 921ae3ea31efdebc92977e26a230f3ec928a556d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 23 Dec 2023 15:59:56 +0000 Subject: [PATCH 04/15] chore(deps): bump @koa/cors in /backend/services/socketio Bumps [@koa/cors](https://github.com/koajs/cors) from 4.0.0 to 5.0.0. - [Changelog](https://github.com/koajs/cors/blob/master/History.md) - [Commits](https://github.com/koajs/cors/compare/4.0.0...5.0.0) --- updated-dependencies: - dependency-name: "@koa/cors" dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- backend/services/socketio/package-lock.json | 14 +++++++------- backend/services/socketio/package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/backend/services/socketio/package-lock.json b/backend/services/socketio/package-lock.json index 7e3dbe9..954c709 100644 --- a/backend/services/socketio/package-lock.json +++ b/backend/services/socketio/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@koa/cors": "^4.0.0", + "@koa/cors": "^5.0.0", "cors": "^2.8.5", "dotenv": "^16.3.1", "express": "^4.18.2", @@ -18,9 +18,9 @@ } }, "node_modules/@koa/cors": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@koa/cors/-/cors-4.0.0.tgz", - "integrity": "sha512-Y4RrbvGTlAaa04DBoPBWJqDR5gPj32OOz827ULXfgB1F7piD1MB/zwn8JR2LAnvdILhxUbXbkXGWuNVsFuVFCQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@koa/cors/-/cors-5.0.0.tgz", + "integrity": "sha512-x/iUDjcS90W69PryLDIMgFyV21YLTnG9zOpPXS7Bkt2b8AsY3zZsIpOLBkYr9fBcF3HbkKaER5hOBZLfpLgYNw==", "dependencies": { "vary": "^1.1.2" }, @@ -1084,9 +1084,9 @@ }, "dependencies": { "@koa/cors": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@koa/cors/-/cors-4.0.0.tgz", - "integrity": "sha512-Y4RrbvGTlAaa04DBoPBWJqDR5gPj32OOz827ULXfgB1F7piD1MB/zwn8JR2LAnvdILhxUbXbkXGWuNVsFuVFCQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@koa/cors/-/cors-5.0.0.tgz", + "integrity": "sha512-x/iUDjcS90W69PryLDIMgFyV21YLTnG9zOpPXS7Bkt2b8AsY3zZsIpOLBkYr9fBcF3HbkKaER5hOBZLfpLgYNw==", "requires": { "vary": "^1.1.2" } diff --git a/backend/services/socketio/package.json b/backend/services/socketio/package.json index 7c6dbf5..bf28997 100644 --- a/backend/services/socketio/package.json +++ b/backend/services/socketio/package.json @@ -11,7 +11,7 @@ "author": "", "license": "ISC", "dependencies": { - "@koa/cors": "^4.0.0", + "@koa/cors": "^5.0.0", "cors": "^2.8.5", "dotenv": "^16.3.1", "express": "^4.18.2", From e207bd0f0a42a9d3e570f5642f0ae00cd4ba5f16 Mon Sep 17 00:00:00 2001 From: leandrofars Date: Sun, 24 Dec 2023 11:19:32 -0300 Subject: [PATCH 05/15] feat: script to run agent --- agent/run.sh | 1 + 1 file changed, 1 insertion(+) create mode 100644 agent/run.sh diff --git a/agent/run.sh b/agent/run.sh new file mode 100644 index 0000000..996e4a4 --- /dev/null +++ b/agent/run.sh @@ -0,0 +1 @@ +obuspa -p -v 4 -r ./oktopus-mqtt-obuspa.txt -i lo \ No newline at end of file From 3fa8315d622e895392be98345589e775e543b87e Mon Sep 17 00:00:00 2001 From: leandrofars Date: Sun, 24 Dec 2023 11:19:53 -0300 Subject: [PATCH 06/15] fix(controller): list device by id --- backend/services/controller/internal/api/device.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/backend/services/controller/internal/api/device.go b/backend/services/controller/internal/api/device.go index af4e798..8c0675b 100644 --- a/backend/services/controller/internal/api/device.go +++ b/backend/services/controller/internal/api/device.go @@ -2,11 +2,12 @@ package api import ( "encoding/json" - "go.mongodb.org/mongo-driver/bson" "log" "net/http" "strconv" + "go.mongodb.org/mongo-driver/bson" + "github.com/gorilla/mux" "github.com/leandrofars/oktopus/internal/db" usp_msg "github.com/leandrofars/oktopus/internal/usp_message" @@ -37,11 +38,15 @@ func (a *Api) retrieveDevices(w http.ResponseWriter, r *http.Request) { const PAGE_SIZE_DEFAULT = 20 // Get specific device - id := mux.Vars(r)["id"] + id := r.URL.Query().Get("id") if id != "" { device, err := a.Db.RetrieveDevice(id) if err != nil { - log.Println(err) + if err == mongo.ErrNoDocuments { + json.NewEncoder(w).Encode("Device id: " + id + " not found") + return + } + json.NewEncoder(w).Encode(err) w.WriteHeader(http.StatusInternalServerError) return } From 318720d9fa7389414068aea11ec1be29ec859c11 Mon Sep 17 00:00:00 2001 From: leandrofars Date: Sun, 24 Dec 2023 13:21:21 -0300 Subject: [PATCH 07/15] feat(controller): add details for devices list --- backend/services/controller/internal/api/device.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/backend/services/controller/internal/api/device.go b/backend/services/controller/internal/api/device.go index 8c0675b..d533217 100644 --- a/backend/services/controller/internal/api/device.go +++ b/backend/services/controller/internal/api/device.go @@ -98,6 +98,7 @@ func (a *Api) retrieveDevices(w http.ResponseWriter, r *http.Request) { if err != nil { w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode("Unable to get devices count from database") + return } skip := page_number * (page_size - 1) @@ -122,12 +123,15 @@ func (a *Api) retrieveDevices(w http.ResponseWriter, r *http.Request) { return } - err = json.NewEncoder(w).Encode(devices) + err = json.NewEncoder(w).Encode(map[string]interface{}{ + "pages": total / page_size, + "page": page_number, + "size": page_size, + "devices": devices, + }) if err != nil { log.Println(err) } - - return } func (a *Api) deviceCreateMsg(w http.ResponseWriter, r *http.Request) { From 763fe6efa2e7bd399edeb17dc080d04aa07870cf Mon Sep 17 00:00:00 2001 From: leandrofars Date: Wed, 27 Dec 2023 21:48:50 -0300 Subject: [PATCH 08/15] feat(frontend): get device per id + init pagination --- frontend/src/pages/devices.js | 134 ++++++++++++++++++++++++++++++++-- 1 file changed, 129 insertions(+), 5 deletions(-) diff --git a/frontend/src/pages/devices.js b/frontend/src/pages/devices.js index 5defbb1..2f9b2bf 100644 --- a/frontend/src/pages/devices.js +++ b/frontend/src/pages/devices.js @@ -1,6 +1,17 @@ import React, { useState, useEffect } from 'react'; import Head from 'next/head'; -import { Box, Container, Unstable_Grid2 as Grid } from '@mui/material'; +import { + Box, + Container, + Unstable_Grid2 as Grid, + Card, + OutlinedInput, + InputAdornment, + SvgIcon, + Stack, + Pagination +} from '@mui/material'; +import MagnifyingGlassIcon from '@heroicons/react/24/solid/MagnifyingGlassIcon'; import { Layout as DashboardLayout } from 'src/layouts/dashboard/layout'; import { OverviewLatestOrders } from 'src/sections/overview/overview-latest-orders'; import { useAuth } from 'src/hooks/use-auth'; @@ -10,6 +21,10 @@ const Page = () => { const router = useRouter() const auth = useAuth(); const [devices, setDevices] = useState([]); + const [deviceFound, setDeviceFound] = useState(false) + const [pages, setPages] = useState(0); + const [page, setPage] = useState(null); + useEffect(() => { @@ -36,13 +51,70 @@ const Page = () => { return response.json() }) .then(json => { - return setDevices(json) + setPages(json.pages + 1) + setPage(json.page) + setDevices(json.devices) + return setDeviceFound(true) }) .catch(error => { return console.error('Error:', error) }); }, [auth.user]); + const handleChangePage = (e) => { + console.log("new page: ", e.target.value) + //TODO: Handle page change + } + + const fetchDevicePerId = async (id) => { + + var myHeaders = new Headers(); + myHeaders.append("Content-Type", "application/json"); + myHeaders.append("Authorization", auth.user.token); + + var requestOptions = { + method: 'GET', + headers: myHeaders, + redirect: 'follow' + } + + if (id == ""){ + fetch(process.env.NEXT_PUBLIC_REST_ENPOINT+'/device', requestOptions) + .then(response => { + if (response.status === 401) + router.push("/auth/login") + return response.json() + }) + .then(json => { + setPages(json.pages + 1) + setPage(json.page) + setDevices(json.devices) + return setDeviceFound(true) + }) + .catch(error => { + return console.error('Error:', error) + }); + } + + let response = await fetch(process.env.NEXT_PUBLIC_REST_ENPOINT+'/device?id='+id, requestOptions) + if (response.status === 401) + router.push("/auth/login") + let json = await response.json() + if (json.device != undefined){ + setDevices({"devices":[ + json.device + ]}) + setPages(1) + setPage(1) + }else{ + setDeviceFound(false) + setDevices([]) + setPages(1) + setPage(1) + } + + } + return ( <> @@ -50,6 +122,7 @@ const Page = () => { Oktopus | TR-369 + { }} > - + + + { + if (e.key === 'Enter') { + console.log("Fetch devices per id: ", e.target.value) + fetchDevicePerId(e.target.value) + } + }} + startAdornment={( + + + + + + )} + sx={{ maxWidth: 500 }} + /> + + {deviceFound ? + : + +

Device Not Found

+
+ } + + {pages ? : null} + {/* //TODO: show loading */} + +
From 00007d611228ef030d4d2bcc71ec0d9887c7c4a2 Mon Sep 17 00:00:00 2001 From: leandrofars Date: Wed, 3 Jan 2024 22:08:31 -0300 Subject: [PATCH 09/15] chore: update license --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 5923ce0..6268dc9 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [2023] [Leandro Antônio Farias Machado] + Copyright 2024 Leandro Antônio Farias Machado Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From b55a0d7bee20bac32339d44c3057eebbe90384f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leandro=20Ant=C3=B4nio=20Farias=20Machado?= <83298718+leandrofars@users.noreply.github.com> Date: Wed, 10 Jan 2024 23:41:54 -0300 Subject: [PATCH 10/15] docs(readme): add overview --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index b6a87d4..1269eaa 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,12 @@


+
    +
  • +

    Overview:

    +
  • +
+
  • Introduction:

    From 12966b6dd2ebb772c1dddebf0a4370885e6a4589 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leandro=20Ant=C3=B4nio=20Farias=20Machado?= <83298718+leandrofars@users.noreply.github.com> Date: Wed, 10 Jan 2024 23:43:58 -0300 Subject: [PATCH 11/15] docs(readme): identation --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 1269eaa..fcde55a 100644 --- a/README.md +++ b/README.md @@ -245,7 +245,6 @@ OBS: Do not use those instructions in production. To implement the project in pr
  • -

    Agent Simulation:

    In case you want a more complete and real-world simulation of devices you might use Oktopus TR-369 Agent Simulator.

    From d50fcc1ee271ccc81524304b6c2ddcfb13b72e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leandro=20Ant=C3=B4nio=20Farias=20Machado?= <83298718+leandrofars@users.noreply.github.com> Date: Wed, 10 Jan 2024 23:52:07 -0300 Subject: [PATCH 12/15] docs(readme):update --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fcde55a..c5724eb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@

    - -

    +


    • @@ -8,6 +7,7 @@
    +image source = https://oktopus.app.br/controller
    • Introduction:

      From 8f226d09a950c049f34d93b10fcc3a3a3ff87a66 Mon Sep 17 00:00:00 2001 From: leandrofars Date: Thu, 11 Jan 2024 18:35:28 -0300 Subject: [PATCH 13/15] fix(api): device page number --- backend/services/controller/internal/api/device.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/services/controller/internal/api/device.go b/backend/services/controller/internal/api/device.go index d533217..e3f1d65 100644 --- a/backend/services/controller/internal/api/device.go +++ b/backend/services/controller/internal/api/device.go @@ -64,7 +64,7 @@ func (a *Api) retrieveDevices(w http.ResponseWriter, r *http.Request) { var page_number int64 if page_n == "" { - page_number = 1 + page_number = 0 } else { page_number, err = strconv.ParseInt(page_n, 10, 64) if err != nil { From 5fd6afc8fa589f7e4032d3bf7daf0535cfd0c873 Mon Sep 17 00:00:00 2001 From: leandrofars Date: Thu, 11 Jan 2024 19:19:35 -0300 Subject: [PATCH 14/15] chore(api): show online devices first --- backend/services/controller/internal/api/device.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/services/controller/internal/api/device.go b/backend/services/controller/internal/api/device.go index e3f1d65..0993583 100644 --- a/backend/services/controller/internal/api/device.go +++ b/backend/services/controller/internal/api/device.go @@ -109,9 +109,12 @@ func (a *Api) retrieveDevices(w http.ResponseWriter, r *http.Request) { //TODO: Create filters //TODO: Create sorting + sort := bson.M{} + sort["status"] = 1 + filter := bson.A{ //bson.M{"$match": filter}, - //bson.M{"$sort": sort}, + bson.M{"$sort": sort}, // shows online devices first bson.M{"$skip": skip}, bson.M{"$limit": page_size}, } From 638abfe355fde0dc8784eecb8d5b13e8667d1cfc Mon Sep 17 00:00:00 2001 From: leandrofars Date: Thu, 11 Jan 2024 19:20:18 -0300 Subject: [PATCH 15/15] feat(frontend): complete pagination + device search per id --- frontend/src/pages/devices.js | 64 ++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/frontend/src/pages/devices.js b/frontend/src/pages/devices.js index 2f9b2bf..6933b39 100644 --- a/frontend/src/pages/devices.js +++ b/frontend/src/pages/devices.js @@ -9,7 +9,8 @@ import { InputAdornment, SvgIcon, Stack, - Pagination + Pagination, + CircularProgress } from '@mui/material'; import MagnifyingGlassIcon from '@heroicons/react/24/solid/MagnifyingGlassIcon'; import { Layout as DashboardLayout } from 'src/layouts/dashboard/layout'; @@ -24,10 +25,11 @@ const Page = () => { const [deviceFound, setDeviceFound] = useState(false) const [pages, setPages] = useState(0); const [page, setPage] = useState(null); + const [Loading, setLoading] = useState(true); useEffect(() => { - + setLoading(true) if (auth.user.token) { console.log("auth.user.token =", auth.user.token) }else{ @@ -54,6 +56,7 @@ const Page = () => { setPages(json.pages + 1) setPage(json.page) setDevices(json.devices) + setLoading(false) return setDeviceFound(true) }) .catch(error => { @@ -61,12 +64,14 @@ const Page = () => { }); }, [auth.user]); - const handleChangePage = (e) => { - console.log("new page: ", e.target.value) - //TODO: Handle page change + const handleChangePage = (event, value) => { + console.log("new page: ", value) + setPage(value) + fetchDevicePerPage(value) } - const fetchDevicePerId = async (id) => { + const fetchDevicePerPage = async (p) => { + setLoading(true) var myHeaders = new Headers(); myHeaders.append("Content-Type", "application/json"); @@ -78,8 +83,39 @@ const Page = () => { redirect: 'follow' } + p = p - 1 + p = p.toString() + + fetch(process.env.NEXT_PUBLIC_REST_ENPOINT+'/device?page_number='+p, requestOptions) + .then(response => { + if (response.status === 401) + router.push("/auth/login") + return response.json() + }) + .then(json => { + setDevices(json.devices) + setLoading(false) + return + }) + .catch(error => { + return console.error('Error:', error) + }); + } + + const fetchDevicePerId = async (id) => { + setLoading(true) + var myHeaders = new Headers(); + myHeaders.append("Content-Type", "application/json"); + myHeaders.append("Authorization", auth.user.token); + + var requestOptions = { + method: 'GET', + headers: myHeaders, + redirect: 'follow' + } + if (id == ""){ - fetch(process.env.NEXT_PUBLIC_REST_ENPOINT+'/device', requestOptions) + return fetch(process.env.NEXT_PUBLIC_REST_ENPOINT+'/device', requestOptions) .then(response => { if (response.status === 401) router.push("/auth/login") @@ -89,6 +125,7 @@ const Page = () => { setPages(json.pages + 1) setPage(json.page) setDevices(json.devices) + setLoading(false) return setDeviceFound(true) }) .catch(error => { @@ -100,10 +137,10 @@ const Page = () => { if (response.status === 401) router.push("/auth/login") let json = await response.json() - if (json.device != undefined){ - setDevices({"devices":[ - json.device - ]}) + if (json.MTP != undefined){ + setDevices([json]) + setDeviceFound(true) + setLoading(false) setPages(1) setPage(1) }else{ @@ -111,6 +148,7 @@ const Page = () => { setDevices([]) setPages(1) setPage(1) + setLoading(false) } } @@ -162,10 +200,12 @@ const Page = () => { /> {deviceFound ? + ( !Loading ? + /> : + ) :