diff --git a/README.md b/README.md
index dc6e229..2c8f3ae 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ Oktopus is a multi-vendor management platform for CPEs and IoTs. Any device t
-
If you'd like to become a sponsor, start a partnership or somehow to contribute to the project, email leandro@oktopus.app.br , every contribution is welcome, and the resources will help the project to move on. Also, if your company uses this project and you'd like your logo to appear up here, contact us.
+
If you'd like to become a sponsor, start a partnership or somehow to contribute to the project, email contact@oktopus.app.br , every contribution is welcome, and the resources will help the project to move on. Also, if your company uses this project and you'd like your logo to appear up here, contact us.
@@ -23,7 +23,7 @@ Oktopus is a multi-vendor management platform for CPEs and IoTs. Any device t
Our solution has an open-source software license, meaning you can modify/study the code and use it for free. You can perform all the configurations, allocate servers, and set it up on your network with the classic "do it yourself" approach, or save time and money: contact us for a quote and get commercial support.
- Contact leandro@oktopus.app.br via email and get a quote.
+ Contact sales@oktopus.app.br via email and get a quote.
diff --git a/backend/services/acs/internal/config/config.go b/backend/services/acs/internal/config/config.go
index e6e6325..1f5fd5e 100644
--- a/backend/services/acs/internal/config/config.go
+++ b/backend/services/acs/internal/config/config.go
@@ -14,10 +14,11 @@ import (
const LOCAL_ENV = ".env.local"
type Nats struct {
- Url string
- Name string
- VerifyCertificates bool
- Ctx context.Context
+ Url string
+ Name string
+ EnableTls bool
+ Cert Tls
+ Ctx context.Context
}
type Acs struct {
@@ -40,6 +41,12 @@ type Config struct {
Nats Nats
}
+type Tls struct {
+ CertFile string
+ KeyFile string
+ CaFile string
+}
+
func NewConfig() *Config {
loadEnvVariables()
@@ -47,7 +54,10 @@ func NewConfig() *Config {
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "adapter"), "name for nats client")
- natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
+ natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
+ clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
+ clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
+ serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
acsPort := flag.String("acs_port", lookupEnvOrString("ACS_PORT", ":9292"), "port for acs server")
acsRoute := flag.String("acs_route", lookupEnvOrString("ACS_ROUTE", "/acs"), "route for acs server")
connReqUser := flag.String("connrq_user", lookupEnvOrString("CONN_RQ_USER", ""), "Connection Request Username")
@@ -77,10 +87,15 @@ func NewConfig() *Config {
return &Config{
Nats: Nats{
- Url: *natsUrl,
- Name: *natsName,
- VerifyCertificates: *natsVerifyCertificates,
- Ctx: ctx,
+ Url: *natsUrl,
+ Name: *natsName,
+ EnableTls: *natsEnableTls,
+ Ctx: ctx,
+ Cert: Tls{
+ CertFile: *clientCrt,
+ KeyFile: *clientKey,
+ CaFile: *serverCA,
+ },
},
Acs: Acs{
Port: *acsPort,
diff --git a/backend/services/acs/internal/nats/nats.go b/backend/services/acs/internal/nats/nats.go
index 0b1e803..d4d8a6e 100644
--- a/backend/services/acs/internal/nats/nats.go
+++ b/backend/services/acs/internal/nats/nats.go
@@ -141,8 +141,10 @@ func defineOptions(c config.Nats) []nats.Option {
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
}))
- if c.VerifyCertificates {
- opts = append(opts, nats.RootCAs())
+ if c.EnableTls {
+ log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
+ opts = append(opts, nats.RootCAs(c.Cert.CaFile))
+ opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
}
return opts
diff --git a/backend/services/bulkdata/http/internal/config/config.go b/backend/services/bulkdata/http/internal/config/config.go
index 8375aca..fff17d3 100644
--- a/backend/services/bulkdata/http/internal/config/config.go
+++ b/backend/services/bulkdata/http/internal/config/config.go
@@ -13,10 +13,11 @@ import (
const LOCAL_ENV = ".env.local"
type Nats struct {
- Url string
- Name string
- VerifyCertificates bool
- Ctx context.Context
+ Url string
+ Name string
+ EnableTls bool
+ Cert Tls
+ Ctx context.Context
}
type RestApi struct {
@@ -29,6 +30,12 @@ type Config struct {
Nats Nats
}
+type Tls struct {
+ CertFile string
+ KeyFile string
+ CaFile string
+}
+
func NewConfig() *Config {
loadEnvVariables()
@@ -36,7 +43,10 @@ func NewConfig() *Config {
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "adapter"), "name for nats client")
- natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
+ natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
+ clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
+ clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
+ serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
flApiPort := flag.String("api_port", lookupEnvOrString("REST_API_PORT", "4000"), "Rest api port")
flHelp := flag.Bool("help", false, "Help")
@@ -62,10 +72,15 @@ func NewConfig() *Config {
Ctx: ctx,
},
Nats: Nats{
- Url: *natsUrl,
- Name: *natsName,
- VerifyCertificates: *natsVerifyCertificates,
- Ctx: ctx,
+ Url: *natsUrl,
+ Name: *natsName,
+ EnableTls: *natsEnableTls,
+ Ctx: ctx,
+ Cert: Tls{
+ CertFile: *clientCrt,
+ KeyFile: *clientKey,
+ CaFile: *serverCA,
+ },
},
}
}
diff --git a/backend/services/bulkdata/http/internal/nats/nats.go b/backend/services/bulkdata/http/internal/nats/nats.go
index 0c77ac4..dd58bf8 100644
--- a/backend/services/bulkdata/http/internal/nats/nats.go
+++ b/backend/services/bulkdata/http/internal/nats/nats.go
@@ -70,8 +70,10 @@ func defineOptions(c config.Nats) []nats.Option {
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
}))
- if c.VerifyCertificates {
- opts = append(opts, nats.RootCAs())
+ if c.EnableTls {
+ log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
+ opts = append(opts, nats.RootCAs(c.Cert.CaFile))
+ opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
}
return opts
diff --git a/backend/services/controller/internal/api/api.go b/backend/services/controller/internal/api/api.go
index 4046436..404e900 100644
--- a/backend/services/controller/internal/api/api.go
+++ b/backend/services/controller/internal/api/api.go
@@ -57,6 +57,13 @@ func (a *Api) StartApi() {
authentication.HandleFunc("/password", a.changePassword).Methods("PUT")
authentication.HandleFunc("/admin/register", a.registerAdminUser).Methods("POST")
authentication.HandleFunc("/admin/exists", a.adminUserExists).Methods("GET")
+ if a.enterpise.Enable {
+ mapRoutes := r.PathPrefix("/api/map").Subrouter()
+ mapRoutes.HandleFunc("", a.devicesLocation).Methods("GET")
+ mapRoutes.Use(func(handler http.Handler) http.Handler {
+ return middleware.Middleware(handler)
+ })
+ }
iot := r.PathPrefix("/api/device").Subrouter()
iot.HandleFunc("/alias", a.setDeviceAlias).Methods("PUT")
iot.HandleFunc("/auth", a.deviceAuth).Methods("GET", "POST", "DELETE")
diff --git a/backend/services/controller/internal/api/enterprise.go b/backend/services/controller/internal/api/enterprise.go
index f7ce633..1e09d44 100644
--- a/backend/services/controller/internal/api/enterprise.go
+++ b/backend/services/controller/internal/api/enterprise.go
@@ -28,6 +28,22 @@ func (a *Api) getEnterpriseResource(
return err
}
+func (a *Api) getMapsResource(
+ action string,
+ w http.ResponseWriter,
+ body []byte,
+) error {
+
+ err := bridge.NatsEnterpriseInteraction("geolocation.v1."+action, body, w, a.nc)
+ return err
+}
+
+func (a *Api) devicesLocation(w http.ResponseWriter, r *http.Request) {
+ if r.Method == http.MethodGet {
+ a.getMapsResource("get", w, []byte{})
+ }
+}
+
func (a *Api) deviceSiteSurvey(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
sn := vars["sn"]
diff --git a/backend/services/controller/internal/api/user.go b/backend/services/controller/internal/api/user.go
index 5484a06..b67d4b5 100644
--- a/backend/services/controller/internal/api/user.go
+++ b/backend/services/controller/internal/api/user.go
@@ -243,7 +243,6 @@ func adminUserExists(users []map[string]interface{}, supportEmail string) bool {
for _, x := range users {
if db.UserLevels(x["level"].(int32)) == db.AdminUser && x["email"].(string) != supportEmail {
- log.Println("Admin exists")
return true
}
}
diff --git a/backend/services/controller/internal/bridge/bridge.go b/backend/services/controller/internal/bridge/bridge.go
index f9697ed..16f1b43 100644
--- a/backend/services/controller/internal/bridge/bridge.go
+++ b/backend/services/controller/internal/bridge/bridge.go
@@ -263,7 +263,7 @@ func NatsEnterpriseInteraction(
if err != nil {
if err == nats.ErrNoResponders {
w.WriteHeader(http.StatusInternalServerError)
- w.Write(utils.Marshall("You have no enterprise license, to get one contact: leandro@oktopus.app.br"))
+ w.Write(utils.Marshall("You have no enterprise license, to get one contact: sales@oktopus.app.br"))
return err
}
w.WriteHeader(http.StatusInternalServerError)
diff --git a/backend/services/controller/internal/config/config.go b/backend/services/controller/internal/config/config.go
index ff97dd6..e90dc5e 100644
--- a/backend/services/controller/internal/config/config.go
+++ b/backend/services/controller/internal/config/config.go
@@ -13,10 +13,11 @@ import (
const LOCAL_ENV = ".env.local"
type Nats struct {
- Url string
- Name string
- VerifyCertificates bool
- Ctx context.Context
+ Url string
+ Name string
+ EnableTls bool
+ Cert Tls
+ Ctx context.Context
}
type Mongo struct {
@@ -42,6 +43,12 @@ type Config struct {
Enterprise Enterprise
}
+type Tls struct {
+ CertFile string
+ KeyFile string
+ CaFile string
+}
+
func NewConfig() *Config {
loadEnvVariables()
@@ -49,7 +56,10 @@ func NewConfig() *Config {
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "controller"), "name for nats client")
- natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
+ natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
+ clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
+ clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
+ serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
flApiPort := flag.String("api_port", lookupEnvOrString("REST_API_PORT", "8000"), "Rest api port")
mongoUri := flag.String("mongo_uri", lookupEnvOrString("MONGO_URI", "mongodb://localhost:27017"), "uri for mongodb server")
enterpise := flag.Bool("enterprise", lookupEnvOrBool("ENTERPRISE", false), "enterprise version enable")
@@ -79,10 +89,15 @@ func NewConfig() *Config {
Ctx: ctx,
},
Nats: Nats{
- Url: *natsUrl,
- Name: *natsName,
- VerifyCertificates: *natsVerifyCertificates,
- Ctx: ctx,
+ Url: *natsUrl,
+ Name: *natsName,
+ EnableTls: *natsEnableTls,
+ Ctx: ctx,
+ Cert: Tls{
+ CertFile: *clientCrt,
+ KeyFile: *clientKey,
+ CaFile: *serverCA,
+ },
},
Mongo: Mongo{
Uri: *mongoUri,
diff --git a/backend/services/controller/internal/nats/nats.go b/backend/services/controller/internal/nats/nats.go
index 3786604..394a1f2 100644
--- a/backend/services/controller/internal/nats/nats.go
+++ b/backend/services/controller/internal/nats/nats.go
@@ -77,8 +77,10 @@ func defineOptions(c config.Nats) []nats.Option {
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
}))
- if c.VerifyCertificates {
- opts = append(opts, nats.RootCAs())
+ if c.EnableTls {
+ log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
+ opts = append(opts, nats.RootCAs(c.Cert.CaFile))
+ opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
}
return opts
diff --git a/backend/services/mtp/adapter/internal/config/config.go b/backend/services/mtp/adapter/internal/config/config.go
index 7562b36..25b0840 100644
--- a/backend/services/mtp/adapter/internal/config/config.go
+++ b/backend/services/mtp/adapter/internal/config/config.go
@@ -13,10 +13,17 @@ import (
const LOCAL_ENV = ".env.local"
type Nats struct {
- Url string
- Name string
- VerifyCertificates bool
- Ctx context.Context
+ Url string
+ Name string
+ EnableTls bool
+ Cert Tls
+ Ctx context.Context
+}
+
+type Tls struct {
+ CertFile string
+ KeyFile string
+ CaFile string
}
type Mongo struct {
@@ -42,7 +49,10 @@ func NewConfig() *Config {
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "adapter"), "name for nats client")
- natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
+ natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
+ clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
+ clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
+ serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
mongoUri := flag.String("mongo_uri", lookupEnvOrString("MONGO_URI", "mongodb://localhost:27017"), "uri for mongodb server")
controllerId := flag.String("controller_id", lookupEnvOrString("CONTROLLER_ID", "oktopusController"), "usp controller endpoint id")
controllerPassword := flag.String("controller_passwd", lookupEnvOrString("CONTROLLER_PASSWORD", ""), "usp controller endpoint password to connect to")
@@ -66,10 +76,15 @@ func NewConfig() *Config {
return &Config{
Nats: Nats{
- Url: *natsUrl,
- Name: *natsName,
- VerifyCertificates: *natsVerifyCertificates,
- Ctx: ctx,
+ Url: *natsUrl,
+ Name: *natsName,
+ EnableTls: *natsEnableTls,
+ Ctx: ctx,
+ Cert: Tls{
+ CertFile: *clientCrt,
+ KeyFile: *clientKey,
+ CaFile: *serverCA,
+ },
},
Mongo: Mongo{
Uri: *mongoUri,
diff --git a/backend/services/mtp/adapter/internal/events/cwmp_handler/info.go b/backend/services/mtp/adapter/internal/events/cwmp_handler/info.go
index d46a895..8ce31f1 100644
--- a/backend/services/mtp/adapter/internal/events/cwmp_handler/info.go
+++ b/backend/services/mtp/adapter/internal/events/cwmp_handler/info.go
@@ -1,6 +1,7 @@
package cwmp_handler
import (
+ "encoding/json"
"encoding/xml"
"log"
@@ -12,6 +13,10 @@ func (h *Handler) HandleDeviceInfo(device string, data []byte, ack func()) {
defer ack()
log.Printf("Device %s info", device)
deviceInfo := parseDeviceInfoMsg(data)
+ if deviceExists, _ := h.db.DeviceExists(deviceInfo.SN); !deviceExists {
+ fmtDeviceInfo, _ := json.Marshal(deviceInfo)
+ h.nc.Publish("device.v1.new", fmtDeviceInfo)
+ }
err := h.db.CreateDevice(deviceInfo)
if err != nil {
log.Printf("Failed to create device: %v", err)
diff --git a/backend/services/mtp/adapter/internal/events/usp_handler/info.go b/backend/services/mtp/adapter/internal/events/usp_handler/info.go
index 07acca7..ce2bd66 100644
--- a/backend/services/mtp/adapter/internal/events/usp_handler/info.go
+++ b/backend/services/mtp/adapter/internal/events/usp_handler/info.go
@@ -1,6 +1,7 @@
package usp_handler
import (
+ "encoding/json"
"log"
"github.com/OktopUSP/oktopus/backend/services/mtp/adapter/internal/db"
@@ -14,6 +15,10 @@ func (h *Handler) HandleDeviceInfo(device, subject string, data []byte, mtp stri
defer ack()
log.Printf("Device %s info, mtp: %s", device, mtp)
deviceInfo := parseDeviceInfoMsg(device, subject, data, getMtp(mtp))
+ if deviceExists, _ := h.db.DeviceExists(deviceInfo.SN); !deviceExists {
+ fmtDeviceInfo, _ := json.Marshal(deviceInfo)
+ h.nc.Publish("device.v1.new", fmtDeviceInfo)
+ }
err := h.db.CreateDevice(deviceInfo)
if err != nil {
log.Printf("Failed to create device: %v", err)
diff --git a/backend/services/mtp/adapter/internal/nats/nats.go b/backend/services/mtp/adapter/internal/nats/nats.go
index 7985275..9396d7f 100644
--- a/backend/services/mtp/adapter/internal/nats/nats.go
+++ b/backend/services/mtp/adapter/internal/nats/nats.go
@@ -150,8 +150,10 @@ func defineOptions(c config.Nats) []nats.Option {
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
}))
- if c.VerifyCertificates {
- opts = append(opts, nats.RootCAs())
+ if c.EnableTls {
+ log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
+ opts = append(opts, nats.RootCAs(c.Cert.CaFile))
+ opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
}
return opts
diff --git a/backend/services/mtp/mqtt-adapter/internal/config/config.go b/backend/services/mtp/mqtt-adapter/internal/config/config.go
index 9bac4a7..0cfd6c6 100644
--- a/backend/services/mtp/mqtt-adapter/internal/config/config.go
+++ b/backend/services/mtp/mqtt-adapter/internal/config/config.go
@@ -13,10 +13,17 @@ import (
const LOCAL_ENV = ".env.local"
type Nats struct {
- Url string
- Name string
- VerifyCertificates bool
- Ctx context.Context
+ Url string
+ Name string
+ EnableTls bool
+ Cert Tls
+ Ctx context.Context
+}
+
+type Tls struct {
+ CertFile string
+ KeyFile string
+ CaFile string
}
type Mqtt struct {
@@ -42,7 +49,10 @@ func NewConfig() *Config {
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "mqtt-adapter"), "name for nats client")
- natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
+ natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
+ clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
+ clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
+ serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
mqttUrl := flag.String("mqtt_url", lookupEnvOrString("MQTT_URL", "tcp://localhost:1883"), "url for mqtt server")
mqttsUrl := flag.String("mqtts_url", lookupEnvOrString("MQTTS_URL", ""), "url for mqtts server")
mqttsSkipVerify := flag.Bool("mqtts_skip_verify", lookupEnvOrBool("MQTTS_SKIP_VERIFY", false), "skip verification of server certificate for mqtts")
@@ -69,10 +79,15 @@ func NewConfig() *Config {
return &Config{
Nats: Nats{
- Url: *natsUrl,
- Name: *natsName,
- VerifyCertificates: *natsVerifyCertificates,
- Ctx: ctx,
+ Url: *natsUrl,
+ Name: *natsName,
+ EnableTls: *natsEnableTls,
+ Ctx: ctx,
+ Cert: Tls{
+ CertFile: *clientCrt,
+ KeyFile: *clientKey,
+ CaFile: *serverCA,
+ },
},
Mqtt: Mqtt{
Url: *mqttUrl,
diff --git a/backend/services/mtp/mqtt-adapter/internal/nats/nats.go b/backend/services/mtp/mqtt-adapter/internal/nats/nats.go
index 7698d76..4e96605 100644
--- a/backend/services/mtp/mqtt-adapter/internal/nats/nats.go
+++ b/backend/services/mtp/mqtt-adapter/internal/nats/nats.go
@@ -92,8 +92,10 @@ func defineOptions(c config.Nats) []nats.Option {
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
}))
- if c.VerifyCertificates {
- opts = append(opts, nats.RootCAs())
+ if c.EnableTls {
+ log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
+ opts = append(opts, nats.RootCAs(c.Cert.CaFile))
+ opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
}
return opts
diff --git a/backend/services/mtp/mqtt/internal/config/config.go b/backend/services/mtp/mqtt/internal/config/config.go
index 805d4ae..e701117 100644
--- a/backend/services/mtp/mqtt/internal/config/config.go
+++ b/backend/services/mtp/mqtt/internal/config/config.go
@@ -32,10 +32,17 @@ type Config struct {
}
type Nats struct {
- Url string
- Name string
- VerifyCertificates bool
- Ctx context.Context
+ Url string
+ Name string
+ EnableTls bool
+ Cert Tls
+ Ctx context.Context
+}
+
+type Tls struct {
+ CertFile string
+ KeyFile string
+ CaFile string
}
func NewConfig() Config {
@@ -66,7 +73,10 @@ func NewConfig() Config {
logLevel := flag.Int("log_level", lookupEnvOrInt("LOG_LEVEL", 1), "0=DEBUG, 1=INFO, 2=WARNING, 3=ERROR")
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "adapter"), "name for nats client")
- natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
+ natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
+ clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
+ clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
+ serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
flag.Parse()
flHelp := flag.Bool("help", false, "Help")
@@ -99,10 +109,15 @@ func NewConfig() Config {
HttpPort: *httpPort,
LogLevel: *logLevel,
Nats: Nats{
- Url: *natsUrl,
- Name: *natsName,
- VerifyCertificates: *natsVerifyCertificates,
- Ctx: ctx,
+ Url: *natsUrl,
+ Name: *natsName,
+ EnableTls: *natsEnableTls,
+ Ctx: ctx,
+ Cert: Tls{
+ CertFile: *clientCrt,
+ KeyFile: *clientKey,
+ CaFile: *serverCA,
+ },
},
}
diff --git a/backend/services/mtp/mqtt/internal/nats/nats.go b/backend/services/mtp/mqtt/internal/nats/nats.go
index 1eb51a4..d1548a3 100644
--- a/backend/services/mtp/mqtt/internal/nats/nats.go
+++ b/backend/services/mtp/mqtt/internal/nats/nats.go
@@ -74,8 +74,10 @@ func defineOptions(c config.Nats) []nats.Option {
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
}))
- if c.VerifyCertificates {
- opts = append(opts, nats.RootCAs())
+ if c.EnableTls {
+ log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
+ opts = append(opts, nats.RootCAs(c.Cert.CaFile))
+ opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
}
return opts
diff --git a/backend/services/mtp/stomp-adapter/internal/config/config.go b/backend/services/mtp/stomp-adapter/internal/config/config.go
index f79de27..2b54a40 100644
--- a/backend/services/mtp/stomp-adapter/internal/config/config.go
+++ b/backend/services/mtp/stomp-adapter/internal/config/config.go
@@ -13,10 +13,17 @@ import (
const LOCAL_ENV = ".env.local"
type Nats struct {
- Url string
- Name string
- VerifyCertificates bool
- Ctx context.Context
+ Url string
+ Name string
+ EnableTls bool
+ Cert Tls
+ Ctx context.Context
+}
+
+type Tls struct {
+ CertFile string
+ KeyFile string
+ CaFile string
}
type Stomp struct {
@@ -37,7 +44,10 @@ func NewConfig() *Config {
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "mqtt-adapter"), "name for nats client")
- natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
+ natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
+ clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
+ clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
+ serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
stompAddr := flag.String("stomp_server", lookupEnvOrString("STOMP_SERVER", "localhost:61613"), "STOMP server endpoint")
stompUser := flag.String("stomp_user", lookupEnvOrString("STOMP_USER", ""), "stomp server user")
stompPassword := flag.String("stomp_passsword", lookupEnvOrString("STOMP_PASSWD", ""), "stomp server password")
@@ -61,10 +71,15 @@ func NewConfig() *Config {
return &Config{
Nats: Nats{
- Url: *natsUrl,
- Name: *natsName,
- VerifyCertificates: *natsVerifyCertificates,
- Ctx: ctx,
+ Url: *natsUrl,
+ Name: *natsName,
+ EnableTls: *natsEnableTls,
+ Ctx: ctx,
+ Cert: Tls{
+ CertFile: *clientCrt,
+ KeyFile: *clientKey,
+ CaFile: *serverCA,
+ },
},
Stomp: Stomp{
Url: *stompAddr,
diff --git a/backend/services/mtp/stomp-adapter/internal/nats/nats.go b/backend/services/mtp/stomp-adapter/internal/nats/nats.go
index ad739fd..774ba86 100644
--- a/backend/services/mtp/stomp-adapter/internal/nats/nats.go
+++ b/backend/services/mtp/stomp-adapter/internal/nats/nats.go
@@ -81,9 +81,10 @@ func defineOptions(c config.Nats) []nats.Option {
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
}))
- if c.VerifyCertificates {
- opts = append(opts, nats.RootCAs())
+ if c.EnableTls {
+ log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
+ opts = append(opts, nats.RootCAs(c.Cert.CaFile))
+ opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
}
-
return opts
}
diff --git a/backend/services/mtp/ws-adapter/internal/config/config.go b/backend/services/mtp/ws-adapter/internal/config/config.go
index c78e4dd..cf4231b 100644
--- a/backend/services/mtp/ws-adapter/internal/config/config.go
+++ b/backend/services/mtp/ws-adapter/internal/config/config.go
@@ -13,10 +13,17 @@ import (
const LOCAL_ENV = ".env.local"
type Nats struct {
- Url string
- Name string
- VerifyCertificates bool
- Ctx context.Context
+ Url string
+ Name string
+ EnableTls bool
+ Cert Tls
+ Ctx context.Context
+}
+
+type Tls struct {
+ CertFile string
+ KeyFile string
+ CaFile string
}
type Ws struct {
@@ -42,7 +49,10 @@ func NewConfig() *Config {
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "ws-adapter"), "name for nats client")
- natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
+ natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
+ clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
+ clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
+ serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
wsAuthEnable := flag.Bool("ws_auth_enable", lookupEnvOrBool("WS_AUTH_ENABLE", false), "enable authentication for websocket server")
wsAddr := flag.String("ws_addr", lookupEnvOrString("WS_ADDR", "localhost"), "websocket server address (domain or ip)")
wsPort := flag.String("ws_port", lookupEnvOrString("WS_PORT", ":8080"), "websocket server port")
@@ -68,10 +78,15 @@ func NewConfig() *Config {
return &Config{
Nats: Nats{
- Url: *natsUrl,
- Name: *natsName,
- VerifyCertificates: *natsVerifyCertificates,
- Ctx: ctx,
+ Url: *natsUrl,
+ Name: *natsName,
+ EnableTls: *natsEnableTls,
+ Ctx: ctx,
+ Cert: Tls{
+ CertFile: *clientCrt,
+ KeyFile: *clientKey,
+ CaFile: *serverCA,
+ },
},
Ws: Ws{
AuthEnable: *wsAuthEnable,
diff --git a/backend/services/mtp/ws-adapter/internal/nats/nats.go b/backend/services/mtp/ws-adapter/internal/nats/nats.go
index c5a1de4..729129c 100644
--- a/backend/services/mtp/ws-adapter/internal/nats/nats.go
+++ b/backend/services/mtp/ws-adapter/internal/nats/nats.go
@@ -91,8 +91,10 @@ func defineOptions(c config.Nats) []nats.Option {
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
}))
- if c.VerifyCertificates {
- opts = append(opts, nats.RootCAs())
+ if c.EnableTls {
+ log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
+ opts = append(opts, nats.RootCAs(c.Cert.CaFile))
+ opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
}
return opts
diff --git a/backend/services/mtp/ws/internal/config/config.go b/backend/services/mtp/ws/internal/config/config.go
index f79f176..3080571 100644
--- a/backend/services/mtp/ws/internal/config/config.go
+++ b/backend/services/mtp/ws/internal/config/config.go
@@ -24,10 +24,17 @@ type Config struct {
}
type Nats struct {
- Url string
- Name string
- VerifyCertificates bool
- Ctx context.Context
+ Url string
+ Name string
+ EnableTls bool
+ Cert Tls
+ Ctx context.Context
+}
+
+type Tls struct {
+ CertFile string
+ KeyFile string
+ CaFile string
}
func NewConfig() Config {
@@ -47,7 +54,10 @@ func NewConfig() Config {
/* ------------------------------ define flags ------------------------------ */
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "ws-adapter"), "name for nats client")
- natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
+ natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
+ clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
+ clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
+ serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
flPort := flag.String("port", lookupEnvOrString("SERVER_PORT", ":8080"), "Server port")
flAuth := flag.Bool("auth", lookupEnvOrBool("SERVER_AUTH_ENABLE", false), "Server auth enable/disable")
flControllerEid := flag.String("controller-eid", lookupEnvOrString("CONTROLLER_EID", "oktopusController"), "Controller eid")
@@ -81,10 +91,15 @@ func NewConfig() Config {
FullChain: *flFullchain,
PrivateKey: *flPrivKey,
Nats: Nats{
- Url: *natsUrl,
- Name: *natsName,
- VerifyCertificates: *natsVerifyCertificates,
- Ctx: ctx,
+ Url: *natsUrl,
+ Name: *natsName,
+ EnableTls: *natsEnableTls,
+ Ctx: ctx,
+ Cert: Tls{
+ CertFile: *clientCrt,
+ KeyFile: *clientKey,
+ CaFile: *serverCA,
+ },
},
}
}
diff --git a/backend/services/mtp/ws/internal/nats/nats.go b/backend/services/mtp/ws/internal/nats/nats.go
index a5a557d..2afc947 100644
--- a/backend/services/mtp/ws/internal/nats/nats.go
+++ b/backend/services/mtp/ws/internal/nats/nats.go
@@ -66,8 +66,10 @@ func defineOptions(c config.Nats) []nats.Option {
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
}))
- if c.VerifyCertificates {
- opts = append(opts, nats.RootCAs())
+ if c.EnableTls {
+ log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
+ opts = append(opts, nats.RootCAs(c.Cert.CaFile))
+ opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
}
return opts
diff --git a/backend/services/utils/file-server/.env b/backend/services/utils/file-server/.env
index 8eb288c..10e120d 100644
--- a/backend/services/utils/file-server/.env
+++ b/backend/services/utils/file-server/.env
@@ -1,2 +1,2 @@
-DIRECTORY_PATH="./firmwares"
+DIRECTORY_PATH="."
SERVER_PORT=":8004"
\ No newline at end of file
diff --git a/backend/services/utils/file-server/.gitignore b/backend/services/utils/file-server/.gitignore
index 0835f35..943b9ca 100644
--- a/backend/services/utils/file-server/.gitignore
+++ b/backend/services/utils/file-server/.gitignore
@@ -1,2 +1,3 @@
firmwares/
-.env.local
\ No newline at end of file
+.env.local
+images/
\ No newline at end of file
diff --git a/backend/services/utils/file-server/build/Dockerfile b/backend/services/utils/file-server/build/Dockerfile
new file mode 100644
index 0000000..25700be
--- /dev/null
+++ b/backend/services/utils/file-server/build/Dockerfile
@@ -0,0 +1,8 @@
+FROM golang:1.22.2@sha256:450e3822c7a135e1463cd83e51c8e2eb03b86a02113c89424e6f0f8344bb4168 as builder
+WORKDIR /app
+COPY ../ .
+RUN CGO_ENABLED=0 GOOS=linux go build -o file-server main.go
+
+FROM alpine:3.14@sha256:0f2d5c38dd7a4f4f733e688e3a6733cb5ab1ac6e3cb4603a5dd564e5bfb80eed
+COPY --from=builder /app/file-server /
+ENTRYPOINT ["/file-server"]
\ No newline at end of file
diff --git a/backend/services/utils/file-server/build/Makefile b/backend/services/utils/file-server/build/Makefile
new file mode 100644
index 0000000..a35adde
--- /dev/null
+++ b/backend/services/utils/file-server/build/Makefile
@@ -0,0 +1,61 @@
+.PHONY: help build push start stop release remove delete run logs bash
+
+DOCKER_USER ?= oktopusp
+DOCKER_APP ?= file-server
+DOCKER_TAG ?= $(shell git log --format="%h" -n 1)
+CONTAINER_SHELL ?= /bin/sh
+
+.DEFAULT_GOAL := help
+
+help:
+ @echo "Makefile arguments:"
+ @echo ""
+ @echo "DOCKER_USER - docker user to build image"
+ @echo "DOCKER_APP - docker image name"
+ @echo "DOCKER_TAG - docker image tag"
+ @echo "CONTAINER_SHELL - container shell e.g:'/bin/bash'"
+ @echo ""
+ @echo "Makefile commands:"
+ @echo ""
+ @echo "build - docker image build"
+ @echo "push - push docker iamge to registry"
+ @echo "run - create and start docker container with the image"
+ @echo "start - start existent docker container with the image"
+ @echo "stop - stop docker container running the image"
+ @echo "remove - remove docker container running the image"
+ @echo "delete - delete docker image"
+ @echo "logs - show logs of docker container"
+ @echo "bash - access container shell"
+ @echo "release - tag image as latest and push to registry"
+
+build:
+ @docker build -t ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG} -f Dockerfile ../
+
+run:
+ @docker run -d --name ${DOCKER_USER}-${DOCKER_APP} ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG}
+
+stop:
+ @docker stop ${DOCKER_USER}-${DOCKER_APP}
+
+remove: stop
+ @docker rm ${DOCKER_USER}-${DOCKER_APP}
+
+delete:
+ @docker rmi ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG}
+
+start:
+ @docker start ${DOCKER_USER}-${DOCKER_APP}
+
+push:
+ @docker push ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG}
+
+logs:
+ @docker logs -f ${DOCKER_USER}-${DOCKER_APP}
+
+bash:
+ @docker exec -it ${DOCKER_USER}-${DOCKER_APP} ${CONTAINER_SHELL}
+
+release: build
+ @docker push ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG}
+ @docker tag ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG} ${DOCKER_USER}/${DOCKER_APP}:latest
+ @docker push ${DOCKER_USER}/${DOCKER_APP}:latest
\ No newline at end of file
diff --git a/backend/services/utils/file-server/main.go b/backend/services/utils/file-server/main.go
index 82e7705..e3dd389 100644
--- a/backend/services/utils/file-server/main.go
+++ b/backend/services/utils/file-server/main.go
@@ -42,7 +42,7 @@ func main() {
http.Handle("/", fileServer)
port := os.Getenv("SERVER_PORT")
- fmt.Printf("Server started at http://localhost:%s\n", port)
+ fmt.Printf("Server started at http://localhost%s\n", port)
err = http.ListenAndServe(port, nil)
if err != nil {
fmt.Printf("Error starting server: %s\n", err)
diff --git a/build/Makefile b/build/Makefile
index c87bf00..3e41492 100644
--- a/build/Makefile
+++ b/build/Makefile
@@ -26,6 +26,7 @@ build-backend:
@make build -C ../backend/services/controller/build/ DOCKER_USER=${DOCKER_USER}
@make build -C ../backend/services/acs/build/ DOCKER_USER=${DOCKER_USER}
@make build -C ../backend/services/utils/socketio/build/ DOCKER_USER=${DOCKER_USER}
+ @make build -C ../backend/services/utils/file-server/build/ DOCKER_USER=${DOCKER_USER}
@make build -C ../backend/services/mtp/adapter/build/ DOCKER_USER=${DOCKER_USER}
@make build -C ../backend/services/mtp/ws-adapter/build/ DOCKER_USER=${DOCKER_USER}
@make build -C ../backend/services/mtp/ws/build/ DOCKER_USER=${DOCKER_USER}
@@ -43,6 +44,7 @@ release-backend:
@make release -C ../backend/services/controller/build/ DOCKER_USER=${DOCKER_USER}
@make release -C ../backend/services/acs/build/ DOCKER_USER=${DOCKER_USER}
@make release -C ../backend/services/utils/socketio/build/ DOCKER_USER=${DOCKER_USER}
+ @make release -C ../backend/services/utils/file-server/build/ DOCKER_USER=${DOCKER_USER}
@make release -C ../backend/services/mtp/adapter/build/ DOCKER_USER=${DOCKER_USER}
@make release -C ../backend/services/mtp/ws-adapter/build/ DOCKER_USER=${DOCKER_USER}
@make release -C ../backend/services/mtp/ws/build/ DOCKER_USER=${DOCKER_USER}
diff --git a/deploy/compose/.env.acs b/deploy/compose/.env.acs
index 9af7128..472de27 100644
--- a/deploy/compose/.env.acs
+++ b/deploy/compose/.env.acs
@@ -1 +1,5 @@
-NATS_URL=nats://msg_broker:4222
\ No newline at end of file
+NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
+NATS_ENABLE_TLS="true"
+CLIENT_CRT=/tmp/nats/config/cert.pem
+CLIENT_KEY=/tmp/nats/config/key.pem
+SERVER_CA=/tmp/nats/config/rootCA.pem
diff --git a/deploy/compose/.env.adapter b/deploy/compose/.env.adapter
index 70fd6fe..d3dcd0d 100644
--- a/deploy/compose/.env.adapter
+++ b/deploy/compose/.env.adapter
@@ -1,2 +1,6 @@
-NATS_URL=nats://msg_broker:4222
-MONGO_URI=mongodb://mongo_usp:27017
\ No newline at end of file
+MONGO_URI=mongodb://mongo_usp:27017
+NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
+NATS_ENABLE_TLS="true"
+CLIENT_CRT=/tmp/nats/config/cert.pem
+CLIENT_KEY=/tmp/nats/config/key.pem
+SERVER_CA=/tmp/nats/config/rootCA.pem
diff --git a/deploy/compose/.env.controller b/deploy/compose/.env.controller
index 70fd6fe..d3dcd0d 100644
--- a/deploy/compose/.env.controller
+++ b/deploy/compose/.env.controller
@@ -1,2 +1,6 @@
-NATS_URL=nats://msg_broker:4222
-MONGO_URI=mongodb://mongo_usp:27017
\ No newline at end of file
+MONGO_URI=mongodb://mongo_usp:27017
+NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
+NATS_ENABLE_TLS="true"
+CLIENT_CRT=/tmp/nats/config/cert.pem
+CLIENT_KEY=/tmp/nats/config/key.pem
+SERVER_CA=/tmp/nats/config/rootCA.pem
diff --git a/deploy/compose/.env.file-server b/deploy/compose/.env.file-server
new file mode 100644
index 0000000..10e120d
--- /dev/null
+++ b/deploy/compose/.env.file-server
@@ -0,0 +1,2 @@
+DIRECTORY_PATH="."
+SERVER_PORT=":8004"
\ No newline at end of file
diff --git a/deploy/compose/.env.mqtt b/deploy/compose/.env.mqtt
index e0c2d35..4f467a1 100644
--- a/deploy/compose/.env.mqtt
+++ b/deploy/compose/.env.mqtt
@@ -1,3 +1,7 @@
REDIS_ENABLE=false
REDIS_ADDR=redis_usp:6379
-NATS_URL=nats://msg_broker:4222
\ No newline at end of file
+NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
+NATS_ENABLE_TLS="true"
+CLIENT_CRT=/tmp/nats/config/cert.pem
+CLIENT_KEY=/tmp/nats/config/key.pem
+SERVER_CA=/tmp/nats/config/rootCA.pem
diff --git a/deploy/compose/.env.mqtt-adapter b/deploy/compose/.env.mqtt-adapter
index e567b54..569032b 100644
--- a/deploy/compose/.env.mqtt-adapter
+++ b/deploy/compose/.env.mqtt-adapter
@@ -1,2 +1,6 @@
-NATS_URL=nats://msg_broker:4222
-MQTT_URL=tcp://mqtt:1883
\ No newline at end of file
+MQTT_URL=tcp://mqtt:1883
+NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
+NATS_ENABLE_TLS="true"
+CLIENT_CRT=/tmp/nats/config/cert.pem
+CLIENT_KEY=/tmp/nats/config/key.pem
+SERVER_CA=/tmp/nats/config/rootCA.pem
diff --git a/deploy/compose/.env.nats b/deploy/compose/.env.nats
new file mode 100644
index 0000000..95fa9bc
--- /dev/null
+++ b/deploy/compose/.env.nats
@@ -0,0 +1,3 @@
+NATS_NAME=oktopus
+NATS_USER=oktopususer
+NATS_PW=oktopuspw
diff --git a/deploy/compose/.env.socketio b/deploy/compose/.env.socketio
index 9af7128..472de27 100644
--- a/deploy/compose/.env.socketio
+++ b/deploy/compose/.env.socketio
@@ -1 +1,5 @@
-NATS_URL=nats://msg_broker:4222
\ No newline at end of file
+NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
+NATS_ENABLE_TLS="true"
+CLIENT_CRT=/tmp/nats/config/cert.pem
+CLIENT_KEY=/tmp/nats/config/key.pem
+SERVER_CA=/tmp/nats/config/rootCA.pem
diff --git a/deploy/compose/.env.stomp-adapter b/deploy/compose/.env.stomp-adapter
index cdd100a..8754e23 100644
--- a/deploy/compose/.env.stomp-adapter
+++ b/deploy/compose/.env.stomp-adapter
@@ -1,2 +1,6 @@
-NATS_URL=nats://msg_broker:4222
STOMP_SERVER=stomp:61613
+NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
+NATS_ENABLE_TLS="true"
+CLIENT_CRT=/tmp/nats/config/cert.pem
+CLIENT_KEY=/tmp/nats/config/key.pem
+SERVER_CA=/tmp/nats/config/rootCA.pem
diff --git a/deploy/compose/.env.ws b/deploy/compose/.env.ws
index 9af7128..472de27 100644
--- a/deploy/compose/.env.ws
+++ b/deploy/compose/.env.ws
@@ -1 +1,5 @@
-NATS_URL=nats://msg_broker:4222
\ No newline at end of file
+NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
+NATS_ENABLE_TLS="true"
+CLIENT_CRT=/tmp/nats/config/cert.pem
+CLIENT_KEY=/tmp/nats/config/key.pem
+SERVER_CA=/tmp/nats/config/rootCA.pem
diff --git a/deploy/compose/.env.ws-adapter b/deploy/compose/.env.ws-adapter
index 13fcdca..8454cce 100644
--- a/deploy/compose/.env.ws-adapter
+++ b/deploy/compose/.env.ws-adapter
@@ -1,2 +1,6 @@
-NATS_URL=nats://msg_broker:4222
-WS_ADDR=ws
\ No newline at end of file
+WS_ADDR=ws
+NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
+NATS_ENABLE_TLS="true"
+CLIENT_CRT=/tmp/nats/config/cert.pem
+CLIENT_KEY=/tmp/nats/config/key.pem
+SERVER_CA=/tmp/nats/config/rootCA.pem
diff --git a/deploy/compose/.gitignore b/deploy/compose/.gitignore
index af5be97..93a4138 100644
--- a/deploy/compose/.gitignore
+++ b/deploy/compose/.gitignore
@@ -3,4 +3,8 @@ portainer_data/*
mongo_data/*
!mongo_data/.gitkeep
nats_data/*
-!nats_data/.gitkeep
\ No newline at end of file
+!nats_data/.gitkeep
+firmwares/*
+!firmwares/.gitkeep
+images/*
+!images/logo.png
\ No newline at end of file
diff --git a/deploy/compose/docker-compose.yaml b/deploy/compose/docker-compose.yaml
index 5fdbddd..410fe46 100644
--- a/deploy/compose/docker-compose.yaml
+++ b/deploy/compose/docker-compose.yaml
@@ -1,38 +1,42 @@
services:
-
-#/* ----------------------------- Message Broker ----------------------------- */
+ #/* ----------------------------- Message Broker ----------------------------- */
msg_broker:
- image: 'nats:latest'
+ image: "nats:latest"
container_name: nats
ports:
- 4222:4222
- 8222:8222
- command: -n oktopus -m 8222 -js
+ command: -c /tmp/nats/config/nats.cfg
+ env_file:
+ - .env.nats
volumes:
- ./nats_data:/tmp/nats/jetstream
+ - ./nats_config:/tmp/nats/config
networks:
usp_network:
ipv4_address: 172.16.235.2
profiles: [nats]
-#/* -------------------------------------------------------------------------- */
+ #/* -------------------------------------------------------------------------- */
-#/* ------------------------ API REST / USP Controller ----------------------- */
+ #/* ------------------------ API REST / USP Controller ----------------------- */
controller:
- image: 'oktopusp/controller'
+ image: "oktopusp/controller"
container_name: controller
ports:
- - 8000:8000
+ - 8000:8000
depends_on:
- - mongo_usp
+ - mongo_usp
env_file:
- .env.controller
+ volumes:
+ - ./nats_config:/tmp/nats/config
networks:
usp_network:
ipv4_address: 172.16.235.3
profiles: [controller]
-#/* -------------------------------------------------------------------------- */
+ #/* -------------------------------------------------------------------------- */
-#/* ---------------------------- Databases / Cache --------------------------- */
+ #/* ---------------------------- Databases / Cache --------------------------- */
mongo_usp:
image: mongo
container_name: mongo_usp
@@ -43,115 +47,128 @@ services:
ipv4_address: 172.16.235.4
volumes:
- ./mongo_data:/data/db
- profiles: [controller,adapter]
+ profiles: [controller, adapter]
-#/* -------------------------------------------------------------------------- */
+ #/* -------------------------------------------------------------------------- */
-#/* ----------------------- Message Transfer Protocols ----------------------- */
+ #/* ----------------------- Message Transfer Protocols ----------------------- */
mqtt:
- image: 'oktopusp/mqtt'
+ image: "oktopusp/mqtt"
container_name: mqtt
ports:
- - 1883:1883
- - 8883:8883
+ - 1883:1883
+ - 8883:8883
env_file:
- .env.mqtt
+ volumes:
+ - ./nats_config:/tmp/nats/config
networks:
usp_network:
ipv4_address: 172.16.235.6
profiles: [mqtt]
ws:
- image: 'oktopusp/ws'
+ image: "oktopusp/ws"
container_name: websockets
ports:
- - 8080:8080
+ - 8080:8080
env_file:
- .env.ws
+ volumes:
+ - ./nats_config:/tmp/nats/config
networks:
usp_network:
ipv4_address: 172.16.235.7
profiles: [ws]
-
+
stomp:
- image: 'oktopusp/stomp'
+ image: "oktopusp/stomp"
container_name: stomp
ports:
- - 61613:61613
+ - 61613:61613
networks:
usp_network:
ipv4_address: 172.16.235.8
profiles: [stomp]
-#/* -------------------------------------------------------------------------- */
+ #/* -------------------------------------------------------------------------- */
-#/* --------------- Message transfer Protocols Adapters to NATS -------------- */
+ #/* --------------- Message transfer Protocols Adapters to NATS -------------- */
mqtt-adapter:
- image: 'oktopusp/mqtt-adapter'
+ image: "oktopusp/mqtt-adapter"
container_name: mqtt-adapter
depends_on:
- mqtt
env_file:
- .env.mqtt-adapter
+ volumes:
+ - ./nats_config:/tmp/nats/config
networks:
usp_network:
ipv4_address: 172.16.235.9
profiles: [mqtt]
-
ws-adapter:
- image: 'oktopusp/ws-adapter'
+ image: "oktopusp/ws-adapter"
container_name: ws-adapter
depends_on:
- ws
env_file:
- .env.ws-adapter
+ volumes:
+ - ./nats_config:/tmp/nats/config
networks:
usp_network:
ipv4_address: 172.16.235.10
profiles: [ws]
-
+
stomp-adapter:
- image: 'oktopusp/stomp-adapter'
+ image: "oktopusp/stomp-adapter"
container_name: stomp-adapter
depends_on:
- stomp
env_file:
- .env.stomp-adapter
+ volumes:
+ - ./nats_config:/tmp/nats/config
networks:
usp_network:
ipv4_address: 172.16.235.11
profiles: [stomp]
adapter:
- image: 'oktopusp/adapter'
+ image: "oktopusp/adapter"
container_name: adapter
depends_on:
- mongo_usp
env_file:
- .env.adapter
+ volumes:
+ - ./nats_config:/tmp/nats/config
networks:
usp_network:
ipv4_address: 172.16.235.12
profiles: [adapter]
-#/* -------------------------------------------------------------------------- */
+ #/* -------------------------------------------------------------------------- */
-#/* ------------- SocketIO Real Time Communication With Frontend ------------- */
+ #/* ------------- SocketIO Real Time Communication With Frontend ------------- */
socketio:
- image: 'oktopusp/socketio'
+ image: "oktopusp/socketio"
container_name: socketio
ports:
- - 5000:5000
+ - 5000:5000
env_file:
- .env.socketio
+ volumes:
+ - ./nats_config:/tmp/nats/config
networks:
usp_network:
ipv4_address: 172.16.235.13
profiles: [frontend]
-#/* -------------------------------------------------------------------------- */
+ #/* -------------------------------------------------------------------------- */
-#/* -------------------------------- Frontend -------------------------------- */
+ #/* -------------------------------- Frontend -------------------------------- */
frontend:
- image: 'oktopusp/frontend-ce'
+ image: "oktopusp/frontend-ce"
container_name: frontend
ports:
- 3000:3000
@@ -159,7 +176,7 @@ services:
usp_network:
ipv4_address: 172.16.235.14
profiles: [frontend]
-#/* -------------------------------------------------------------------------- */
+ #/* -------------------------------------------------------------------------- */
portainer:
image: portainer/portainer-ce:latest
@@ -173,38 +190,52 @@ services:
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./portainer_data:/data
-
+
acs:
- image: oktopusp/acs
+ image: "oktopusp/acs"
container_name: acs
ports:
- 9292:9292
env_file:
- .env.acs
+ volumes:
+ - ./nats_config:/tmp/nats/config
networks:
usp_network:
ipv4_address: 172.16.235.16
profiles: [cwmp]
-
+
nginx:
image: nginx:latest
container_name: nginx
ports:
- 80:80
- depends_on:
- - frontend
- - controller
- - socketio
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
+ extra_hosts:
+ - "host.docker.internal:host-gateway"
networks:
usp_network:
ipv4_address: 172.16.235.17
+ file-server:
+ image: oktopusp/file-server
+ container_name: file-server
+ ports:
+ - 8004:8004
+ volumes:
+ - ./firmwares:/app/firmwares
+ - ./images:/app/images
+ env_file:
+ - .env.file-server
+ networks:
+ usp_network:
+ ipv4_address: 172.16.235.18
+
networks:
- usp_network:
+ usp_network:
driver: bridge
- ipam:
+ ipam:
driver: default
config:
- subnet: 172.16.235.0/24
diff --git a/deploy/compose/firmwares/.gitkeep b/deploy/compose/firmwares/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/frontend/public/assets/oktopus.png b/deploy/compose/images/logo.png
similarity index 100%
rename from frontend/public/assets/oktopus.png
rename to deploy/compose/images/logo.png
diff --git a/deploy/compose/nats_config/cert.pem b/deploy/compose/nats_config/cert.pem
new file mode 100644
index 0000000..0cf14cb
--- /dev/null
+++ b/deploy/compose/nats_config/cert.pem
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEeTCCAuGgAwIBAgIRAJenDys60PD3Cjh9VXeAzsowDQYJKoZIhvcNAQELBQAw
+gY0xHjAcBgNVBAoTFW1rY2VydCBkZXZlbG9wbWVudCBDQTExMC8GA1UECwwoY2hp
+ZXNhQEFkcmlhbm9NYWMubG9jYWwgKEFkcmlhbm8gQ2hpZXNhKTE4MDYGA1UEAwwv
+bWtjZXJ0IGNoaWVzYUBBZHJpYW5vTWFjLmxvY2FsIChBZHJpYW5vIENoaWVzYSkw
+HhcNMjQwNzA2MTQzODQ2WhcNMjYxMDA2MTQzODQ2WjBcMScwJQYDVQQKEx5ta2Nl
+cnQgZGV2ZWxvcG1lbnQgY2VydGlmaWNhdGUxMTAvBgNVBAsMKGNoaWVzYUBBZHJp
+YW5vTWFjLmxvY2FsIChBZHJpYW5vIENoaWVzYSkwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQCdQCgwn7M5jtkNzYv/yUelUV84ehsYjPTQspCXCjDdUltO
+E6jafRM/2SopUWwzPTorIZkerIpqq/avi77e6wSdCKJZBA5DsrMSOmFjjMqG4H2b
+euzr5b+ZKzKnw4nF/CuB2cmWkz/qAiluqVdRl+Gef/Ouyuer/NuhJhK6Mgy1VuAd
+ynwizGsAgQ/oAGDuHWmcMhGw/2NVTnXqHei5ntr+F4r08YOgXnRsGId+16nJU5xd
+Xs80sw2dFl+1zQiFJxWjVQk65CyZfLDcwC7e3PAMsT+8obzuBKCn6fW3JiIZ68tc
+o8GZClHSkeS7IMp+/wtjMXf1iipE0bRWzzdl1xQnAgMBAAGjgYMwgYAwDgYDVR0P
+AQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMB8GA1UdIwQYMBaAFH2KEsMw
+S7/Qu1eE1DxRhZTI0Z7RMDgGA1UdEQQxMC+CCm1zZ19icm9rZXKCCWxvY2FsaG9z
+dIcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQsFAAOCAYEAVr06
+Kg/FaWxUbD6Q+e5OLzckeeFZOKcb/2mmEH+e99HebnCuydiiGebZVWcLsoOw+gmb
+WG/4rFyp9D/ZYFiQxWNRm/nCcxiHIV+JHDxhBn3vKENxYNNbr+WTMBTqmaYqPARK
+SelnX+XDRTZUnoRBo03wZFYwOYwHUFWrlMFz+o6jOo2KZa4J+pcEDbttkJEoVhiV
+C8EKIxSsG9TuW4lh5UySfB62ZfQBNd8SyhD4LF5JHFbBV9ysnylg/8gVvavjHWtM
+FleOk/lNi9oj2n8uQEGbBT6FpTaKKJDiF85E3J4fuv8iNiFy2nWhCpJFF9K5/hu6
+s41Y2ZRb7luBoUj+CQWlTpGjCJPzzWmSkZUjf5kRP6b01bAXoLBzBBn50KWf8DWw
+Rx7VaHtzbBRxfzESQxslGRgZvz2KxjY/x2jH6xdW+bzt93aHkgeGkDrjpY9q/uQF
+SyEJYHIDt+FZupcc3KjvTY2p+icbckOrwQAtVWXzEjCsnDjf33+O7VGdACDm
+-----END CERTIFICATE-----
diff --git a/deploy/compose/nats_config/key.pem b/deploy/compose/nats_config/key.pem
new file mode 100644
index 0000000..83486a9
--- /dev/null
+++ b/deploy/compose/nats_config/key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCdQCgwn7M5jtkN
+zYv/yUelUV84ehsYjPTQspCXCjDdUltOE6jafRM/2SopUWwzPTorIZkerIpqq/av
+i77e6wSdCKJZBA5DsrMSOmFjjMqG4H2beuzr5b+ZKzKnw4nF/CuB2cmWkz/qAilu
+qVdRl+Gef/Ouyuer/NuhJhK6Mgy1VuAdynwizGsAgQ/oAGDuHWmcMhGw/2NVTnXq
+Hei5ntr+F4r08YOgXnRsGId+16nJU5xdXs80sw2dFl+1zQiFJxWjVQk65CyZfLDc
+wC7e3PAMsT+8obzuBKCn6fW3JiIZ68tco8GZClHSkeS7IMp+/wtjMXf1iipE0bRW
+zzdl1xQnAgMBAAECggEAMRDQuYNLJ/2DioQFV/WVDmdaf8PR6pIo3WmqJga/An/t
+D2qg+DOoqvZ26leGnGJRYR3lqiWKNwibO2EuWF4anWkRRxc14DfFGj3vH2HR2832
+Q2pSvLR+WSuabbBcr9MkPCsZdItTmQ+9n9Lk9QegFZW1Emgra4XFff3kQAbX4kjR
+ATyEsvZsgnkK5jHi5bzVHEKY730MKyhYzmHmUgxH1ibD5x+tnFtRiBGK+qY24erW
+rw+wu0YKu1ESp62orYDnaA8MH7aWlFZLniPB4liA0h0bElrgHA8Zndx+cEtXqF4m
+5+igR3MjXbg2at80ah++z6EGUTtEPccRSpcA7qFqMQKBgQDFVp1msdn45Xwquw+8
+CSZ45KAurvQEPNxtK/GMHtR5LjRZlKQEpNy3AVjz56azv72kqUfhNsP+ZNokMQTH
+NTMvdkLzcwKe3qCnsfBRlSkRBVCwan266oCJW8SSX8pdaoME9lzc2BfMVAxJ1n+Y
+289ZHXyyPYdNd+L4FxjreJDkKQKBgQDL/uD+kCSKZ/dYVZqwF06DIzYiBv1Xjne3
+3H90J0h/2iU9/yX9UsCS7D5RWbVROUyMh64fpH0f2lVFT8Xo3SjBWISrMovOxEzl
+C2wZwM2VQmrfhiUg9h46drJSl/JL9/V/QOnpuQe35bVWjROtFStaZagUK/3vx1hh
+xCV4iVS/zwKBgQC2Ea3zvA/x9jlTa3ee84pNbBLmP4DgEA8Hos2fjCpZC+o85ElY
+B4ukRVf+4TILEdM1AwJQpii6o+4oChnwegMZvTEUUH6QebMcRa4Gd2qGS7MgsYAD
+XqztDoAU1NBu1ADCKVOQZse+O6WC0qazL8rk27Ha+a3GKeB9KUJSrtBv0QKBgCi5
+IftPlSvYI2WL+Uxr6q19KwJR+OMwuq+Goh7y9KMpTkP5GoFesrjh1nLxAKRNVv26
+3ETO1ne0Y09p5G1fMRKf9CQk/Anz4BHdXOArQB8q2iDzK5hP6arsJR8d3C3UOzsD
+H28cE/FfNvsnQKVN05DBOHOGcLQcTIV/3acZa0S7AoGBAJqSujzhVkewH7wJWOOh
+92F66vMnCsE4Qn10h84GQQWORgjr8z8d8UbW7VrobVfZP74IBqo3ZUBYm85+lUFu
+FWHjTkXoZzwP8IvMW0gE2iC3W4QSr2Z96a6RlRJdxC70LB+Pm6FFwLTloKBGK8Bf
+Kp53gUDjsvJcQGv6nOty0uHQ
+-----END PRIVATE KEY-----
diff --git a/deploy/compose/nats_config/nats.cfg b/deploy/compose/nats_config/nats.cfg
new file mode 100644
index 0000000..ae6618f
--- /dev/null
+++ b/deploy/compose/nats_config/nats.cfg
@@ -0,0 +1,18 @@
+server_name: $NATS_NAME
+port: 4222
+http_port: 8222
+authorization: {
+ users: [
+ {user: $NATS_USER, password: $NATS_PW}
+ ]
+}
+tls: {
+ cert_file: "/tmp/nats/config/cert.pem"
+ key_file: "/tmp/nats/config/key.pem"
+ ca_file: "/tmp/nats/config/rootCA.pem"
+}
+// enables jetstream, an empty block will enable and use defaults
+jetstream {
+ // jetstream data will be in /data/nats-server/jetstream
+ store_dir: "/tmp/nats/jetstream"
+}
diff --git a/deploy/compose/nats_config/rootCA.pem b/deploy/compose/nats_config/rootCA.pem
new file mode 100644
index 0000000..30288b2
--- /dev/null
+++ b/deploy/compose/nats_config/rootCA.pem
@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIE6zCCA1OgAwIBAgIQcw3hWvi1nfQFSkUzrcdrhTANBgkqhkiG9w0BAQsFADCB
+jTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMTEwLwYDVQQLDChjaGll
+c2FAQWRyaWFub01hYy5sb2NhbCAoQWRyaWFubyBDaGllc2EpMTgwNgYDVQQDDC9t
+a2NlcnQgY2hpZXNhQEFkcmlhbm9NYWMubG9jYWwgKEFkcmlhbm8gQ2hpZXNhKTAe
+Fw0yMjA4MTIxNTM1NDdaFw0zMjA4MTIxNTM1NDdaMIGNMR4wHAYDVQQKExVta2Nl
+cnQgZGV2ZWxvcG1lbnQgQ0ExMTAvBgNVBAsMKGNoaWVzYUBBZHJpYW5vTWFjLmxv
+Y2FsIChBZHJpYW5vIENoaWVzYSkxODA2BgNVBAMML21rY2VydCBjaGllc2FAQWRy
+aWFub01hYy5sb2NhbCAoQWRyaWFubyBDaGllc2EpMIIBojANBgkqhkiG9w0BAQEF
+AAOCAY8AMIIBigKCAYEA4HBEZqDbKPB0StZX/ILPU1q2Tm/U4j32/HvaWOGt528q
+15y5eqa4OqpYQ7waVhkSR+M6258yAk9BCCOGrI+oXcllO7LKv4bg/y+HVhfEg4E0
+fnZS583+VWrIcIKOENQQX1cbFnIqLldBL/ph6YNMDT8wOoLqtQ2vp1EiXFA3ghQs
+fK3iqDL31SQ7cZhdw7hnNACgvIM6MipwFLYbMsm27eMa9fCL4ZB3xokhbYVBmEcT
+RTdhGvcRBs+QF8fcP/Y6uC9y7q2ddeIYEAf5xCVc15QepPqVskuAM3rktzVpBKEl
+lzJGtW3EWu3kojrrW8dYZkZFJkHy9ymZVNUPjpAGiIIylp1Rik/o9VttXi+BQmrV
+l1tpkrU1JfhLcktjBtRxtvRJTARpSkMM8gVc1rA2KgNsULzF4Zaas12wUh7r/VzW
+4lwKiV3vgAM0wE5Fo4NLmv53/j3w7yX9GtSq0Ck/cKu2k0cOe+PTlG9aQ5MdhLCx
++BwMij/ohBfh0qtgPVPdAgMBAAGjRTBDMA4GA1UdDwEB/wQEAwICBDASBgNVHRMB
+Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBR9ihLDMEu/0LtXhNQ8UYWUyNGe0TANBgkq
+hkiG9w0BAQsFAAOCAYEAyGNw197jniIGfCpcArC2lHbzNIQCq97BXsOj4h+CaUB+
+ZfTpTOdtS5DK2fSQ4jwH6nzm7VQvrnHcbP2pCgVDWW9da+Acnh1U6dYXI1VPDDVA
+KZGDiK63M6PneX3IDl2N2fubRDP1ALkZQ6zwjtJLC2nT6IVjAJdRNt8egbCUAyMb
+nOb4F+Zrr0L2SILM0jHq9diJVpX4Lxqggldmd+5HdVGHoR8BGzw4MReuoRWOZtf/
+H+opFtJ2f8GNTWsWtmN7FsjrGOOBgREB/Tz7WCWgGEeXQveJEfkOIddVVgb/n9Ly
+mEOTbtJj36o4JJzv0v42SdT1WUkdvc6AmLVmYFn0uaLohNLVelJmU+aGavuVFpFb
+08uVsSl8JMBWwVO23CpuvZFbI/1BFVix85UZgDj8BnpAWlsJxPYV1HqxS2oJJJbn
+zRf8/0xzFPrLirXzebIr4jiCRVBRamacQTxlvPUz6c6FLTQLaqQdUV/IZaXsXX38
+byH1ABmJPGjXLm1r2RWD
+-----END CERTIFICATE-----
diff --git a/deploy/compose/nginx.conf b/deploy/compose/nginx.conf
index 1bba7d8..64e9648 100644
--- a/deploy/compose/nginx.conf
+++ b/deploy/compose/nginx.conf
@@ -11,19 +11,7 @@ server {
}
location / {
- proxy_pass http://frontend:3000;
- proxy_read_timeout 60;
- proxy_connect_timeout 60;
- proxy_redirect off;
- }
- location /api {
- proxy_pass http://controller:8000;
- proxy_read_timeout 60;
- proxy_connect_timeout 60;
- proxy_redirect off;
- }
- location /socket.io {
- proxy_pass http://socketio:5000;
+ proxy_pass http://host.docker.internal:3000;
proxy_read_timeout 60;
proxy_connect_timeout 60;
proxy_redirect off;
@@ -34,6 +22,33 @@ server {
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
+ location /api {
+ proxy_pass http://host.docker.internal:8000;
+ proxy_read_timeout 60;
+ proxy_connect_timeout 60;
+ proxy_redirect off;
+ }
+ location /custom-frontend {
+ proxy_pass http://host.docker.internal:8005;
+ proxy_read_timeout 60;
+ proxy_connect_timeout 60;
+ proxy_redirect off;
+ }
+ location /socket.io {
+ proxy_pass http://host.docker.internal:5000;
+ proxy_read_timeout 60;
+ proxy_connect_timeout 60;
+ proxy_redirect off;
+
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection 'upgrade';
+ proxy_set_header Host $host;
+ proxy_cache_bypass $http_upgrade;
+ }
+ location /companylink {
+ return 301 https://oktopus.app.br/controller;
+ }
error_page 500 502 503 504 /50x.html;
location = /50x.html {
diff --git a/frontend/.env b/frontend/.env
index 2116eeb..293b49b 100644
--- a/frontend/.env
+++ b/frontend/.env
@@ -1,6 +1,5 @@
# ----------------------------- Local Environment ---------------------------- #
-NEXT_PUBLIC_REST_ENDPOINT="http://localhost:8000"
NEXT_PUBLIC_WS_ENDPOINT="http://localhost:5000/"
NEXT_PUBLIC_ENTERPRISE_VERSION="false"
NEXT_PUBLIC_GOOGLE_MAPS_KEY=""
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index cf2561d..12297bb 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -18,14 +18,14 @@
"@mui/system": "5.11.9",
"@mui/x-date-pickers": "5.0.19",
"@react-google-maps/api": "^2.19.3",
- "apexcharts": "3.37.0",
+ "apexcharts": "^3.37.0",
"date-fns": "2.29.3",
"formik": "2.2.9",
"next": "^14.2.4",
"nprogress": "0.2.0",
"prop-types": "15.8.1",
"react": "^18.3.1",
- "react-apexcharts": "1.4.0",
+ "react-apexcharts": "^1.4.0",
"react-dom": "^18.3.1",
"simple-peer": "^9.11.1",
"simplebar-react": "^3.2.1",
@@ -1480,6 +1480,11 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
+ "node_modules/@yr/monotone-cubic-spline": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz",
+ "integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA=="
+ },
"node_modules/acorn": {
"version": "8.11.3",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
@@ -1538,10 +1543,11 @@
}
},
"node_modules/apexcharts": {
- "version": "3.37.0",
- "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.37.0.tgz",
- "integrity": "sha512-0mg1gDKUo3JG00Q//LK0jEXBS6OLjpuglqZ8ec9cqfA5oP8owopD9n5EhfARbWROb5o8GSPzFuohTJiCm2ecWw==",
+ "version": "3.50.0",
+ "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.50.0.tgz",
+ "integrity": "sha512-LJT1PNAm+NoIU3aogL2P+ViC0y/Cjik54FdzzGV54UNnGQLBoLe5ok3fxsJDTgyez45BGYT8gqNpYKqhdfy5sg==",
"dependencies": {
+ "@yr/monotone-cubic-spline": "^1.0.3",
"svg.draggable.js": "^2.2.2",
"svg.easing.js": "^2.0.0",
"svg.filter.js": "^2.0.2",
@@ -4722,14 +4728,14 @@
}
},
"node_modules/react-apexcharts": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.0.tgz",
- "integrity": "sha512-DrcMV4aAMrUG+n6412yzyATWEyCDWlpPBBhVbpzBC4PDeuYU6iF84SmExbck+jx5MUm4U5PM3/T307Mc3kzc9Q==",
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.1.tgz",
+ "integrity": "sha512-G14nVaD64Bnbgy8tYxkjuXEUp/7h30Q0U33xc3AwtGFijJB9nHqOt1a6eG0WBn055RgRg+NwqbKGtqPxy15d0Q==",
"dependencies": {
- "prop-types": "^15.5.7"
+ "prop-types": "^15.8.1"
},
"peerDependencies": {
- "apexcharts": "^3.18.0",
+ "apexcharts": "^3.41.0",
"react": ">=0.13"
}
},
@@ -7102,6 +7108,11 @@
"eslint-visitor-keys": "^3.3.0"
}
},
+ "@yr/monotone-cubic-spline": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz",
+ "integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA=="
+ },
"acorn": {
"version": "8.11.3",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
@@ -7142,10 +7153,11 @@
}
},
"apexcharts": {
- "version": "3.37.0",
- "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.37.0.tgz",
- "integrity": "sha512-0mg1gDKUo3JG00Q//LK0jEXBS6OLjpuglqZ8ec9cqfA5oP8owopD9n5EhfARbWROb5o8GSPzFuohTJiCm2ecWw==",
+ "version": "3.50.0",
+ "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.50.0.tgz",
+ "integrity": "sha512-LJT1PNAm+NoIU3aogL2P+ViC0y/Cjik54FdzzGV54UNnGQLBoLe5ok3fxsJDTgyez45BGYT8gqNpYKqhdfy5sg==",
"requires": {
+ "@yr/monotone-cubic-spline": "^1.0.3",
"svg.draggable.js": "^2.2.2",
"svg.easing.js": "^2.0.0",
"svg.filter.js": "^2.0.2",
@@ -9444,11 +9456,11 @@
}
},
"react-apexcharts": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.0.tgz",
- "integrity": "sha512-DrcMV4aAMrUG+n6412yzyATWEyCDWlpPBBhVbpzBC4PDeuYU6iF84SmExbck+jx5MUm4U5PM3/T307Mc3kzc9Q==",
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.1.tgz",
+ "integrity": "sha512-G14nVaD64Bnbgy8tYxkjuXEUp/7h30Q0U33xc3AwtGFijJB9nHqOt1a6eG0WBn055RgRg+NwqbKGtqPxy15d0Q==",
"requires": {
- "prop-types": "^15.5.7"
+ "prop-types": "^15.8.1"
}
},
"react-dom": {
diff --git a/frontend/package.json b/frontend/package.json
index 7347046..02747e2 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -24,14 +24,14 @@
"@mui/system": "5.11.9",
"@mui/x-date-pickers": "5.0.19",
"@react-google-maps/api": "^2.19.3",
- "apexcharts": "3.37.0",
+ "apexcharts": "^3.37.0",
"date-fns": "2.29.3",
"formik": "2.2.9",
"next": "^14.2.4",
"nprogress": "0.2.0",
"prop-types": "15.8.1",
"react": "^18.3.1",
- "react-apexcharts": "1.4.0",
+ "react-apexcharts": "^1.4.0",
"react-dom": "^18.3.1",
"simple-peer": "^9.11.1",
"simplebar-react": "^3.2.1",
diff --git a/frontend/public/assets/logo.png b/frontend/public/assets/logo.png
new file mode 100644
index 0000000..5352dba
Binary files /dev/null and b/frontend/public/assets/logo.png differ
diff --git a/frontend/src/layouts/auth/layout.js b/frontend/src/layouts/auth/layout.js
index 203d38d..b8d2872 100644
--- a/frontend/src/layouts/auth/layout.js
+++ b/frontend/src/layouts/auth/layout.js
@@ -1,13 +1,16 @@
import PropTypes from 'prop-types';
import NextLink from 'next/link';
import Link from 'next/link'
-import { Box, Typography, Unstable_Grid2 as Grid } from '@mui/material';
+import { Box, Typography, Unstable_Grid2 as Grid, Stack } from '@mui/material';
import { Logo } from 'src/components/logo';
-
-// TODO: Change subtitle text
+import { useTheme, useMediaQuery } from '@mui/material'
export const Layout = (props) => {
const { children } = props;
+ const lgUp = useMediaQuery((theme) => theme.breakpoints.up('lg'));
+ const theme = useTheme();
+
+ console.log("logUp", lgUp)
return (
{
lg={6}
sx={{
alignItems: 'center',
- background: 'radial-gradient(50% 50% at 50% 50%, #306D6F 0%, #255355 100%)',
+ background: `radial-gradient(50% 50% at 50% 50%, ${theme.palette.primary.main} 0%, ${theme.palette.primary.dark } 100%)`,
color: 'white',
display: 'flex',
justifyContent: 'center',
@@ -70,20 +73,32 @@ export const Layout = (props) => {
}}
>
-
-
-
-
-
+
+
+
+
+
+ Powered by
+
+
+
+
+
);
};
diff --git a/frontend/src/layouts/dashboard/config.js b/frontend/src/layouts/dashboard/config.js
index 171482a..f2e7fff 100644
--- a/frontend/src/layouts/dashboard/config.js
+++ b/frontend/src/layouts/dashboard/config.js
@@ -35,15 +35,15 @@ export const items = [
//
// )
// },
- // {
- // title: 'Map',
- // path: '/map',
- // icon: (
- //
- //
- //
- // ),
- // },
+ {
+ title: 'Map',
+ path: '/map',
+ icon: (
+
+
+
+ ),
+ },
{
title: 'Credentials',
path: '/credentials',
diff --git a/frontend/src/layouts/dashboard/layout.js b/frontend/src/layouts/dashboard/layout.js
index 2753fa6..104db95 100644
--- a/frontend/src/layouts/dashboard/layout.js
+++ b/frontend/src/layouts/dashboard/layout.js
@@ -4,8 +4,6 @@ import { styled } from '@mui/material/styles';
import { withAuthGuard } from 'src/hocs/with-auth-guard';
import { SideNav } from './side-nav';
import { TopNav } from './top-nav';
-import Image from 'next/image'
-import { Link } from '@mui/material';
const SIDE_NAV_WIDTH = 280;
diff --git a/frontend/src/layouts/dashboard/side-nav.js b/frontend/src/layouts/dashboard/side-nav.js
index d67d4d5..d09aed5 100644
--- a/frontend/src/layouts/dashboard/side-nav.js
+++ b/frontend/src/layouts/dashboard/side-nav.js
@@ -2,8 +2,6 @@ import NextLink from 'next/link';
import { usePathname } from 'next/navigation';
import PropTypes from 'prop-types';
import Link from 'next/link'
-import ArrowTopRightOnSquareIcon from '@heroicons/react/24/solid/ArrowTopRightOnSquareIcon';
-import ChevronUpDownIcon from '@heroicons/react/24/solid/ChevronUpDownIcon';
import {
Box,
Button,
@@ -18,12 +16,15 @@ import { Logo } from 'src/components/logo';
import { Scrollbar } from 'src/components/scrollbar';
import { items } from './config';
import { SideNavItem } from './side-nav-item';
+import { useTheme } from '@mui/material';
export const SideNav = (props) => {
const { open, onClose } = props;
const pathname = usePathname();
const lgUp = useMediaQuery((theme) => theme.breakpoints.up('lg'));
+ const theme = useTheme();
+
const isItemActive = (currentPath, itemPath) => {
if (currentPath === itemPath) {
return true;
@@ -34,7 +35,6 @@ export const SideNav = (props) => {
}
return false;
- //TODO: test frontend with color of the landing page
}
const content = (
@@ -80,9 +80,9 @@ export const SideNav = (props) => {
p: '12px'
}}
>
-
+
-
@@ -113,6 +113,9 @@ export const SideNav = (props) => {
}}
>
{items.map((item) => {
+ if (item.title == "Map" && process.env.NEXT_PUBLIC_ENTERPRISE_VERSION != "true"){
+ return
+ }
const active = isItemActive(pathname, item.path);
return (
@@ -129,7 +132,24 @@ export const SideNav = (props) => {
})}
-
+
+
+ Powered by
+
+
+
+
+
);
@@ -141,7 +161,7 @@ export const SideNav = (props) => {
open
PaperProps={{
sx: {
- backgroundColor: 'neutral.800',
+ background: `linear-gradient(0deg, ${theme.palette.neutral["800"]} 0%, ${theme.palette.primary.dark} 90%);`,
color: 'common.white',
width: 280
}
@@ -160,7 +180,7 @@ export const SideNav = (props) => {
open={open}
PaperProps={{
sx: {
- backgroundColor: 'neutral.800',
+ background: `linear-gradient(0deg, ${theme.palette.primary.main} 0%, ${theme.palette.primary.dark} 90%);`,
color: 'common.white',
width: 280
}
diff --git a/frontend/src/pages/_app.js b/frontend/src/pages/_app.js
index 7bc21fb..06c636d 100644
--- a/frontend/src/pages/_app.js
+++ b/frontend/src/pages/_app.js
@@ -10,21 +10,26 @@ import { createTheme } from 'src/theme';
import { createEmotionCache } from 'src/utils/create-emotion-cache';
import 'simplebar-react/dist/simplebar.min.css';
import { WsProvider } from 'src/contexts/socketio-context';
+import '../utils/map.css';
+import { useEffect, useState } from 'react';
const clientSideEmotionCache = createEmotionCache();
const SplashScreen = () => null;
const App = (props) => {
+ const [theme, setTheme] = useState(null);
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
useNProgress();
const getLayout = Component.getLayout ?? ((page) => page);
- const theme = createTheme();
+ useEffect(() => {
+ setTheme(createTheme());
+ }, []);
- return (
+ return theme && (
diff --git a/frontend/src/pages/map.js b/frontend/src/pages/map.js
index 24a111c..6ba92ea 100644
--- a/frontend/src/pages/map.js
+++ b/frontend/src/pages/map.js
@@ -1,39 +1,163 @@
import Head from 'next/head';
-import { GoogleMap, useLoadScript } from "@react-google-maps/api"
+import { GoogleMap, useLoadScript, Marker, OverlayView } from "@react-google-maps/api"
import { Layout as DashboardLayout } from 'src/layouts/dashboard/layout';
import { useEffect, useMemo, useState } from 'react';
import mapStyles from '../utils/mapStyles.json';
+import { useRouter } from 'next/router';
+
+const getPixelPositionOffset = pixelOffset => (width, height) => ({
+ x: -(width / 2) + pixelOffset.x,
+ y: -(height / 2) + pixelOffset.y
+});
+
+const Popup = props => {
+ return (
+
+
+
+ );
+};
const Page = () => {
const libraries = useMemo(() => ['places'], []);
+ const router = useRouter();
+
+ const [mapRef, setMapRef] = useState(null);
+
const [mapCenter, setMapCenter] = useState(null);
+ const [markers, setMarkers] = useState([]);
+ const [activeMarker, setActiveMarker] = useState(null);
+ const [activeMarkerdata, setActiveMarkerdata] = useState(null);
+ const [zoom, setZoom] = useState(null)
+
+ const handleDragEnd = () => {
+ if (mapRef) {
+ const newCenter = mapRef.getCenter();
+ console.log("newCenter:",newCenter.lat(), newCenter.lng());
+ localStorage.setItem("mapCenter", JSON.stringify({"lat":newCenter.lat(),"lng":newCenter.lng()}))
+ }
+ }
+
+ const handleZoomChange = () => {
+ if (mapRef) {
+ const newZoom = mapRef.getZoom();
+ console.log("new zoom", newZoom)
+ localStorage.setItem("zoom", newZoom)
+ }
+ }
+
+ const handleOnLoad = map => {
+ setMapRef(map);
+ };
+
+ const fetchMarkers = async () => {
+
+ var myHeaders = new Headers();
+ myHeaders.append("Content-Type", "application/json");
+ myHeaders.append("Authorization", localStorage.getItem("token"));
+
+ var requestOptions = {
+ method: 'GET',
+ headers: myHeaders,
+ redirect: 'follow'
+ };
+
+ let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/map`, requestOptions)
+
+ if (result.status == 200) {
+ const content = await result.json()
+ setMarkers(content)
+ }else if (result.status == 403) {
+ console.log("num tenx permissão, seu boca de sandália")
+ return router.push("/403")
+ }else if (result.status == 401){
+ console.log("taix nem autenticado, sai fora oh")
+ return router.push("/auth/login")
+ } else {
+ setMarkers([])
+ console.log("error to get map markers")
+ }
+ }
+
+ const fetchActiveMarkerData = async (id) => {
+ var myHeaders = new Headers();
+ myHeaders.append("Content-Type", "application/json");
+ myHeaders.append("Authorization", localStorage.getItem("token"));
+
+ var requestOptions = {
+ method: 'GET',
+ headers: myHeaders,
+ redirect: 'follow'
+ };
+
+ let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device?id=`+id, requestOptions)
+
+ if (result.status == 200) {
+ const content = await result.json()
+ setActiveMarkerdata(content)
+ }else if (result.status == 403) {
+ return router.push("/403")
+ }else if (result.status == 401){
+ return router.push("/auth/login")
+ } else {
+ console.log("no device info found")
+ const content = await result.json()
+ }
+ }
useEffect(()=> {
- // Check if geolocation is supported by the browser
- if ("geolocation" in navigator) {
- // Prompt user for permission to access their location
- navigator.geolocation.getCurrentPosition(
- // Get the user's latitude and longitude coordinates
- // Success callback function
- function(position) {
- // Update the map with the user's new location
- setMapCenter({
- lat: position.coords.latitude,
- lng: position.coords.longitude,
- })
- },
- // Error callback function
- function(error) {
- // Handle errors, e.g. user denied location sharing permissions
- console.error("Error getting user location:", error);
- }
- );
- } else {
- // Geolocation is not supported by the browser
- console.error("Geolocation is not supported by this browser.");
- }
+ fetchMarkers();
+
+ let zoomFromLocalStorage = localStorage.getItem("zoom")
+ if (zoomFromLocalStorage) {
+ setZoom(Number(zoomFromLocalStorage))
+ }else{
+ setZoom(25)
+ }
+
+ let mapCenterFromLocalStorage = localStorage.getItem("mapCenter")
+ if (mapCenterFromLocalStorage){
+ let fmtMapCenter = JSON.parse(localStorage.getItem("mapCenter"))
+ console.log("mapCenterFromLocalStorage:", fmtMapCenter)
+ setMapCenter({
+ lat: Number(fmtMapCenter.lat),
+ lng: Number(fmtMapCenter.lng),
+ })
+ return
+ }
+ // Check if geolocation is supported by the browser
+ if ("geolocation" in navigator) {
+ // Prompt user for permission to access their location
+ navigator.geolocation.getCurrentPosition(
+ // Get the user's latitude and longitude coordinates
+ // Success callback function
+ function(position) {
+ // Update the map with the user's new location
+ setMapCenter({
+ lat: position.coords.latitude,
+ lng: position.coords.longitude,
+ })
+ },
+ // Error callback function
+ function(error) {
+ // Handle errors, e.g. user denied location sharing permissions
+ console.log("Error getting user location:", error);
+ }
+ );
+ } else {
+ // Geolocation is not supported by the browser
+ console.log("Geolocation is not supported by this browser, or the user denied access");
+ }
},[])
const mapOptions = useMemo(
@@ -59,7 +183,7 @@ const Page = () => {
return Loading...
;
}
- return ( mapCenter &&
+ return ( markers && zoom &&
<>
@@ -68,12 +192,61 @@ const Page = () => {
console.log('Map Component Loaded...')}
+ onLoad={handleOnLoad}
clickableIcons={false}
- />
+ onDragEnd={handleDragEnd}
+ onZoomChanged={handleZoomChange}
+ >
+ {
+ markers.map((marker, index) => (
+ {
+ setActiveMarkerdata(null);
+ if (activeMarker?.sn === marker.sn) {
+ setActiveMarker(null);
+ return;
+ }
+ fetchActiveMarkerData(marker.sn);
+ setActiveMarker({
+ sn: marker.sn,
+ position: { lat: marker.coordinates.lat, lng: marker.coordinates.lng }
+ });
+ }}
+ >
+
+ ))
+ }
+ {activeMarker &&
+
+ SN: {activeMarker.sn}
+
+
Model: {activeMarkerdata.Model?activeMarkerdata.Model:activeMarkerdata.ProductClass}
+
Alias: {activeMarkerdata.Alias}
+
Status: {activeMarkerdata.Status == 2 ? online : offline }
+
+
+ : no device info found
}
+ />}
+
>
)};
diff --git a/frontend/src/sections/devices/cwmp/connecteddevices.js b/frontend/src/sections/devices/cwmp/connecteddevices.js
index 50e86a2..6d5d859 100644
--- a/frontend/src/sections/devices/cwmp/connecteddevices.js
+++ b/frontend/src/sections/devices/cwmp/connecteddevices.js
@@ -16,102 +16,133 @@ export const ConnectedDevices = () => {
const [interfaces, setInterfaces] = useState([]);
const [interfaceValue, setInterfaceValue] = useState(null);
+ const getConnectionState = (rssi) => {
+ let connectionStatus = "Signal "
+ if (rssi > -30) {
+ return connectionStatus + "Excellent"
+ } else if (rssi > -60) {
+ return connectionStatus + "Good"
+ } else if (rssi > -70) {
+ return connectionStatus + "Bad"
+ } else {
+ return connectionStatus + "Awful"
+ }
+ }
+
const fetchConnectedDevicesData = async () => {
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Authorization", localStorage.getItem("token"));
-
+
var requestOptions = {
- method: 'GET',
- headers: myHeaders,
- redirect: 'follow'
+ method: 'GET',
+ headers: myHeaders,
+ redirect: 'follow'
};
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/connecteddevices`, requestOptions)
- .then(response => {
- if (response.status === 401) {
- router.push("/auth/login")
- }
- return response.json()
- })
- .then(result => {
- console.log("connecteddevices content", result)
- let interfaces = Object.keys(result)
- setInterfaces(interfaces)
- setInterfaceValue(interfaces[0])
- setContent(result)
- })
- .catch(error => console.log('error', error));
+ .then(response => {
+ if (response.status === 401) {
+ router.push("/auth/login")
+ }
+ return response.json()
+ })
+ .then(result => {
+ console.log("connecteddevices content", result)
+ let interfaces = Object.keys(result)
+ setInterfaces(interfaces)
+ setInterfaceValue(interfaces[0])
+ setContent(result)
+ })
+ .catch(error => console.log('error', error));
};
useEffect(() => {
fetchConnectedDevicesData();
- },[])
+ }, [])
- return (
-
- {content && interfaces.length > 0 ?
-
-
-
- Interface
- setInterfaceValue(e.target.value)}>
- {(
- interfaces.map((item, index) => (
-
- {item}
-
+ {content && interfaces.length > 0 ?
+
+
+
+ Interface
+ setInterfaceValue(e.target.value)}>
+ {(
+ interfaces.map((item, index) => (
+
+ {item}
+
+ ))
+ )}
+
+
+ {
+ content[interfaceValue].map((property, index) => (
+
+
+
+
+
+
+
+
+
+
+
+ {property.hostname}
+
+
+
+
+
+ IP address: {property.ip_adress}
+
+
+ MAC: {property.mac}
+
+
+
+
+ Source: {property.adress_source}
+
+
+ {
+ let rssi = property.rssi
+ if(rssi == 0){
+ return theme.palette.neutral[900]
+ } else if (rssi > -30) {
+ return theme.palette.success.main
+ } else if (rssi > -60) {
+ return theme.palette.success.main
+ } else if (rssi > -70) {
+ return theme.palette.warning.main
+ } else {
+ return theme.palette.error.main
+ }
+ }}>
+
+ RSSI:
+
+ {property.rssi} dbm
+
+
+
+
+
+
+
))
- )}
-
-
- {
- content[interfaceValue].map((property,index) => (
-
-
-
-
-
-
-
-
-
-
-
- {property.hostname}
-
-
-
-
-
- IP address: {property.ip_adress}
-
-
- MAC: {property.mac}
-
-
-
-
- RSSI: {property.rssi} dbm
-
-
- Source: {property.adress_source}
-
-
-
-
-
-
- ))
- }
-
- : (
- content ? No connected devices found :
- )}
+ }
+
+ : (
+ content ? No connected devices found :
+ )}
)
}
\ No newline at end of file
diff --git a/frontend/src/sections/devices/cwmp/devices-wifi.js b/frontend/src/sections/devices/cwmp/devices-wifi.js
index e9047f2..f0ed7e5 100644
--- a/frontend/src/sections/devices/cwmp/devices-wifi.js
+++ b/frontend/src/sections/devices/cwmp/devices-wifi.js
@@ -1,31 +1,31 @@
import { useCallback, useEffect, useState } from 'react';
import {
- Button,
- Card,
- CardActions,
- CardContent,
- CardHeader,
- Divider,
- Stack,
- TextField,
- InputLabel,
- MenuItem,
- Select,
- FormControl,
- SvgIcon,
- Dialog,
- DialogTitle,
- DialogContent,
- DialogContentText,
- DialogActions,
- Box,
- IconButton,
- Icon,
- SnackbarContent,
- Snackbar,
- Checkbox,
- FormControlLabel,
- useTheme,
+ Button,
+ Card,
+ CardActions,
+ CardContent,
+ CardHeader,
+ Divider,
+ Stack,
+ TextField,
+ InputLabel,
+ MenuItem,
+ Select,
+ FormControl,
+ SvgIcon,
+ Dialog,
+ DialogTitle,
+ DialogContent,
+ DialogContentText,
+ DialogActions,
+ Box,
+ IconButton,
+ Icon,
+ SnackbarContent,
+ Snackbar,
+ Checkbox,
+ FormControlLabel,
+ useTheme,
} from '@mui/material';
import XMarkIcon from '@heroicons/react/24/outline/XMarkIcon';
import Check from '@heroicons/react/24/outline/CheckIcon';
@@ -52,44 +52,44 @@ export const DevicesWiFi = () => {
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Authorization", localStorage.getItem("token"));
-
+
var requestOptions = {
- method: 'GET',
- headers: myHeaders,
- redirect: 'follow'
+ method: 'GET',
+ headers: myHeaders,
+ redirect: 'follow'
};
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/wifi`, requestOptions)
- .then(response => {
- if (response.status === 401) {
- router.push("/auth/login")
- }
- return response.json()
- })
- .then(result => {
- console.log("wifi content", result)
- result.map((item) => {
- let contentToApply = {
- hasChanges: false,
- path: item.path,
+ .then(response => {
+ if (response.status === 401) {
+ router.push("/auth/login")
}
- setApplyContent(oldValue => [...oldValue, contentToApply])
+ return response.json()
})
- setContent(result)
- })
- .catch(error => console.log('error', error));
+ .then(result => {
+ console.log("wifi content", result)
+ result.map((item) => {
+ let contentToApply = {
+ hasChanges: false,
+ path: item.path,
+ }
+ setApplyContent(oldValue => [...oldValue, contentToApply])
+ })
+ setContent(result)
+ })
+ .catch(error => console.log('error', error));
};
- useEffect(()=>{
+ useEffect(() => {
fetchWifiData()
- },[])
+ }, [])
return (
-
{content.length > 1 ?
(content.map((item, index) => {
@@ -99,25 +99,25 @@ export const DevicesWiFi = () => {
title={item.name.value}
avatar={
-
+
}
/>
- { item.enable.value != null &&
- {
- let enable = item.enable.value == 1 ? "0" : "1"
- console.log(enable)
- applyContent[index].hasChanges = true
- applyContent[index].enable = {
- value : enable
- }
- setApplyContent([...applyContent])
- item.enable.value = enable
- }}/>}
- label="Enabled" />}
+ {item.enable.value != null &&
+ {
+ let enable = item.enable.value == 1 ? "0" : "1"
+ console.log(enable)
+ applyContent[index].hasChanges = true
+ applyContent[index].enable = {
+ value: enable
+ }
+ setApplyContent([...applyContent])
+ item.enable.value = enable
+ }} />}
+ label="Enabled" />}
{item.ssid.value != null && {
onChange={(e) => {
applyContent[index].hasChanges = true
applyContent[index].ssid = {
- value : e.target.value
+ value: e.target.value
}
setApplyContent([...applyContent])
item.ssid.value = e.target.value
}}
/>}
{item.securityCapabilities &&
- }
+ }
{item.password.value != null &&
- {
- if (e.target.value.length >= 8) {
- applyContent[index].hasChanges = true
- }else{
- applyContent[index].hasChanges = false
- }
- applyContent[index].password = {
- value : e.target.value
- }
- setApplyContent([...applyContent])
- item.password.value = e.target.value
- console.log("applyContent: ", applyContent)
- }}
- />}
+ {
+ if (e.target.value.length >= 8) {
+ applyContent[index].hasChanges = true
+ } else {
+ applyContent[index].hasChanges = false
+ }
+ applyContent[index].password = {
+ value: e.target.value
+ }
+ setApplyContent([...applyContent])
+ item.password.value = e.target.value
+ console.log("applyContent: ", applyContent)
+ }}
+ />}
+ {item.channel?.value != null && item.possibleChannels?.value != null &&
+
+ Channel
+ {
+ applyContent[index].hasChanges = true
+ applyContent[index].channel = {
+ value: e.target.value
+ }
+ setApplyContent([...applyContent])
+ item.channel.value = e.target.value
+ }}
+ label="Channel"
+ >
+ {item.possibleChannels.value.map((channel, index) => {
+ return (
+ {channel} )
+ })}
+
+
+ }
{item.standard.value != null &&
- {
- applyContent[index].hasChanges = true
- applyContent[index].standard = {
- value : e.target.value
- }
- setApplyContent([...applyContent])
- item.standard.value = e.target.value
- }}
- />}
+ {
+ applyContent[index].hasChanges = true
+ applyContent[index].standard = {
+ value: e.target.value
+ }
+ setApplyContent([...applyContent])
+ item.standard.value = e.target.value
+ }}
+ />}
-
-
+ }
+ endIcon={ }
onClick={
- ()=>{
+ () => {
setApply(true)
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Authorization", localStorage.getItem("token"));
-
+
delete applyContent[index].hasChanges
let contentToApply = [applyContent[index]]
console.log("contentToApply: ", contentToApply)
@@ -198,38 +222,38 @@ export const DevicesWiFi = () => {
redirect: 'follow'
};
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/wifi`, requestOptions)
- .then(response => {
- if (response.status === 401) {
- router.push("/auth/login")
- }
- if (response.status == 500) {
- setErrorModal(true)
- }
- return response.json()
- })
- .then(result => {
- if (errorModal) {
- setErrorModalText(result)
- }
- setApply(false)
- if (result == 1) {
- setErrorModalText("This change could not be applied, or It's gonna be applied later on")
- setErrorModal(true)
- //TODO: fetch wifi data again
- }
- })
- .catch(error => console.log('error', error));
+ .then(response => {
+ if (response.status === 401) {
+ router.push("/auth/login")
+ }
+ if (response.status == 500) {
+ setErrorModal(true)
+ }
+ return response.json()
+ })
+ .then(result => {
+ if (errorModal) {
+ setErrorModalText(result)
+ }
+ setApply(false)
+ if (result == 1) {
+ setErrorModalText("This change could not be applied, or It's gonna be applied later on")
+ setErrorModal(true)
+ //TODO: fetch wifi data again
+ }
+ })
+ .catch(error => console.log('error', error));
}
}
- sx={{mt:'25px', mb:'-15px'}}
- >
+ sx={{ mt: '25px', mb: '-15px' }}
+ >
Apply
)
- })):
+ })) :
}
@@ -239,44 +263,44 @@ export const DevicesWiFi = () => {
>
-
-
+
+
Response
- {
- setErrorModalText("")
- setErrorModal(false)
- }}>
-
- < XMarkIcon/>
+ {
+ setErrorModalText("")
+ setErrorModal(false)
+ }}>
+
+ < XMarkIcon />
-
-
-
-
+
+
+
+
{errorModalText}
-
-
-
- {
- setErrorModalText("")
- setErrorModal(false)
- }}>OK
-
-
-
- );
+
+
+
+ {
+ setErrorModalText("")
+ setErrorModal(false)
+ }}>OK
+
+
+
+ );
};
diff --git a/frontend/src/sections/devices/cwmp/site-survey.js b/frontend/src/sections/devices/cwmp/site-survey.js
index 1a97cfe..dcfb1bb 100644
--- a/frontend/src/sections/devices/cwmp/site-survey.js
+++ b/frontend/src/sections/devices/cwmp/site-survey.js
@@ -1,6 +1,3 @@
-import PropTypes from 'prop-types';
-import ArrowPathIcon from '@heroicons/react/24/solid/ArrowPathIcon';
-import ArrowRightIcon from '@heroicons/react/24/solid/ArrowRightIcon';
import {
Button,
Card,
@@ -22,12 +19,11 @@ import {
TableHead,
TableRow,
TableContainer,
- Paper,
- Container,
- CircularProgress
+ CircularProgress,
+ ToggleButton,
+ ToggleButtonGroup
} from '@mui/material';
-import { Scrollbar } from 'src/components/scrollbar';
-import { alpha, useTheme } from '@mui/material/styles';
+import { useTheme } from '@mui/material/styles';
import { Chart } from 'src/components/chart';
import ChartBarSquareIcon from '@heroicons/react/24/outline/ChartBarSquareIcon';
import ListBulletIcon from '@heroicons/react/24/outline/ListBulletIcon';
@@ -35,109 +31,256 @@ import { useRouter } from 'next/router';
import { Stack } from '@mui/system';
import { useEffect, useState } from 'react';
-const useChartOptions = () => {
- const theme = useTheme();
-
- return {
- chart: {
- background: 'transparent',
- stacked: false,
- toolbar: {
- show: true
- }
- },
- colors: [
- theme.palette.graphics.dark,
- theme.palette.graphics.darkest,
- theme.palette.graphics.light,
- theme.palette.graphics.main,
- theme.palette.graphics.lightest,
- ],
- dataLabels: {
- enabled: false
- },
- fill: {
- opacity: 1,
- type: 'solid'
- },
- grid: {
- borderColor: theme.palette.divider,
- strokeDashArray: 2,
- xaxis: {
- lines: {
- show: false
- }
- },
- yaxis: {
- lines: {
- show: true
- }
- }
- },
- legend: {
- show: true
- },
- plotOptions: {
- bar: {
- columnWidth: '40px'
- }
- },
- stroke: {
- colors: ['transparent'],
- show: true,
- width: 2
- },
- theme: {
- mode: theme.palette.mode
- },
- xaxis: {
- axisBorder: {
- color: theme.palette.divider,
- show: true
- },
- axisTicks: {
- color: theme.palette.divider,
- show: true
- },
- categories: [
- 'Jan',
- 'Feb',
- 'Mar',
- 'Apr',
- 'May',
- 'Jun',
- 'Jul',
- 'Aug',
- 'Sep',
- 'Oct',
- 'Nov',
- 'Dec'
- ],
- labels: {
- offsetY: 5,
- style: {
- colors: theme.palette.text.secondary
- }
- }
- },
- yaxis: {
- labels: {
- formatter: (value) => (value > 0 ? `${value}K` : `${value}`),
- offsetX: -10,
- style: {
- colors: theme.palette.text.secondary
- }
- }
- }
- };
-};
-
export const SiteSurvey = (props) => {
- const chartSeries = [{ name: 'This year', data: [18, 16, 5, 8, 3, 14, 14, 16, 17, 19, 18, 20] }, { name: 'Last year', data: [12, 11, 4, 6, 2, 9, 9, 10, 11, 12, 13, 13] }]
+
+ // const getMaxChannel = () => {
+ // if (frequency == "2.4GHz") {
+ // return 13;
+ // } else {
+ // return 128;
+ // }
+ // }
+
+ // const geMinChannel = () => {
+ // if (frequency == "2.4GHz") {
+ // return 0;
+ // } else {
+ // return 36;
+ // }
+ // }
+
+ // const getChannelSpacing = () => {
+ // if (frequency == "2.4GHz") {
+ // return 1;
+ // } else {
+ // return 4;
+ // }
+ // }
+
+ // const getChannelAmount = () => {
+ // if (frequency == "2.4GHz") {
+ // return 13;
+ // } else {
+ // return 20;
+ // }
+ // }
+
+ const getCategories = () => {
+
+ }
const router = useRouter();
- const [content, setContent] = useState(null);
+
const [frequency, setFrequency] = useState("2.4GHz");
+ const [view, setView] = useState("chart");
+ const [content, setContent] = useState(null);
+
+ const getSeries = () => {
+ let series = []
+ content[frequency].map((network) => {
+
+ let data = []
+
+ if (frequency == "2.4GHz") {
+ if (Number(network.bandwidth) == 20) {
+ data.push({"x": Number(network.channel) -2, "y": -100})
+ data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
+ data.push({"x": Number(network.channel) +2, "y": -100})
+ }
+ if (Number(network.bandwidth) == 40) {
+ data.push({"x": Number(network.channel) -4, "y": -100})
+ data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
+ data.push({"x": Number(network.channel) +4, "y": -100})
+ }
+ }else {
+ if (Number(network.bandwidth) == 20) {
+ data.push({"x": Number(network.channel) -4, "y": -100})
+ data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
+ data.push({"x": Number(network.channel) +4, "y": -100})
+ }
+ if (Number(network.bandwidth) == 40) {
+ data.push({"x": Number(network.channel) -8, "y": -100})
+ data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
+ data.push({"x": Number(network.channel) +8, "y": -100})
+ }
+ if (Number(network.bandwidth) == 80) {
+ data.push({"x": Number(network.channel) -16, "y": -100})
+ data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
+ data.push({"x": Number(network.channel) +16, "y": -100})
+ }
+ if (Number(network.bandwidth) == 160) {
+ data.push({"x": Number(network.channel) -32, "y": -100})
+ data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
+ data.push({"x": Number(network.channel) +32, "y": -100})
+ }
+ }
+
+ let ssid = network.ssid
+ if ( ssid == "") {
+ ssid = " "
+ }
+ return series.push({
+ name: ssid,
+ data: data
+ })
+ })
+ return series;
+ }
+
+ const useChartOptions = () => {
+ const theme = useTheme();
+
+ return {
+ chart: {
+ background: 'transparent',
+ stacked: false,
+ toolbar: {
+ show: true
+ },
+ zoom: {
+ enabled: false
+ },
+ },
+ title: {
+ text: 'Site Survey Results',
+ },
+ // markers: {
+ // size: 5,
+ // hover: {
+ // size: 9
+ // }
+ // },
+ colors: [
+ theme.palette.graphics.dark,
+ theme.palette.warning.main,
+ theme.palette.graphics.darkest,
+ theme.palette.graphics.main,
+ theme.palette.info.light,
+ theme.palette.graphics.lightest,
+ theme.palette.primary.main,
+ theme.palette.graphics.light,
+ theme.palette.error.light,
+ theme.palette.error.dark
+ ],
+ dataLabels: {
+ enabled: false
+ },
+ grid: {
+ //borderColor: theme.palette.divider,
+ strokeDashArray: 2,
+ xaxis: {
+ lines: {
+ show: true
+ }
+ },
+ yaxis: {
+ lines: {
+ show: true
+ },
+ },
+ },
+ legend: {
+ show: true,
+ showForSingleSeries: true,
+ },
+ plotOptions: {
+ area: {
+ fillTo: 'end',
+ }
+ },
+ stroke: {
+ show: true,
+ curve: 'smooth',
+ lineCap: 'round',
+ },
+ theme: {
+ mode: theme.palette.mode
+ },
+ yaxis: {
+ min: -100,
+ max: 0,
+ labels: {
+ formatter: function (value) {
+ return value + ' dBm';
+ },
+ //offsetY: -10,
+ style: {
+ //colors: theme.palette.text.secondary
+ }
+ },
+ },
+ // annotations: {
+ // xaxis: [
+ // {
+ // x: 9,
+ // x2: 10,
+ // borderColor: '#0b54ff',
+ // label: {
+ // style: {
+ // color: 'black',
+ // },
+ // text: 'Channel 10',
+ // offsetX: 45,
+ // borderColor: 'transparent',
+ // style: {
+ // background: 'transparent',
+ // color: theme.palette.text.secondary,
+ // fontSize: '17px',
+ // },
+ // }
+ // }
+ // ]
+ // },
+ // annotations: {
+ // points: [{
+ // x: 9,
+ // y: -5,
+ // label: {
+ // borderColor: '#775DD0',
+ // offsetY: 0,
+ // style: {
+ // color: '#fff',
+ // background: '#775DD0',
+ // },
+ // rotate: -45,
+ // text: 'Bananas are good',
+ // }
+ // }]
+ // },
+ xaxis: {
+ // tickPlacement: 'on',
+ // tickAmount: getChannelAmount(),
+ tickPlacement: 'on',
+ labels: {
+ show: true,
+ style: {
+ //colors: theme.palette.text.secondary
+ },
+ trim: true,
+ },
+ // max: getMaxChannel(),
+ // min: geMinChannel(),
+ // stepSize: getChannelSpacing(),
+ //type: 'category',
+ //categories: [getCategories()],
+ type: 'numeric',
+ decimalsInFloat: 0,
+ },
+ tooltip: {
+ x: {
+ show: true,
+ formatter: (seriesName) => "Channel "+ seriesName,
+ },
+ followCursor: false,
+ intersect: false,
+ shared: true,
+ enabled: true,
+ onDatasetHover: {
+ highlightDataSeries: true,
+ }
+ }
+ };
+ };
const chartOptions = useChartOptions();
@@ -181,23 +324,30 @@ export const SiteSurvey = (props) => {
- {
+ setView(value)
+ }}
>
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
{
-
+ {view == "list" &&
@@ -273,31 +423,18 @@ export const SiteSurvey = (props) => {
- {/*
-
-
-
-
-
-
-
- } label="2.4GHz" />
- } label="5GHz" />
-
-
-
- */}
-
+ }
+ {view == "chart" &&
+
+
+
+ }
: }
);
diff --git a/frontend/src/sections/overview/overview-tasks-progress.js b/frontend/src/sections/overview/overview-tasks-progress.js
index da8beaf..bfb3c0f 100644
--- a/frontend/src/sections/overview/overview-tasks-progress.js
+++ b/frontend/src/sections/overview/overview-tasks-progress.js
@@ -97,7 +97,7 @@ const showIcon = (mtpType) => {
{
}
else{
options.colors = [
- theme.palette.primary.main,
theme.palette.info.main,
theme.palette.warning.main,
theme.palette.graphics.lightest,
diff --git a/frontend/src/theme/colors.js b/frontend/src/theme/colors.js
index 74ef40e..7d6589e 100644
--- a/frontend/src/theme/colors.js
+++ b/frontend/src/theme/colors.js
@@ -1,5 +1,5 @@
import { alpha } from '@mui/material/styles';
-
+
const withAlphas = (color) => {
return {
...color,
@@ -11,8 +11,16 @@ const withAlphas = (color) => {
};
};
-export const neutral = {
- 50: '#306d6f',
+export const neutral = (colors) => {
+ console.log("neutral colors:", colors);
+ let parsedColors = JSON.parse(colors);
+
+ let tableColor = parsedColors["tables"]
+ let sidebarColorInitial = parsedColors["sidebar_initial"]
+ let wordsOutsideSidebarColor = parsedColors["words_outside_sidebar"]
+
+ return {
+ 50: tableColor,
100: '#F3F4F6',
200: '#E5E7EB',
300: '#D2D6DB',
@@ -20,18 +28,29 @@ export const neutral = {
500: '#6C737F',
600: '#4D5761',
700: '#FFFFFF',
- 800: '#306d6f',
- 900: '#30596f'
+ 800: sidebarColorInitial,
+ 900: wordsOutsideSidebarColor,
+}
};
-export const indigo = withAlphas({
- lightest: '#FFFFFF',
- light: '#306D6F',
- main: '#306D6F',
- dark: '#255355',
- darkest: '#00a0b8',
- contrastText: '#FFFFFF'
-});
+export const indigo = (colors) => {
+
+ console.log("indigo colors:", colors);
+ let parsedColors = JSON.parse(colors);
+
+ let buttonColor = parsedColors["buttons"]
+ let sidebarColorEnd = parsedColors["sidebar_end"]
+ let mtpsColor = parsedColors["connected_mtps_color"]
+
+ return withAlphas({
+ lightest: '#FFFFFF',
+ light: '#ff3383',
+ main: buttonColor,
+ dark: sidebarColorEnd,
+ darkest: mtpsColor,
+ contrastText: '#FFFFFF'
+ });
+}
export const success = withAlphas({
lightest: '#F0FDF9',
diff --git a/frontend/src/theme/create-palette.js b/frontend/src/theme/create-palette.js
index 43e67f4..7768322 100644
--- a/frontend/src/theme/create-palette.js
+++ b/frontend/src/theme/create-palette.js
@@ -2,15 +2,62 @@ import { common } from '@mui/material/colors';
import { alpha } from '@mui/material/styles';
import { error, indigo, info, neutral, success, warning, graphics } from './colors';
+const getColorScheme = async () => {
+
+ let result = await fetch('http://localhost/custom-frontend/colors').catch((error) => {
+ console.log('Error fetching colors');
+ sessionStorage.setItem('colors', JSON.stringify({
+ "buttons": "#306d6f",
+ "sidebar_end": "#306d6f",
+ "sidebar_initial": "#306d6f",
+ "tables": "#306d6f",
+ "words_outside_sidebar": "#30596f",
+ "connected_mtps_color": "#f28950"
+ }));
+ location.reload();
+ return
+ });
+ if (result.status!=200) {
+ console.log('Error fetching colors');
+ sessionStorage.setItem('colors', JSON.stringify({
+ "buttons": "#306d6f",
+ "sidebar_end": "#306d6f",
+ "sidebar_initial": "#306d6f",
+ "tables": "#306d6f",
+ "words_outside_sidebar": "#30596f",
+ "connected_mtps_color": "#f28950"
+ }));
+ location.reload();
+ return
+ }
+
+ let response = await result.json();
+ let fmtresponse = JSON.stringify(response);
+ sessionStorage.setItem('colors', fmtresponse);
+ location.reload();
+}
+
export function createPalette() {
- return {
+
+ let colors = sessionStorage.getItem('colors');
+
+ if (colors !== null) {
+ console.log('colors already fetched');
+ } else {
+ getColorScheme();
+ }
+ console.log("colors scheme:", colors);
+
+ let neutralColors = neutral(colors);
+
+ return {
action: {
- active: neutral[500],
- disabled: alpha(neutral[900], 0.38),
- disabledBackground: alpha(neutral[900], 0.12),
- focus: alpha(neutral[900], 0.16),
- hover: alpha(neutral[900], 0.04),
- selected: alpha(neutral[900], 0.12)
+ active: neutralColors[500],
+ disabled: alpha(neutralColors[900], 0.38),
+ disabledBackground: alpha(neutralColors[900], 0.12),
+ focus: alpha(neutralColors[900], 0.16),
+ hover: alpha(neutralColors[900], 0.04),
+ selected: alpha(neutralColors[900], 0.12)
},
background: {
default: common.white,
@@ -21,13 +68,13 @@ export function createPalette() {
graphics,
info,
mode: 'light',
- neutral,
- primary: indigo,
+ neutral: neutralColors,
+ primary: indigo(colors),
success,
text: {
- primary: neutral[900],
- secondary: neutral[500],
- disabled: alpha(neutral[900], 0.38)
+ primary: neutralColors[900],
+ secondary: neutralColors[500],
+ disabled: alpha(neutralColors[900], 0.38)
},
warning
};
diff --git a/frontend/src/utils/map.css b/frontend/src/utils/map.css
new file mode 100644
index 0000000..55a1725
--- /dev/null
+++ b/frontend/src/utils/map.css
@@ -0,0 +1,47 @@
+/* The location pointed to by the popup tip. */
+.popup-tip-anchor {
+ height: 0;
+ position: absolute;
+ /* The max width of the info window. */
+ width: 200px;
+ }
+ /* The bubble is anchored above the tip. */
+ .popup-bubble-anchor {
+ position: absolute;
+ width: 100%;
+ bottom: /* TIP_HEIGHT= */ 8px;
+ left: 0;
+ }
+ /* Draw the tip. */
+ .popup-bubble-anchor::after {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ /* Center the tip horizontally. */
+ transform: translate(-50%, 0);
+ /* The tip is a https://css-tricks.com/snippets/css/css-triangle/ */
+ width: 0;
+ height: 0;
+ /* The tip is 8px high, and 12px wide. */
+ border-left: 6px solid transparent;
+ border-right: 6px solid transparent;
+ border-top: /* TIP_HEIGHT= */ 8px solid white;
+ }
+ /* The popup bubble itself. */
+ .popup-bubble-content {
+ position: absolute;
+ top: 0;
+ left: 0;
+ transform: translate(-50%, -100%);
+ /* Style the info window. */
+ background-color: white;
+ padding: 5px;
+ border-radius: 5px;
+ font-family: sans-serif;
+ font-size: 14px ;
+ overflow-y: auto;
+ max-height: 80px;
+ box-shadow: 0px 2px 10px 1px rgba(0, 0, 0, 0.5);
+ }
+
\ No newline at end of file