Merge pull request #306 from OktopUSP/dev

Nginx + Admin Initial User
This commit is contained in:
Leandro Antônio Farias Machado 2024-07-03 09:41:46 -03:00 committed by GitHub
commit 1a85da603c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
43 changed files with 544 additions and 209 deletions

View File

@ -58,7 +58,7 @@ user@user-laptop:~$ cd oktopus/deploy/compose
user@user-laptop:~/oktopus/deploy/compose$ COMPOSE_PROFILES=nats,controller,cwmp,mqtt,stomp,ws,adapter,frontend,portainer docker compose up -d
</pre>
Oktopus deployment in <u><b>Kubernetes</b></u> still is in beta phase: <a href="https://github.com/OktopUSP/oktopus/blob/main/deploy/kubernetes/README.md"> Instructions for Kubernetes deployment</a><p></p>
UI will open at port 3000:
UI will open at port 80:
<img src="https://github.com/OktopUSP/oktopus/assets/83298718/65f7c5b9-c08d-479a-8a13-fdfc634b5ca2"/><br/><br/>
<h1>Agent</h1>

View File

@ -73,6 +73,8 @@ func NewConfig() *Config {
ctx := context.TODO()
log.Printf("Connection Request User: %q and Password: %q", *connReqUser, *connReqPasswd)
return &Config{
Nats: Nats{
Url: *natsUrl,

View File

@ -116,7 +116,7 @@ func (h *Handler) CwmpHandler(w http.ResponseWriter, r *http.Request) {
} else if e.KindOf() == "SetParameterValuesResponse" {
log.Println("Receive SetParameterValuesResponse from CPE:", cpe.SerialNumber)
msgAnswer(cpe.Waiting.Callback, cpe.Waiting.Time, h.acsConfig.DeviceAnswerTimeout, tmp)
}else if e.KindOf() == "Fault" {
} else if e.KindOf() == "Fault" {
log.Println("Receive FaultResponse from CPE:", cpe.SerialNumber)
msgAnswer(cpe.Waiting.Callback, cpe.Waiting.Time, h.acsConfig.DeviceAnswerTimeout, tmp)
log.Println(body)
@ -156,9 +156,11 @@ func (h *Handler) ConnectionRequest(cpe CPE) error {
ok, err := auth.Auth(h.acsConfig.ConnReqUsername, h.acsConfig.ConnReqPassword, cpe.ConnectionRequestURL)
if !ok {
cpe.Queue.Dequeue()
log.Println("Error while authenticating to CPE: ", err)
log.Println("Error while authenticating to CPE, err:", err)
} else {
log.Println("<-- Successfully authenticated to CPE", cpe.SerialNumber)
}
log.Println("<-- Successfully authenticated to CPE", cpe.SerialNumber)
return err
}

View File

@ -24,16 +24,11 @@ type Api struct {
db db.Database
kv jetstream.KeyValue
ctx context.Context
enterpise bool
enterpise config.Enterprise
}
const REQUEST_TIMEOUT = time.Second * 30
const (
NormalUser = iota
AdminUser
)
func NewApi(c *config.Config, js jetstream.JetStream, nc *nats.Conn, bridge bridge.Bridge, d db.Database, kv jetstream.KeyValue) Api {
return Api{
port: c.RestApi.Port,
@ -48,6 +43,11 @@ func NewApi(c *config.Config, js jetstream.JetStream, nc *nats.Conn, bridge brid
}
func (a *Api) StartApi() {
if a.enterpise.SupportPassword != "" && a.enterpise.SupportEmail != "" {
go registerEnterpriseSupport(a.enterpise.SupportEmail, a.enterpise.SupportPassword, a.db)
}
r := mux.NewRouter()
authentication := r.PathPrefix("/api/auth").Subrouter()
authentication.HandleFunc("/login", a.generateToken).Methods("PUT")
@ -77,7 +77,7 @@ func (a *Api) StartApi() {
iot.HandleFunc("/{sn}/{mtp}/instances", a.deviceGetParameterInstances).Methods("PUT")
iot.HandleFunc("/{sn}/{mtp}/operate", a.deviceOperateMsg).Methods("PUT")
iot.HandleFunc("/{sn}/{mtp}/fw_update", a.deviceFwUpdate).Methods("PUT") //TODO: put it to work and generalize for usp and cwmp
if a.enterpise {
if a.enterpise.Enable {
iot.HandleFunc("/{sn}/sitesurvey", a.deviceSiteSurvey).Methods("GET")
iot.HandleFunc("/{sn}/connecteddevices", a.deviceConnectedDevices).Methods("GET")
iot.HandleFunc("/{sn}/traceroute", a.deviceTraceRoute).Methods("GET", "PUT")
@ -124,3 +124,32 @@ func (a *Api) StartApi() {
}()
log.Println("Running REST API at port", a.port)
}
func registerEnterpriseSupport(email, password string, d db.Database) {
user := db.User{
Email: email,
Password: password,
Name: "Enterprise Support",
Level: db.AdminUser,
}
for {
if err := user.HashPassword(password); err != nil {
return
}
err := d.RegisterUser(user)
if err != nil {
if err == db.ErrorUserExists {
log.Println("Enterprise support user already registered.")
return
}
log.Println("Error to register enterprise support user:", err)
time.Sleep(time.Second * 5)
continue
}
log.Println("Enterprise support user registered successfully.")
return
}
}

View File

@ -8,6 +8,7 @@ import (
"strconv"
"github.com/leandrofars/oktopus/internal/bridge"
"github.com/leandrofars/oktopus/internal/db"
local "github.com/leandrofars/oktopus/internal/nats"
"github.com/leandrofars/oktopus/internal/utils"
"github.com/nats-io/nats.go/jetstream"
@ -134,7 +135,7 @@ func (a *Api) deviceAuth(w http.ResponseWriter, r *http.Request) {
utils.MarshallEncoder(err, w)
return
}
if user.Level != AdminUser {
if user.Level != db.AdminUser {
w.WriteHeader(http.StatusForbidden)
return
}

View File

@ -51,7 +51,7 @@ func (a *Api) registerUser(w http.ResponseWriter, r *http.Request) {
//Check if user which is requesting creation has the necessary privileges
rUser, err := a.db.FindUser(email)
if rUser.Level != AdminUser {
if rUser.Level != db.AdminUser {
w.WriteHeader(http.StatusForbidden)
return
}
@ -63,7 +63,7 @@ func (a *Api) registerUser(w http.ResponseWriter, r *http.Request) {
return
}
user.Level = NormalUser
user.Level = db.NormalUser
if err := user.HashPassword(user.Password); err != nil {
w.WriteHeader(http.StatusInternalServerError)
@ -112,7 +112,7 @@ func (a *Api) deleteUser(w http.ResponseWriter, r *http.Request) {
userEmail := mux.Vars(r)["user"]
if rUser.Email == userEmail || (rUser.Level == AdminUser && rUser.Email != userEmail) { //Admin can delete any account, but admin account can never be deleted
if rUser.Email == userEmail || (rUser.Level == db.AdminUser) { //Admin can delete any account
if err := a.db.DeleteUser(userEmail); err != nil {
w.WriteHeader(http.StatusInternalServerError)
json.NewEncoder(w).Encode(err)
@ -138,7 +138,7 @@ func (a *Api) changePassword(w http.ResponseWriter, r *http.Request) {
userToChangePasswd := mux.Vars(r)["user"]
if userToChangePasswd != "" && userToChangePasswd != email {
rUser, _ := a.db.FindUser(email)
if rUser.Level != AdminUser {
if rUser.Level != db.AdminUser {
w.WriteHeader(http.StatusForbidden)
return
}
@ -168,28 +168,61 @@ func (a *Api) changePassword(w http.ResponseWriter, r *http.Request) {
func (a *Api) registerAdminUser(w http.ResponseWriter, r *http.Request) {
tokenString := r.Header.Get("Authorization")
if tokenString == "" {
users, err := a.db.FindAllUsers()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
utils.MarshallEncoder(err, w)
}
if !adminUserExists(users, a.enterpise.SupportEmail) {
var user db.User
err = json.NewDecoder(r.Body).Decode(&user)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
user.Level = db.AdminUser
if err := user.HashPassword(user.Password); err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
if err := a.db.RegisterUser(user); err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
} else {
w.WriteHeader(http.StatusForbidden)
}
return
}
email, err := auth.ValidateToken(tokenString)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
return
}
//Check if user which is requesting creation has the necessary privileges
rUser, err := a.db.FindUser(email)
if rUser.Level != db.AdminUser {
w.WriteHeader(http.StatusForbidden)
return
}
var user db.User
err := json.NewDecoder(r.Body).Decode(&user)
err = json.NewDecoder(r.Body).Decode(&user)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
users, err := a.db.FindAllUsers()
if err != nil {
log.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
adminExists := adminUserExists(users)
if adminExists {
log.Println("There might exist only one admin")
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode("There might exist only one admin")
return
}
user.Level = AdminUser
user.Level = db.AdminUser
if err := user.HashPassword(user.Password); err != nil {
w.WriteHeader(http.StatusInternalServerError)
@ -202,9 +235,14 @@ func (a *Api) registerAdminUser(w http.ResponseWriter, r *http.Request) {
}
}
func adminUserExists(users []map[string]interface{}) bool {
func adminUserExists(users []map[string]interface{}, supportEmail string) bool {
if len(users) == 0 {
return false
}
for _, x := range users {
if x["level"].(int32) == AdminUser {
if db.UserLevels(x["level"].(int32)) == db.AdminUser && x["email"].(string) != supportEmail {
log.Println("Admin exists")
return true
}
@ -220,7 +258,7 @@ func (a *Api) adminUserExists(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
return
}
adminExits := adminUserExists(users)
adminExits := adminUserExists(users, a.enterpise.SupportEmail)
json.NewEncoder(w).Encode(adminExits)
return
}

View File

@ -213,7 +213,7 @@ func (a *Api) deviceWifi(w http.ResponseWriter, r *http.Request) {
if device.Cwmp == entity.Online {
if a.enterpise {
if a.enterpise.Enable {
a.getEnterpriseResource("wifi", "get", device, sn, w, []byte{}, "cwmp", "098")
return
}
@ -347,7 +347,7 @@ func (a *Api) deviceWifi(w http.ResponseWriter, r *http.Request) {
if device.Cwmp == entity.Online {
if a.enterpise {
if a.enterpise.Enable {
payload, err := io.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)

View File

@ -29,11 +29,17 @@ type RestApi struct {
Ctx context.Context
}
type Enterprise struct {
Enable bool
SupportPassword string
SupportEmail string
}
type Config struct {
RestApi RestApi
Nats Nats
Mongo Mongo
Enterprise bool
Enterprise Enterprise
}
func NewConfig() *Config {
@ -47,6 +53,8 @@ func NewConfig() *Config {
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")
enterprise_support_password := flag.String("enterprise_support_password", lookupEnvOrString("ENTERPRISE_SUPPORT_PASSWORD", ""), "enterprise support password")
enterpise_support_email := flag.String("enterprise_support_email", lookupEnvOrString("ENTERPRISE_SUPPORT_EMAIL", ""), "enterprise support email")
flHelp := flag.Bool("help", false, "Help")
/*
@ -80,7 +88,11 @@ func NewConfig() *Config {
Uri: *mongoUri,
Ctx: ctx,
},
Enterprise: *enterpise,
Enterprise: Enterprise{
Enable: *enterpise,
SupportPassword: *enterprise_support_password,
SupportEmail: *enterpise_support_email,
},
}
}

View File

@ -9,12 +9,19 @@ import (
"golang.org/x/crypto/bcrypt"
)
type UserLevels int32
const (
NormalUser UserLevels = iota
AdminUser
)
type User struct {
Email string `json:"email"`
Name string `json:"name"`
Password string `json:"password,omitempty"`
Level int `json:"level"`
Phone string `json:"phone"`
Email string `json:"email"`
Name string `json:"name"`
Password string `json:"password,omitempty"`
Level UserLevels `json:"level"`
Phone string `json:"phone"`
}
var ErrorUserExists = errors.New("User already exists")

View File

@ -1,17 +0,0 @@
# ----------------------------- Local Environment ---------------------------- #
NEXT_PUBLIC_REST_ENDPOINT="http://localhost:8000/api"
NEXT_PUBLIC_WS_ENDPOINT="http://localhost:5000/"
# ---------------------------------------------------------------------------- #
# -------------------------- Production Environment -------------------------- #
#NEXT_PUBLIC_REST_ENPOINT="https://demo.oktopus.app.br/api"
#NEXT_PUBLIC_WS_ENPOINT="https://demo.oktopus.app.br/"
# ---------------------------------------------------------------------------- #
# ---------------------------- Mocked Environment ---------------------------- #
#NEXT_PUBLIC_REST_ENPOINT="https://d9962fd9-2464-4a30-9a86-a15a04b57ad0.mock.pstmn.io"
# ---------------------------------------------------------------------------- #

View File

@ -151,10 +151,8 @@ services:
#/* -------------------------------- Frontend -------------------------------- */
frontend:
image: 'oktopusp/frontend'
image: 'oktopusp/frontend-ce'
container_name: frontend
env_file:
- .env.frontend
ports:
- 3000:3000
networks:
@ -188,6 +186,21 @@ services:
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
networks:
usp_network:
ipv4_address: 172.16.235.17
networks:
usp_network:
driver: bridge

41
deploy/compose/nginx.conf Normal file
View File

@ -0,0 +1,41 @@
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
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_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;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}

1
deploy/compose/run.sh Normal file
View File

@ -0,0 +1 @@
COMPOSE_PROFILES=nats,controller,cwmp,mqtt,stomp,ws,adapter,frontend,portainer docker compose up -d

1
deploy/compose/stop.sh Normal file
View File

@ -0,0 +1 @@
COMPOSE_PROFILES=nats,controller,cwmp,mqtt,stomp,ws,adapter,frontend,portainer docker compose down

View File

@ -1,8 +1,9 @@
# ----------------------------- Local Environment ---------------------------- #
NEXT_PUBLIC_REST_ENDPOINT="http://localhost:8000/api"
NEXT_PUBLIC_REST_ENDPOINT="http://localhost:8000"
NEXT_PUBLIC_WS_ENDPOINT="http://localhost:5000/"
NEXT_PUBLIC_ENTERPRISE_VERSION="false"
NEXT_PUBLIC_GOOGLE_MAPS_KEY=""
# ---------------------------------------------------------------------------- #
# -------------------------- Production Environment -------------------------- #

View File

@ -1 +1,4 @@
.next/
../.next/
../node_modules/
../.env
../.env.local

View File

@ -1,29 +0,0 @@
FROM node:18.17.0-alpine as builder
WORKDIR /app
COPY ../ ./
RUN npm install
RUN NEXT_PUBLIC_REST_ENDPOINT=REST_API_URL NEXT_PUBLIC_WS_ENDPOINT=WS_URL NEXT_PUBLIC_ENTERPRISE_VERSION=ENTERPRISE_VERSION npm run build
RUN ls -la && echo "Listing directory contents done"
FROM node:18.17.0-alpine as runner
WORKDIR /app
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/build/entrypoint.sh ./entrypoint.sh
COPY --from=builder /app/public ./public
RUN npm install
RUN chmod 755 entrypoint.sh
ENTRYPOINT ["/app/entrypoint.sh"]
CMD [ "npm", "run", "start" ]

View File

@ -0,0 +1,22 @@
FROM node:18.18.0-alpine as builder
WORKDIR /app
COPY ../ ./
RUN rm .env && rm .env.local || true
RUN npm install
RUN NEXT_PUBLIC_ENTERPRISE_VERSION="false" npm run build
FROM node:18.18.0-alpine as runner
WORKDIR /app
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/public ./public
RUN npm install
CMD [ "npm", "run", "start" ]

View File

@ -0,0 +1,22 @@
FROM node:18.18.0-alpine as builder
WORKDIR /app
COPY ../ ./
RUN rm .env && rm .env.local || true
RUN npm install
RUN NEXT_PUBLIC_ENTERPRISE_VERSION="true" npm run build
FROM node:18.18.0-alpine as runner
WORKDIR /app
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/public ./public
RUN npm install
CMD [ "npm", "run", "start" ]

View File

@ -18,48 +18,16 @@ help:
@echo "Makefile commands:"
@echo ""
@echo "build - docker image build"
@echo "push - push docker image 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"
@echo "tag - tag image as latest"
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}
@docker build -t ${DOCKER_USER}/${DOCKER_APP}-ce:${DOCKER_TAG} -f Dockerfile.ce ../
@docker build -t ${DOCKER_USER}/${DOCKER_APP}-ee:${DOCKER_TAG} -f Dockerfile.ee ../
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
tag:
docker tag ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG} ${DOCKER_USER}/${DOCKER_APP}:latest
@docker push ${DOCKER_USER}/${DOCKER_APP}-ce:${DOCKER_TAG}
@docker push ${DOCKER_USER}/${DOCKER_APP}-ee:${DOCKER_TAG}
@docker tag ${DOCKER_USER}/${DOCKER_APP}-ce:${DOCKER_TAG} ${DOCKER_USER}/${DOCKER_APP}-ce:latest
@docker tag ${DOCKER_USER}/${DOCKER_APP}-ee:${DOCKER_TAG} ${DOCKER_USER}/${DOCKER_APP}-ee:latest
@docker push ${DOCKER_USER}/${DOCKER_APP}-ce:latest
@docker push ${DOCKER_USER}/${DOCKER_APP}-ee:latest

View File

@ -1,22 +0,0 @@
#!/usr/bin/env sh
set -Ex
function apply_path {
echo "Check that we have NEXT_PUBLIC_REST_ENDPOINT vars"
test -n "$NEXT_PUBLIC_REST_ENDPOINT"
echo "Check that we have NEXT_PUBLIC_WS_ENDPOINT vars"
test -n "$NEXT_PUBLIC_WS_ENDPOINT"
echo "Check that we have NEXT_PUBLIC_ENTERPRISE_VERSION vars"
test -n "$NEXT_PUBLIC_ENTERPRISE_VERSION"
find /app/.next \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s#REST_API_URL#$NEXT_PUBLIC_REST_ENDPOINT#g"
find /app/.next \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s#WS_URL#$NEXT_PUBLIC_WS_ENDPOINT#g"
find /app/.next \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s#ENTERPRISE_VERSION#$NEXT_PUBLIC_ENTERPRISE_VERSION#g"
}
apply_path
echo "Starting Nextjs"
exec "$@"

View File

@ -17,6 +17,7 @@
"@mui/material": "5.11.10",
"@mui/system": "5.11.9",
"@mui/x-date-pickers": "5.0.19",
"@react-google-maps/api": "^2.19.3",
"apexcharts": "3.37.0",
"date-fns": "2.29.3",
"formik": "2.2.9",
@ -499,6 +500,23 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@googlemaps/js-api-loader": {
"version": "1.16.2",
"resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.2.tgz",
"integrity": "sha512-psGw5u0QM6humao48Hn4lrChOM2/rA43ZCm3tKK9qQsEj1/VzqkCqnvGfEOshDbBQflydfaRovbKwZMF4AyqbA==",
"dependencies": {
"fast-deep-equal": "^3.1.3"
}
},
"node_modules/@googlemaps/markerclusterer": {
"version": "2.5.3",
"resolved": "https://registry.npmjs.org/@googlemaps/markerclusterer/-/markerclusterer-2.5.3.tgz",
"integrity": "sha512-x7lX0R5yYOoiNectr10wLgCBasNcXFHiADIBdmn7jQllF2B5ENQw5XtZK+hIw4xnV0Df0xhN4LN98XqA5jaiOw==",
"dependencies": {
"fast-deep-equal": "^3.1.3",
"supercluster": "^8.0.1"
}
},
"node_modules/@heroicons/react": {
"version": "2.0.16",
"resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.0.16.tgz",
@ -1215,6 +1233,33 @@
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@react-google-maps/api": {
"version": "2.19.3",
"resolved": "https://registry.npmjs.org/@react-google-maps/api/-/api-2.19.3.tgz",
"integrity": "sha512-jiLqvuOt5lOowkLeq7d077AByTyJp+s6hZVlLhlq7SBacBD37aUNpXBz2OsazfeR6Aw4a+9RRhAEjEFvrR1f5A==",
"dependencies": {
"@googlemaps/js-api-loader": "1.16.2",
"@googlemaps/markerclusterer": "2.5.3",
"@react-google-maps/infobox": "2.19.2",
"@react-google-maps/marker-clusterer": "2.19.2",
"@types/google.maps": "3.55.2",
"invariant": "2.2.4"
},
"peerDependencies": {
"react": "^16.8 || ^17 || ^18",
"react-dom": "^16.8 || ^17 || ^18"
}
},
"node_modules/@react-google-maps/infobox": {
"version": "2.19.2",
"resolved": "https://registry.npmjs.org/@react-google-maps/infobox/-/infobox-2.19.2.tgz",
"integrity": "sha512-6wvBqeJsQ/eFSvoxg+9VoncQvNoVCdmxzxRpLvmjPD+nNC6mHM0vJH1xSqaKijkMrfLJT0nfkTGpovrF896jwg=="
},
"node_modules/@react-google-maps/marker-clusterer": {
"version": "2.19.2",
"resolved": "https://registry.npmjs.org/@react-google-maps/marker-clusterer/-/marker-clusterer-2.19.2.tgz",
"integrity": "sha512-x9ibmsP0ZVqzyCo1Pitbw+4b6iEXRw/r1TCy3vOUR3eKrzWLnHYZMR325BkZW2r8fnuWE/V3Fp4QZOP9qYORCw=="
},
"node_modules/@rushstack/eslint-patch": {
"version": "1.10.3",
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz",
@ -1245,6 +1290,11 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
},
"node_modules/@types/google.maps": {
"version": "3.55.2",
"resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.55.2.tgz",
"integrity": "sha512-JcTwzkxskR8DN/nnX96Pie3gGN3WHiPpuxzuQ9z3516o1bB243d8w8DHUJ8BohuzoT1o3HUFta2ns/mkZC8KRw=="
},
"node_modules/@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@ -2981,8 +3031,7 @@
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"node_modules/fast-glob": {
"version": "3.3.2",
@ -3529,6 +3578,14 @@
"node": ">= 0.4"
}
},
"node_modules/invariant": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
"dependencies": {
"loose-envify": "^1.0.0"
}
},
"node_modules/is-array-buffer": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
@ -4018,6 +4075,11 @@
"node": ">=4.0"
}
},
"node_modules/kdbush": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz",
"integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA=="
},
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@ -5445,6 +5507,14 @@
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz",
"integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA=="
},
"node_modules/supercluster": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz",
"integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==",
"dependencies": {
"kdbush": "^4.0.2"
}
},
"node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@ -6440,6 +6510,23 @@
}
}
},
"@googlemaps/js-api-loader": {
"version": "1.16.2",
"resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.2.tgz",
"integrity": "sha512-psGw5u0QM6humao48Hn4lrChOM2/rA43ZCm3tKK9qQsEj1/VzqkCqnvGfEOshDbBQflydfaRovbKwZMF4AyqbA==",
"requires": {
"fast-deep-equal": "^3.1.3"
}
},
"@googlemaps/markerclusterer": {
"version": "2.5.3",
"resolved": "https://registry.npmjs.org/@googlemaps/markerclusterer/-/markerclusterer-2.5.3.tgz",
"integrity": "sha512-x7lX0R5yYOoiNectr10wLgCBasNcXFHiADIBdmn7jQllF2B5ENQw5XtZK+hIw4xnV0Df0xhN4LN98XqA5jaiOw==",
"requires": {
"fast-deep-equal": "^3.1.3",
"supercluster": "^8.0.1"
}
},
"@heroicons/react": {
"version": "2.0.16",
"resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.0.16.tgz",
@ -6818,6 +6905,29 @@
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A=="
},
"@react-google-maps/api": {
"version": "2.19.3",
"resolved": "https://registry.npmjs.org/@react-google-maps/api/-/api-2.19.3.tgz",
"integrity": "sha512-jiLqvuOt5lOowkLeq7d077AByTyJp+s6hZVlLhlq7SBacBD37aUNpXBz2OsazfeR6Aw4a+9RRhAEjEFvrR1f5A==",
"requires": {
"@googlemaps/js-api-loader": "1.16.2",
"@googlemaps/markerclusterer": "2.5.3",
"@react-google-maps/infobox": "2.19.2",
"@react-google-maps/marker-clusterer": "2.19.2",
"@types/google.maps": "3.55.2",
"invariant": "2.2.4"
}
},
"@react-google-maps/infobox": {
"version": "2.19.2",
"resolved": "https://registry.npmjs.org/@react-google-maps/infobox/-/infobox-2.19.2.tgz",
"integrity": "sha512-6wvBqeJsQ/eFSvoxg+9VoncQvNoVCdmxzxRpLvmjPD+nNC6mHM0vJH1xSqaKijkMrfLJT0nfkTGpovrF896jwg=="
},
"@react-google-maps/marker-clusterer": {
"version": "2.19.2",
"resolved": "https://registry.npmjs.org/@react-google-maps/marker-clusterer/-/marker-clusterer-2.19.2.tgz",
"integrity": "sha512-x9ibmsP0ZVqzyCo1Pitbw+4b6iEXRw/r1TCy3vOUR3eKrzWLnHYZMR325BkZW2r8fnuWE/V3Fp4QZOP9qYORCw=="
},
"@rushstack/eslint-patch": {
"version": "1.10.3",
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz",
@ -6850,6 +6960,11 @@
}
}
},
"@types/google.maps": {
"version": "3.55.2",
"resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.55.2.tgz",
"integrity": "sha512-JcTwzkxskR8DN/nnX96Pie3gGN3WHiPpuxzuQ9z3516o1bB243d8w8DHUJ8BohuzoT1o3HUFta2ns/mkZC8KRw=="
},
"@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@ -8149,8 +8264,7 @@
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"fast-glob": {
"version": "3.3.2",
@ -8547,6 +8661,14 @@
"side-channel": "^1.0.4"
}
},
"invariant": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
"requires": {
"loose-envify": "^1.0.0"
}
},
"is-array-buffer": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
@ -8874,6 +8996,11 @@
"object.values": "^1.1.6"
}
},
"kdbush": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz",
"integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA=="
},
"keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@ -9849,6 +9976,14 @@
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz",
"integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA=="
},
"supercluster": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz",
"integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==",
"requires": {
"kdbush": "^4.0.2"
}
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",

View File

@ -23,6 +23,7 @@
"@mui/material": "5.11.10",
"@mui/system": "5.11.9",
"@mui/x-date-pickers": "5.0.19",
"@react-google-maps/api": "^2.19.3",
"apexcharts": "3.37.0",
"date-fns": "2.29.3",
"formik": "2.2.9",

View File

@ -150,7 +150,7 @@ export const AuthProvider = (props) => {
redirect: 'follow'
};
let result = await fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+"/auth/login", requestOptions)
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/auth/login`, requestOptions)
if (result.status != 200) {
throw new Error('Please check your email and password');
@ -199,7 +199,7 @@ export const AuthProvider = (props) => {
redirect: 'follow'
};
let result = await fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+"/auth/admin/register", requestOptions)
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/auth/admin/register`, requestOptions)
if (result.status == 200) {
router.push("/auth/login")

View File

@ -42,7 +42,7 @@ export const items = [
// <SvgIcon fontSize="small">
// <MapIcon/>
// </SvgIcon>
// )
// ),
// },
{
title: 'Credentials',

View File

@ -49,12 +49,11 @@ export const Layout = withAuthGuard((props) => {
return (
<>
<TopNav onNavOpen={() => setOpenNav(true)} />
{pathname != "/map" && <TopNav onNavOpen={() => setOpenNav(true)} />}
<SideNav
onClose={() => setOpenNav(false)}
open={openNav}
/>
<LayoutRoot>
<LayoutContainer>
{children}

View File

@ -83,7 +83,7 @@ const Page = () => {
redirect: 'follow',
};
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/auth/admin/exists`, requestOptions))
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/auth/admin/exists`, requestOptions))
let content = await result.json()
console.log("content: ", content)
if (result.status != 200) {
@ -131,12 +131,12 @@ const Page = () => {
<Typography variant="h4">
Login
</Typography>
<Typography
{!(process.env.NEXT_PUBLIC_ENTERPRISE_VERSION == "true") && <Typography
color="text.secondary"
variant="body2"
>
This project is open source, reach out at <Link href='https://github.com/OktopUSP/oktopus'>Github</Link> or <Link href='https://join.slack.com/t/oktopustr-369/shared_invite/zt-1znmrbr52-3AXgOlSeQTPQW8_Qhn3C4g'>Slack</Link>
</Typography>
</Typography>}
</Stack>
{/*<Tabs
onChange={handleMethodChange}

View File

@ -35,7 +35,7 @@ const Page = () => {
redirect: 'follow'
};
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/users`,requestOptions)
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/users`,requestOptions)
.then(response => response.json())
.then(result => {
// let teste = JSON.stringify(JSON.parse(result), null, 2)

View File

@ -49,7 +49,7 @@ const Page = () => {
redirect: 'follow'
}
return fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT + '/device/auth?id='+id, requestOptions)
return fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/auth?id=${id}`, requestOptions)
.then(response => {
if (response.status === 401) {
router.push("/auth/login")
@ -81,7 +81,7 @@ const Page = () => {
redirect: 'follow'
};
let result = await fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+"/device/auth", requestOptions)
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/auth`, requestOptions)
if (result.status == 200) {
console.log("user created: deu boa raça !!")
@ -134,7 +134,7 @@ const Page = () => {
redirect: 'follow'
}
let url = process.env.NEXT_PUBLIC_REST_ENDPOINT + '/device/auth'
let url = `${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/auth`
if (id !== undefined && id !== "") {
url += "?id="+id
}
@ -224,7 +224,7 @@ const Page = () => {
<OutlinedInput
defaultValue=""
fullWidth
placeholder="Search customer"
placeholder="Search credentials by username"
onKeyDownCapture={(e) => {
if (e.key === 'Enter') {
console.log("Fetch credentials per username: ", e.target.value)

View File

@ -46,7 +46,7 @@ const Page = () => {
redirect: 'follow'
}
fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+'/device', requestOptions)
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device`, requestOptions)
.then(response => {
if (response.status === 401)
router.push("/auth/login")
@ -86,7 +86,7 @@ const Page = () => {
p = p - 1
p = p.toString()
fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+'/device?page_number='+p, requestOptions)
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device?page_number=+${p}`, requestOptions)
.then(response => {
if (response.status === 401)
router.push("/auth/login")
@ -116,7 +116,7 @@ const Page = () => {
}
if (id == ""){
return fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+'/device', requestOptions)
return fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device`, requestOptions)
.then(response => {
if (response.status === 401)
router.push("/auth/login")
@ -134,7 +134,7 @@ const Page = () => {
});
}
let response = await fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+'/device?id='+id, requestOptions)
let response = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device?id=${id}`, requestOptions)
if (response.status === 401)
router.push("/auth/login")
let json = await response.json()

View File

@ -38,7 +38,7 @@ const Page = () => {
redirect: 'follow',
};
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/info/general`, requestOptions))
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/info/general`, requestOptions))
if (result.status === 401){
router.push("/auth/login")
}else if (result.status != 200){

86
frontend/src/pages/map.js Normal file
View File

@ -0,0 +1,86 @@
import Head from 'next/head';
import { GoogleMap, useLoadScript } 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';
const Page = () => {
const libraries = useMemo(() => ['places'], []);
const [mapCenter, setMapCenter] = useState(null);
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.");
}
},[])
const mapOptions = useMemo(
() => ({
disableDefaultUI: false,
clickableIcons: true,
zoomControl: true,
controlSize: 23,
styles: mapStyles,
mapTypeControlOptions: {
mapTypeIds: ['roadmap', 'satellite'],
}
}),
[]
);
const { isLoaded } = useLoadScript({
googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_KEY,
libraries: libraries,
});
if (!isLoaded) {
return <p>Loading...</p>;
}
return ( mapCenter &&
<>
<Head>
<title>
Maps | Oktopus
</title>
</Head>
<GoogleMap
options={mapOptions}
zoom={14}
center={mapCenter}
mapContainerStyle={{ width: '100%', height: '100%' }}
onLoad={() => console.log('Map Component Loaded...')}
clickableIcons={false}
/>
</>
)};
Page.getLayout = (page) => (
<DashboardLayout>
{page}
</DashboardLayout>
);
export default Page;

View File

@ -8,7 +8,7 @@ const Page = () => (
<>
<Head>
<title>
Settings | Devias Kit
Settings | Oktopus
</title>
</Head>
<Box

View File

@ -55,7 +55,7 @@ const Page = () => {
redirect: 'follow'
}
return fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT + '/auth/delete/' + id, requestOptions)
return fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/auth/delete/${id}`, requestOptions)
.then(response => {
if (response.status === 401) {
router.push("/auth/login")
@ -82,7 +82,7 @@ const Page = () => {
redirect: 'follow'
}
return fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT + '/users', requestOptions)
return fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/users`, requestOptions)
.then(response => {
if (response.status === 401) {
router.push("/auth/login")
@ -142,7 +142,7 @@ const Page = () => {
redirect: 'follow'
};
let result = await fetch(process.env.NEXT_PUBLIC_REST_ENDPOINT+"/auth/register", requestOptions)
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/auth/register`, requestOptions)
if (result.status == 200) {
console.log("user created: deu boa raça !!")

View File

@ -28,7 +28,7 @@ export const ConnectedDevices = () => {
redirect: 'follow'
};
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/connecteddevices`, requestOptions)
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")

View File

@ -65,7 +65,7 @@ export const DevicesDiagnostic = () => {
redirect: 'follow'
};
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/ping`, requestOptions)
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/ping`, requestOptions)
.then(response => {
if (response.status === 401) {
router.push("/auth/login")
@ -95,7 +95,7 @@ export const DevicesDiagnostic = () => {
body: JSON.stringify(content)
};
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/ping`, requestOptions)
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/ping`, requestOptions)
.then(response => {
if (response.status === 401) {
router.push("/auth/login")

View File

@ -110,7 +110,7 @@ const handleOpen = () => {
}
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/cwmp/${router.query.id[0]}/${method}`, requestOptions)
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/cwmp/${router.query.id[0]}/${method}`, requestOptions)
.then(response => response.text())
.then(result => {
if (result.status === 401){

View File

@ -59,7 +59,7 @@ export const DevicesWiFi = () => {
redirect: 'follow'
};
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/wifi`, requestOptions)
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")
@ -197,7 +197,7 @@ export const DevicesWiFi = () => {
body: data,
redirect: 'follow'
};
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/wifi`, requestOptions)
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")

View File

@ -153,7 +153,7 @@ export const SiteSurvey = (props) => {
redirect: 'follow'
};
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/sitesurvey`, requestOptions)
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/sitesurvey`, requestOptions)
.then(response => {
if (response.status === 401) {
router.push("/auth/login")

View File

@ -96,7 +96,7 @@ const addDeviceObj = async(obj, setShowLoading, router, updateDeviceParameters)
body: raw
};
setShowLoading(true)
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/add`, requestOptions))
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/any/add`, requestOptions))
if (result.status != 200) {
if (result.status === 401){
router.push("/auth/login")
@ -131,7 +131,7 @@ const deleteDeviceObj = async(obj, setShowLoading, router, updateDeviceParameter
body: raw
};
setShowLoading(true)
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/del`, requestOptions))
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/any/del`, requestOptions))
if (result.status != 200) {
if (result.status === 401){
router.push("/auth/login")
@ -481,7 +481,7 @@ const getDeviceParameters = async (raw) =>{
body: raw
};
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/parameters`, requestOptions))
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/any/parameters`, requestOptions))
if (result.status != 200) {
if (result.status === 401){
router.push("/auth/login")
@ -505,7 +505,7 @@ const getDeviceParameterInstances = async (raw) =>{
body: raw
};
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/instances`, requestOptions))
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/any/instances`, requestOptions))
if (result.status != 200) {
throw new Error('Please check your email and password');
}else if (result.status === 401){
@ -779,7 +779,7 @@ const getDeviceParameterInstances = async (raw) =>{
body: raw
};
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/get`, requestOptions))
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/any/get`, requestOptions))
if (result.status != 200) {
if (result.status === 401){
router.push("/auth/login")
@ -1029,7 +1029,7 @@ const getDeviceParameterInstances = async (raw) =>{
setOpen(false)
setShowLoading(true)
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/set`, requestOptions))
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/any/set`, requestOptions))
if (result.status != 200) {
if (result.status === 401){
router.push("/auth/login")
@ -1172,7 +1172,7 @@ const getDeviceParameterInstances = async (raw) =>{
body: raw
};
setShowLoading(true)
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/operate`, requestOptions)
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/any/operate`, requestOptions)
let content = await result.json()
if (result.status != 200) {
setShowLoading(false)

View File

@ -84,7 +84,7 @@ const handleOpen = () => {
}
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/${method}`, requestOptions)
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/any/${method}`, requestOptions)
.then(response => response.text())
.then(result => {
if (result.status === 401){

View File

@ -76,7 +76,7 @@ export const OverviewLatestOrders = (props) => {
redirect: 'follow'
};
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/alias?id=${sn}`, requestOptions)
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/alias?id=${sn}`, requestOptions)
console.log("result:", result)
if (result.status === 401){
router.push("/auth/login")
@ -199,13 +199,6 @@ export const OverviewLatestOrders = (props) => {
setDeviceAlias(order.Alias)
setShowSetDeviceAlias(true)
}}
onKeyDown={e => {
if (e.key === 'Enter') {
setDeviceToBeChanged(index)
setDeviceAlias(order.Alias)
setShowSetDeviceAlias(true)
}
}}
>
<SvgIcon
fontSize="small"
@ -239,10 +232,16 @@ export const OverviewLatestOrders = (props) => {
</Button>
</CardActions>*/}
</Card>
{showSetDeviceAlias&&
<Dialog open={showSetDeviceAlias}>
<DialogContent>
<InputLabel>Device Alias</InputLabel>
<Input value={deviceAlias} onChange={(e)=>{setDeviceAlias(e.target.value)}}>
<Input value={deviceAlias} onChange={(e)=>{setDeviceAlias(e.target.value)}}
onKeyUp={e => {
if (e.key === 'Enter') {
setNewDeviceAlias(deviceAlias, orders[deviceToBeChanged].SN)
}
}}>
</Input>
</DialogContent>
<DialogActions>
@ -255,7 +254,7 @@ export const OverviewLatestOrders = (props) => {
setNewDeviceAlias(deviceAlias, orders[deviceToBeChanged].SN)
}}>Save</Button>
</DialogActions>
</Dialog>
</Dialog>}
</div>
);
};

View File

@ -0,0 +1,20 @@
[
{
"featureType": "all",
"elementType": "labels.text",
"stylers": [
{
"visibility": "on"
}
]
},
{
"featureType": "poi",
"elementType": "labels.icon",
"stylers": [
{
"visibility": "off"
}
]
}
]