From 75933d7e59838f7c8728ca08cf39659f24a6cac6 Mon Sep 17 00:00:00 2001 From: Sambhav Saggi <17993169+9p4@users.noreply.github.com> Date: Tue, 31 May 2022 18:29:50 -0400 Subject: [PATCH 001/141] fix: disable authentication properly --- backend/app.js | 12 +- frontend/src/components/Bar/Bar.jsx | 116 +++++++++--------- .../HomeLoggedOut/HomeLoggedOut.jsx | 2 + frontend/src/utils/API.js | 9 +- 4 files changed, 74 insertions(+), 65 deletions(-) diff --git a/backend/app.js b/backend/app.js index b2a9eff..7f46dd3 100644 --- a/backend/app.js +++ b/backend/app.js @@ -18,11 +18,13 @@ const app = express(); app.use(logger("dev")); app.use(express.json()); app.use(express.urlencoded({ extended: false })); -app.use( - bearerToken({ - headerKey: "Bearer", - }) -); +if (process.env.ZU_DISABLE_AUTH === "true") { + app.use( + bearerToken({ + headerKey: "Bearer", + }) + ); +} if ( process.env.NODE_ENV === "production" && diff --git a/frontend/src/components/Bar/Bar.jsx b/frontend/src/components/Bar/Bar.jsx index 444a06f..aac68c6 100644 --- a/frontend/src/components/Bar/Bar.jsx +++ b/frontend/src/components/Bar/Bar.jsx @@ -21,6 +21,7 @@ import LogIn from "components/LogIn"; function Bar() { const [loggedIn, setLoggedIn] = useLocalStorage("loggedIn", false); + const [disabledAuth] = useLocalStorage("disableAuth", false); const [anchorEl, setAnchorEl] = useState(null); const history = useHistory(); @@ -46,7 +47,7 @@ function Bar() { // name: "Settings", // to: "/settings", // }, - { + !disabledAuth && { name: "Log out", divide: true, onClick: onLogOutClick, @@ -72,69 +73,70 @@ function Bar() { + {/* The filter removes all elements that are "true" or "false" */} + {loggedIn && + menuItems.filter((e) => typeof e !== "boolean").length > 0 && ( + <> + - {loggedIn && ( - <> - + + {menuItems.map((menuItem, index) => { + if ( + menuItem.hasOwnProperty("condition") && + !menuItem.condition + ) { + return null; + } - - {menuItems.map((menuItem, index) => { - if ( - menuItem.hasOwnProperty("condition") && - !menuItem.condition - ) { - return null; - } + let component = null; - let component = null; + if (menuItem.to) { + component = ( + + {menuItem.name} + + ); + } else { + component = ( + { + closeMenu(); - if (menuItem.to) { - component = ( - - {menuItem.name} - - ); - } else { - component = ( - { - closeMenu(); + menuItem.onClick(); + }} + > + {menuItem.name} + + ); + } - menuItem.onClick(); - }} - > - {menuItem.name} - - ); - } + if (menuItem.divide) { + return ( + + - if (menuItem.divide) { - return ( - - + {component} + + ); + } - {component} - - ); - } - - return component; - })} - - - )} + return component; + })} + + + )} {!loggedIn && LogIn()} diff --git a/frontend/src/components/HomeLoggedOut/HomeLoggedOut.jsx b/frontend/src/components/HomeLoggedOut/HomeLoggedOut.jsx index 2a57165..82f5550 100644 --- a/frontend/src/components/HomeLoggedOut/HomeLoggedOut.jsx +++ b/frontend/src/components/HomeLoggedOut/HomeLoggedOut.jsx @@ -6,10 +6,12 @@ import { useHistory } from "react-router-dom"; function HomeLoggedOut() { const [, setLoggedIn] = useLocalStorage("loggedIn", false); const [, setToken] = useLocalStorage("token", null); + const [, setDisableAuth] = useLocalStorage("disableAuth", false); const history = useHistory(); axios.get("/auth/login").then(function (response) { if (!response.data.enabled) { setLoggedIn(true); + setDisableAuth(true); setToken(""); history.go(0); } diff --git a/frontend/src/utils/API.js b/frontend/src/utils/API.js index 1d3a28b..4656032 100644 --- a/frontend/src/utils/API.js +++ b/frontend/src/utils/API.js @@ -5,7 +5,10 @@ const baseURL = "/api/"; export default axios.create({ baseURL: baseURL, responseType: "json", - headers: { - Authorization: `Bearer ${JSON.parse(localStorage.getItem("token"))}`, - }, + headers: + localStorage.getItem("disableAuth") === "true" + ? {} + : { + Authorization: `Bearer ${JSON.parse(localStorage.getItem("token"))}`, + }, }); From f30dec6eacfe0d2ac0031861b4f22f34dbab32c7 Mon Sep 17 00:00:00 2001 From: Sambhav Saggi <17993169+9p4@users.noreply.github.com> Date: Tue, 31 May 2022 19:46:07 -0400 Subject: [PATCH 002/141] fix: correct conditional for enabling bearer token --- backend/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app.js b/backend/app.js index 7f46dd3..263a965 100644 --- a/backend/app.js +++ b/backend/app.js @@ -18,7 +18,7 @@ const app = express(); app.use(logger("dev")); app.use(express.json()); app.use(express.urlencoded({ extended: false })); -if (process.env.ZU_DISABLE_AUTH === "true") { +if (process.env.ZU_DISABLE_AUTH !== "true") { app.use( bearerToken({ headerKey: "Bearer", From 036e5779ba319a63c9d749c32fcbd5452d2bd2d2 Mon Sep 17 00:00:00 2001 From: Sambhav Saggi <17993169+9p4@users.noreply.github.com> Date: Tue, 31 May 2022 20:06:49 -0400 Subject: [PATCH 003/141] fix: update disableAuth in localStorage if server config changes --- frontend/src/components/HomeLoggedOut/HomeLoggedOut.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/src/components/HomeLoggedOut/HomeLoggedOut.jsx b/frontend/src/components/HomeLoggedOut/HomeLoggedOut.jsx index 82f5550..f58e072 100644 --- a/frontend/src/components/HomeLoggedOut/HomeLoggedOut.jsx +++ b/frontend/src/components/HomeLoggedOut/HomeLoggedOut.jsx @@ -14,6 +14,8 @@ function HomeLoggedOut() { setDisableAuth(true); setToken(""); history.go(0); + } else { + setDisableAuth(false); } }); return ( From ddb3f442f85991db4fa0721f0d7c2b004a9ea12d Mon Sep 17 00:00:00 2001 From: Sambhav Saggi <17993169+9p4@users.noreply.github.com> Date: Tue, 31 May 2022 21:00:43 -0400 Subject: [PATCH 004/141] fix: simplify code and check login status on home page load --- frontend/src/components/Bar/Bar.jsx | 125 +++++++++--------- .../components/HomeLoggedIn/HomeLoggedIn.jsx | 14 ++ 2 files changed, 78 insertions(+), 61 deletions(-) diff --git a/frontend/src/components/Bar/Bar.jsx b/frontend/src/components/Bar/Bar.jsx index aac68c6..fe075cd 100644 --- a/frontend/src/components/Bar/Bar.jsx +++ b/frontend/src/components/Bar/Bar.jsx @@ -47,11 +47,15 @@ function Bar() { // name: "Settings", // to: "/settings", // }, - !disabledAuth && { - name: "Log out", - divide: true, - onClick: onLogOutClick, - }, + ...(!disabledAuth + ? [ + { + name: "Log out", + divide: true, + onClick: onLogOutClick, + }, + ] + : []), ]; return ( @@ -74,69 +78,68 @@ function Bar() { {/* The filter removes all elements that are "true" or "false" */} - {loggedIn && - menuItems.filter((e) => typeof e !== "boolean").length > 0 && ( - <> - + {loggedIn && menuItems.length > 0 && ( + <> + - - {menuItems.map((menuItem, index) => { - if ( - menuItem.hasOwnProperty("condition") && - !menuItem.condition - ) { - return null; - } + + {menuItems.map((menuItem, index) => { + if ( + menuItem.hasOwnProperty("condition") && + !menuItem.condition + ) { + return null; + } - let component = null; + let component = null; - if (menuItem.to) { - component = ( - - {menuItem.name} - - ); - } else { - component = ( - { - closeMenu(); + if (menuItem.to) { + component = ( + + {menuItem.name} + + ); + } else { + component = ( + { + closeMenu(); - menuItem.onClick(); - }} - > - {menuItem.name} - - ); - } + menuItem.onClick(); + }} + > + {menuItem.name} + + ); + } - if (menuItem.divide) { - return ( - - + if (menuItem.divide) { + return ( + + - {component} - - ); - } + {component} + + ); + } - return component; - })} - - - )} + return component; + })} + + + )} {!loggedIn && LogIn()} diff --git a/frontend/src/components/HomeLoggedIn/HomeLoggedIn.jsx b/frontend/src/components/HomeLoggedIn/HomeLoggedIn.jsx index ff45f76..2dbc1bd 100644 --- a/frontend/src/components/HomeLoggedIn/HomeLoggedIn.jsx +++ b/frontend/src/components/HomeLoggedIn/HomeLoggedIn.jsx @@ -1,5 +1,7 @@ import { useState, useEffect } from "react"; import { useHistory } from "react-router-dom"; +import { useLocalStorage } from "react-use"; +import axios from "axios"; import { Divider, Button, Grid, Typography, Box } from "@material-ui/core"; import useStyles from "./HomeLoggedIn.styles"; @@ -11,10 +13,22 @@ import { generateNetworkConfig } from "utils/NetworkConfig"; function HomeLoggedIn() { const [networks, setNetworks] = useState([]); + const [, setLoggedIn] = useLocalStorage("loggedIn", false); + const [, setDisableAuth] = useLocalStorage("disableAuth", false); + const [token, setToken] = useLocalStorage("token", null); const classes = useStyles(); const history = useHistory(); + axios.get("/auth/login").then(function (response) { + if (response.data.enabled) { + setDisableAuth(false); + if (!token || token.length === 0) { + setLoggedIn(false); + } + } + }); + const createNetwork = async () => { const network = await API.post("network", generateNetworkConfig()); console.log(network); From 04624d13c8451c68d4d4c673a577b14e6172ceb8 Mon Sep 17 00:00:00 2001 From: dec0dOS Date: Tue, 14 Jun 2022 18:37:44 +0300 Subject: [PATCH 005/141] chore: use zyclonite/zerotier as a controller image in docker-compose.yml example --- .github/workflows/main.yml | 11 ----------- docker-compose.yml | 8 ++++---- docker/zerotier/Dockerfile | 8 -------- 3 files changed, 4 insertions(+), 23 deletions(-) delete mode 100644 docker/zerotier/Dockerfile diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9955f13..fbacb04 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -49,14 +49,3 @@ jobs: platforms: linux/amd64,linux/arm64,linux/arm push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.prep_zero-ui.outputs.tags }} - - - name: Build and push zerotier-controller - id: docker_build_zerotier-controller - uses: docker/build-push-action@master - with: - context: ./ - file: ./docker/zerotier/Dockerfile - builder: ${{ steps.buildx.outputs.name }} - platforms: linux/amd64,linux/arm64,linux/arm - push: ${{ github.event_name != 'pull_request' }} - tags: ${{ secrets.DOCKER_HUB_USERNAME }}/zerotier-controller:latest diff --git a/docker-compose.yml b/docker-compose.yml index b4f0eae..573d0ea 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,14 +2,14 @@ version: "3.9" services: zerotier: - image: dec0dos/zerotier-controller:latest + image: zyclonite/zerotier:1.10.0 container_name: zu-controller - build: - context: . - dockerfile: ./docker/zerotier/Dockerfile restart: unless-stopped volumes: - controller_data:/var/lib/zerotier-one + environment: + - ZT_OVERRIDE_LOCAL_CONF=true + - ZT_ALLOW_MANAGEMENT_FROM=0.0.0.0/0 expose: - "9993/tcp" ports: diff --git a/docker/zerotier/Dockerfile b/docker/zerotier/Dockerfile deleted file mode 100644 index db2c4a1..0000000 --- a/docker/zerotier/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM zyclonite/zerotier:latest - -RUN echo "{\"settings\": {\"portMappingEnabled\": true,\"softwareUpdate\": \"disable\",\"allowManagementFrom\": [\"0.0.0.0/0\"]}}" > /var/lib/zerotier-one/local.conf - -EXPOSE 9993/tcp -EXPOSE 9993/udp - -ENTRYPOINT ["zerotier-one"] From 52ab0af80cb033a8f6959b34202d959a436d3faf Mon Sep 17 00:00:00 2001 From: dec0dOS Date: Tue, 14 Jun 2022 18:40:54 +0300 Subject: [PATCH 006/141] docs: use YOURDOMAIN.com as an example domain for consistency --- README.md | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9944fd1..0356f3e 100755 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ The most simple one-minute installation. Great for the fresh VPS setup. ```sh curl -L -O https://raw.githubusercontent.com/dec0dOS/zero-ui/main/docker-compose.yml ``` -2. Replace `example.com` with your domain name in `docker-compose.yml` +2. Replace `YOURDOMAIN.com` with your domain name in `docker-compose.yml` 3. Pull the images ```sh docker-compose pull diff --git a/docker-compose.yml b/docker-compose.yml index 573d0ea..654e446 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -39,7 +39,7 @@ services: restart: unless-stopped depends_on: - zero-ui - command: caddy reverse-proxy --from example.com --to zero-ui:4000 + command: caddy reverse-proxy --from YOURDOMAIN.com --to zero-ui:4000 volumes: - caddy_data:/data ports: From f883c7371bb5eed330f41aac4c205e3fb1fd3a58 Mon Sep 17 00:00:00 2001 From: dec0dOS Date: Tue, 14 Jun 2022 18:52:00 +0300 Subject: [PATCH 007/141] docs: small fixes --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0356f3e..b7c8ccf 100755 --- a/README.md +++ b/README.md @@ -139,7 +139,7 @@ The most simple one-minute installation. Great for the fresh VPS setup. 7. Navigate to `https://YOURDOMAIN.com/app/`. Now you could use your ZeroUI instance with HTTPS support and automated certificate renewal. -> To disable HTTPS, please remove https-proxy from `docker-compose.yml`, set `ZU_SECURE_HEADERS` to `false` and change zero-ui port `expose` to `ports`. +> To disable HTTPS, remove the `https-proxy` from `docker-compose.yml`, set `ZU_SECURE_HEADERS` to `false` and change zero-ui port `expose` to `ports`. Advanced manual setups are also supported. Check the following environment variables as a reference: | Name | Default value | Description | @@ -158,7 +158,7 @@ Advanced manual setups are also supported. Check the following environment varia ZeroUI could be deployed as a regular nodejs web application, but it requires ZeroTier controller that is installed with `zerotier-one` package. More info about the network controller you could read [here](https://github.com/zerotier/ZeroTierOne/tree/master/controller/#readme).
-Controller setup tips +Controller setup tips (outside the Docker)
If you are using the existing controller on the host, it may be necessary to allow connection from the Docker container. From c19b2581b21656e8fd08a21d64215e4ed773e53d Mon Sep 17 00:00:00 2001 From: dec0dOS Date: Fri, 17 Jun 2022 15:08:09 +0300 Subject: [PATCH 008/141] chore: downgrade default docker-compose.yml file version for better compatibility --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 654e446..ea3042e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -version: "3.9" +version: "3.3" services: zerotier: From 6725a57237a1d2f876f01e87dd179f939be1e5bb Mon Sep 17 00:00:00 2001 From: 9p4 <17993169+9p4@users.noreply.github.com> Date: Sat, 18 Jun 2022 11:05:57 +0530 Subject: [PATCH 009/141] Remove redundant disabled auth checks --- .../src/components/HomeLoggedIn/HomeLoggedIn.jsx | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/frontend/src/components/HomeLoggedIn/HomeLoggedIn.jsx b/frontend/src/components/HomeLoggedIn/HomeLoggedIn.jsx index 2dbc1bd..ff45f76 100644 --- a/frontend/src/components/HomeLoggedIn/HomeLoggedIn.jsx +++ b/frontend/src/components/HomeLoggedIn/HomeLoggedIn.jsx @@ -1,7 +1,5 @@ import { useState, useEffect } from "react"; import { useHistory } from "react-router-dom"; -import { useLocalStorage } from "react-use"; -import axios from "axios"; import { Divider, Button, Grid, Typography, Box } from "@material-ui/core"; import useStyles from "./HomeLoggedIn.styles"; @@ -13,22 +11,10 @@ import { generateNetworkConfig } from "utils/NetworkConfig"; function HomeLoggedIn() { const [networks, setNetworks] = useState([]); - const [, setLoggedIn] = useLocalStorage("loggedIn", false); - const [, setDisableAuth] = useLocalStorage("disableAuth", false); - const [token, setToken] = useLocalStorage("token", null); const classes = useStyles(); const history = useHistory(); - axios.get("/auth/login").then(function (response) { - if (response.data.enabled) { - setDisableAuth(false); - if (!token || token.length === 0) { - setLoggedIn(false); - } - } - }); - const createNetwork = async () => { const network = await API.post("network", generateNetworkConfig()); console.log(network); From b8026818fe942ad611993e868394b069559bc740 Mon Sep 17 00:00:00 2001 From: 9p4 <17993169+9p4@users.noreply.github.com> Date: Sat, 18 Jun 2022 11:08:54 +0530 Subject: [PATCH 010/141] Add localStorage disclaimer --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 31719c4..1e31667 100755 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ Advanced manual setups are also supported. Check the following environment varia | ZU_DEFAULT_USERNAME | unset (`docker-compose.yml`: admin) | Default username that will be set on the first run | | ZU_DEFAULT_PASSWORD | unset (`docker-compose.yml`: zero-ui) | Default password that will be set on the first run | | ZU_DATAPATH | `data/db.json` | ZeroUI data storage path | -| ZU_DISABLE_AUTH | unset | If set to true, automatically log in all users. This is useful if ZeroUI is protected by an authentication proxy | +| ZU_DISABLE_AUTH | unset | If set to true, automatically log in all users. This is useful if ZeroUI is protected by an authentication proxy. Note that when this value is changed, the localStorage of instances of logged-in panels should be cleared | ZeroUI could be deployed as a regular nodejs web application, but it requires ZeroTier controller that is installed with `zerotier-one` package. More info about the network controller you could read [here](https://github.com/zerotier/ZeroTierOne/tree/master/controller/#readme). From 74a36ad3efa3fffad2849c9375f4a621b9c6851a Mon Sep 17 00:00:00 2001 From: 9p4 <17993169+9p4@users.noreply.github.com> Date: Sat, 18 Jun 2022 11:10:48 +0530 Subject: [PATCH 011/141] Remove old comment --- frontend/src/components/Bar/Bar.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/components/Bar/Bar.jsx b/frontend/src/components/Bar/Bar.jsx index fe075cd..7f24969 100644 --- a/frontend/src/components/Bar/Bar.jsx +++ b/frontend/src/components/Bar/Bar.jsx @@ -77,7 +77,6 @@ function Bar() { - {/* The filter removes all elements that are "true" or "false" */} {loggedIn && menuItems.length > 0 && ( <>