Merge pull request #168 from dec0dOS/modernize

Modernize codebase
This commit is contained in:
Aliaksei 2023-10-04 21:57:37 +01:00 committed by GitHub
commit 02384d4d01
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 5430 additions and 14686 deletions

View file

@ -3,7 +3,7 @@
*Dockerfile* *Dockerfile*
*docker-compose* *docker-compose*
node_modules node_modules
jsconfig.js .eslintrc.json
.DS_Store .DS_Store
tmp tmp
temp temp
@ -13,4 +13,6 @@ npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*
.yarn/cache
db.json
backend/data/db.json backend/data/db.json

View file

@ -7,7 +7,7 @@ on:
pull_request: pull_request:
branches: [main] branches: [main]
schedule: schedule:
- cron: "27 2 * * 4" - cron: "30 2 * * 6"
jobs: jobs:
analyze: analyze:

View file

@ -1,20 +0,0 @@
---
name: Lock
on:
schedule:
- cron: "0 9 * * *"
workflow_dispatch:
jobs:
lock:
name: 🔒 Lock closed issues and PRs
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v2.0.3
with:
github-token: ${{ github.token }}
issue-lock-inactive-days: "30"
issue-lock-reason: ""
pr-lock-inactive-days: "1"
pr-lock-reason: ""

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

893
.yarn/releases/yarn-4.0.0-rc.53.cjs vendored Executable file

File diff suppressed because one or more lines are too long

View file

@ -1,11 +1,7 @@
logFilters: compressionLevel: mixed
- code: YN0013
level: discard enableGlobalCache: false
nodeLinker: node-modules nodeLinker: node-modules
plugins: yarnPath: .yarn/releases/yarn-4.0.0-rc.53.cjs
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"
yarnPath: .yarn/releases/yarn-3.3.1.cjs

146
README.md
View file

@ -43,34 +43,25 @@
## About ## About
<table> This project drew inspiration from [ztncui](https://github.com/key-networks/ztncui) and was developed to address the current limitations of self-hosted [network controllers](https://github.com/zerotier/ZeroTierOne/tree/master/controller). Some of the issues in [ztncui](https://github.com/key-networks/ztncui) cannot be resolved due to the core architecture of the project. ZeroUI aims to resolve these issues and introduces the following features:
<tr>
<td>
This project is highly inspired by [ztncui](https://github.com/key-networks/ztncui) and was developed to address the current limitations of applying the self-hosted [network controllers](https://github.com/zerotier/ZeroTierOne/tree/master/controller). Some [ztncui](https://github.com/key-networks/ztncui) problems cannot be fixed because of the core architecture of the project. ZeroUI tries to solve them and implements the following features: - It is a lightweight [Single Page Application (SPA)](https://en.wikipedia.org/wiki/Single-page_application) built with React, providing an improved user experience, and it is mobile-friendly.
- ZeroUI is compatible with the ZeroTier Central API, allowing you to use CLI tools and custom applications designed for ZeroTier Central to manage your networks.
- Full React-powered lightweight [SPA](https://en.wikipedia.org/wiki/Single-page_application) that brings a better user experience, and ZeroUI is mobile-friendly. - ZeroUI implements controller-specific workarounds to address certain existing [issues](https://github.com/zerotier/ZeroTierOne/issues/859) that are not addressed in [ZTNCUI](https://github.com/key-networks/ztncui/issues/63).
- ZeroUI has ZeroTier Central compatible API. That means you could use CLI tools and custom applications made only for ZeroTier Central to manage your networks. - ZeroUI is more feature-complete, supporting almost all network controller features, including a rule editor. Development is ongoing, so you can expect regular updates with new features and bug fixes.
- ZeroUI implements controller-specific workarounds that address some existing [issues](https://github.com/zerotier/ZeroTierOne/issues/859). ZTNCUI [does not](https://github.com/key-networks/ztncui/issues/63). - Deploying ZeroUI is straightforward; refer to the [installation](#installation) section for more information.
- ZeroUI is more feature complete. ZeroUI has almost all network-controller-supported features, for example, rule editor. The development process hasn't stopped, so you will enjoy new features and bug fixes shortly.
- ZeroUI deployment is simple. Please refer to [installation](#installation) for more info.
<details> <details>
<summary>Wait, I haven't heard about ZeroTier yet...</summary> <summary>Curious about ZeroTier?</summary>
<br> <br>
[ZeroTier](https://www.zerotier.com) is awesome [open source project](https://github.com/zerotier/ZeroTierOne) that is available on wide range of [platforms](https://www.zerotier.com/download/). [ZeroTier](https://www.zerotier.com) is an impressive [open-source project](https://github.com/zerotier/ZeroTierOne) available on a wide range of [platforms](https://www.zerotier.com/download/). It can resolve many of your complex networking issues, potentially replacing your intricate VPN setups. You can create a virtual LAN and manage all your devices effortlessly.
Most of your hard networking problems could be solved with ZeroTier. It could replace all your complex VPN setups. You can place all your devices on a virtual LAN and manage it easily.
To sum up, ZeroTier combines the capabilities of VPN and SD-WAN, simplifying network management. In essence, ZeroTier combines the capabilities of VPN and SD-WAN, simplifying network management.
</details> </details>
</td> ## Built With
</tr>
</table>
### Built With
Frontend: Frontend:
@ -83,7 +74,7 @@ Backend:
- [Express](https://expressjs.com) - [Express](https://expressjs.com)
- [Lowdb](https://github.com/typicode/lowdb) - [Lowdb](https://github.com/typicode/lowdb)
Ready to use deployment solution: Ready-to-use deployment solution:
- [Docker](https://www.docker.com) - [Docker](https://www.docker.com)
- [Docker Compose](https://docs.docker.com/compose/) - [Docker Compose](https://docs.docker.com/compose/)
@ -93,14 +84,13 @@ Ready to use deployment solution:
### Prerequisites ### Prerequisites
The recommended method to install ZeroUI is by using Docker and Docker Compose. The recommended way to install ZeroUI is by using Docker and Docker Compose. To install [Docker](https://docs.docker.com/get-docker) and [Docker Compose](https://docs.docker.com/compose/install) on your system, please follow the installation guide in the [official Docker documentation](https://docs.docker.com/get-docker).
To install [Docker](https://docs.docker.com/get-docker) and [Docker Compose](https://docs.docker.com/compose/install) on your system, please follow the installation guide from the [official Docker documentation](https://docs.docker.com/get-docker).
For HTTPS setup you will need a domain name. You can get it for free at https://www.duckdns.org. For HTTPS setup, you will need a domain name. You can obtain one for free at https://www.duckdns.org.
### Installation ### Installation
The most simple one-minute installation. Great for the fresh VPS setup. Here's a straightforward one-minute installation guide, perfect for a fresh VPS setup:
1. Create a project directory 1. Create a project directory
@ -140,28 +130,28 @@ docker-compose up -d --no-build
docker-compose logs -f docker-compose logs -f
``` ```
7. Disable your firewall for the following ports: `80/tcp`, `443/tcp` and `9993/udp` 7. Disable your firewall for the following ports: `80/tcp`, `443/tcp`, and `9993/udp`
- on Ubuntu/Debian with ufw installed: - On Ubuntu/Debian with ufw installed:
```sh ```sh
ufw allow 80/tcp ufw allow 80/tcp
ufw allow 443/tcp ufw allow 443/tcp
ufw allow 9993/udp ufw allow 9993/udp
``` ```
- or you may use the old good iptables: - Or you can use iptables:
```sh ```sh
iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p udp --dport 9993 -j ACCEPT iptables -A INPUT -p udp --dport 9993 -j ACCEPT
``` ```
8. Navigate to `https://YOURDOMAIN.com/app/`. 8. Navigate to `https://YOURDOMAIN.com/app/`.
Now you could use your ZeroUI instance with HTTPS support and automated certificate renewal. Now you can use your ZeroUI instance with HTTPS support and automated certificate renewal.
> To disable Caddy proxy and HTTPS, remove the `https-proxy` from `docker-compose.yml`, set `ZU_SECURE_HEADERS` to `false` and change zero-ui port `expose` to `ports`. > To disable Caddy proxy and 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: Advanced manual setups are also supported. Check the following environment variables as a reference:
| Name | Default value | Description | | Name | Default value | Description |
@ -181,62 +171,49 @@ Advanced manual setups are also supported. Check the following environment varia
ZeroUI could be deployed as a regular nodejs web application, but it requires a ZeroTier controller that is installed with the `zerotier-one` package. For more info about the network controller, you could read [here](https://github.com/zerotier/ZeroTierOne/tree/master/controller/#readme). ZeroUI could be deployed as a regular nodejs web application, but it requires a ZeroTier controller that is installed with the `zerotier-one` package. For more info about the network controller, you could read [here](https://github.com/zerotier/ZeroTierOne/tree/master/controller/#readme).
For Ansible Role, please refer to [zero-ui-ansible repo](https://github.com/dec0dOS/zero-ui-ansible). For Ansible Role, please refer to the [zero-ui-ansible repository](https://github.com/dec0dOS/zero-ui-ansible).
<details> <details>
<summary>Controller setup tips (outside the Docker)</summary> <summary>Controller Setup Tips (Outside Docker)</summary>
<br> <br>
If you are using the existing controller on the host, it may be necessary to allow connection from the Docker container. If you are using an existing controller on the host, you may need to allow connections from the Docker container. There are two ways to do this:
You could do it in two ways:
1. Allowing controller management from any IP address: 1. Allow controller management from any IP address:
```sh ```sh
echo "{\"settings\": {\"portMappingEnabled\": true,\"softwareUpdate\": \"disable\",\"allowManagementFrom\": [\"0.0.0.0/0\"]}}" > /var/lib/zerotier-one/local.conf echo "{\"settings\": {\"portMappingEnabled\": true,\"softwareUpdate\": \"disable\",\"allowManagementFrom\": [\"0.0.0.0/0\"]}}" > /var/lib/zerotier-one/local.conf
``` ```
> Warning: don't forget to block connections to 9993/TCP from WAN. Direct controller API does not mean to be exposed to WAN, it should be proxified via the ZeroUI backend. > Warning: Don't forget to block connections to 9993/TCP from the WAN. Directly exposing the controller API to the WAN is not recommended; it should be proxified via the ZeroUI backend.
2. Adding `network_mode: "host"` to zero-ui in docker-compose.yml. 2. Add `network_mode: "host"` to zero-ui in `docker-compose.yml`.
More info is provided in the following [discussion](https://github.com/dec0dOS/zero-ui/discussions/8). For more information, please refer to this [discussion](https://github.com/dec0dOS/zero-ui/discussions/8).
</details> </details>
## Usage ## Usage
After installation, log in with your credentials that are declared with ZU_DEFAULT_USERNAME and ZU_DEFAULT_PASSWORD. After installation, log in with the credentials declared with `ZU_DEFAULT_USERNAME` and `ZU_DEFAULT_PASSWORD`.
Currently, almost all main ZeroTier Central features are available. Refer to the [roadmap](#roadmap) for more information. Currently, almost all main ZeroTier Central features are available. Refer to the [roadmap](#roadmap) for more information.
_For the screenshots, please refer to the [screenshots](docs/SCREENSHOTS.md)._ _For screenshots, please refer to the [screenshots](docs/SCREENSHOTS.md) section._
### Update ### Update
To get the latest version just run To get the latest version, simply run
```sh ```sh
docker-compose pull && docker-compose up -d --no-build docker-compose pull && docker-compose up -d --no-build
``` ```
in the folder where `docker-compose.yml` is located. Backup is not required as your data is saved in Docker volumes but recommended. in the folder where `docker-compose.yml` is located. While backups are not required as your data is saved in Docker volumes, it is recommended.
You could also set up [watchtower](https://github.com/containrrr/watchtower) for automatic updates.
```sh
docker run -d \
--name watchtower \
-v /var/run/docker.sock:/var/run/docker.sock \
--restart always \
containrrr/watchtower \
--cleanup --include-restarting \
zu-main zu-controller
```
### Backup ### Backup
You should regularly back up the `zerotier-one` and `data` folders in your ZeroUI installation directory. You should regularly back up the `zerotier-one` and `data` folders in your ZeroUI installation directory. You can do this manually before upgrading using the following commands:
You should do it manually before the upgrade via the following commands:
```sh ```sh
tar cvf backup-ui.tar data/ tar cvf backup-ui.tar data/
@ -245,7 +222,7 @@ tar cvf backup-zt.tar zerotier-one/
## Roadmap ## Roadmap
See the [open issues](https://github.com/dec0dOS/zero-ui/issues) for a list of proposed features (and known issues). For a list of proposed features (and known issues), see the [open issues](https://github.com/dec0dOS/zero-ui/issues).
- [Top Feature Requests](https://github.com/dec0dOS/zero-ui/issues?q=label%3Aenhancement+is%3Aopen+sort%3Areactions-%2B1-desc) (Add your votes using the 👍 reaction) - [Top Feature Requests](https://github.com/dec0dOS/zero-ui/issues?q=label%3Aenhancement+is%3Aopen+sort%3Areactions-%2B1-desc) (Add your votes using the 👍 reaction)
- [Top Bugs](https://github.com/dec0dOS/zero-ui/issues?q=is%3Aissue+is%3Aopen+label%3Abug+sort%3Areactions-%2B1-desc) (Add your votes using the 👍 reaction) - [Top Bugs](https://github.com/dec0dOS/zero-ui/issues?q=is%3Aissue+is%3Aopen+label%3Abug+sort%3Areactions-%2B1-desc) (Add your votes using the 👍 reaction)
@ -253,29 +230,30 @@ See the [open issues](https://github.com/dec0dOS/zero-ui/issues) for a list of p
[![GitHub issues open](https://img.shields.io/github/issues/dec0dOS/zero-ui.svg?maxAge=2592000)](https://github.com/dec0dOS/zero-ui/issues) [![GitHub issues open](https://img.shields.io/github/issues/dec0dOS/zero-ui.svg?maxAge=2592000)](https://github.com/dec0dOS/zero-ui/issues)
Please try to create bug reports that are: When creating bug reports, please ensure they are:
- _Reproducible._ Include steps to reproduce the problem. - _Reproducible._ Include steps to reproduce the problem.
- _Specific._ Include as much detail as possible: which version, what environment, etc. - _Specific._ Provide as much detail as possible, including version, environment, etc.
- _Unique._ Do not duplicate existing opened issues. - _Unique._ Avoid duplicating existing open issues.
- _Scoped to a Single Bug._ One bug per report. - _Scoped to a Single Bug._ Report one bug per issue.
## Contributing ## Contributing
First off, thanks for taking the time to contribute! Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make will benefit everybody else and are **greatly appreciated**. Firstly, thank you for considering contributing! Contributions are what make the open-source community thrive. Any contributions you make will benefit everyone, and they are highly appreciated.
1. Fork the project To contribute:
2. Create your feature branch (`git checkout -b feat/amazing_feature`)
3. Commit your changes (`git commit -m 'feat: add amazing_feature'`) 1. Fork the project.
4. Push to the branch (`git push origin feat/amazing_feature`) 2. Create your feature branch (`git checkout -b feat/amazing_feature`).
3. Commit your changes (`git commit -m 'feat: add amazing_feature'`).
4. Push to the branch (`git push origin feat/amazing_feature`).
5. [Open a Pull Request](https://github.com/dec0dOS/zero-ui/compare?expand=1) 5. [Open a Pull Request](https://github.com/dec0dOS/zero-ui/compare?expand=1)
ZeroUI uses [conventional commits](https://www.conventionalcommits.org), so please follow the guidelines. ZeroUI uses [conventional commits](https://www.conventionalcommits.org), so please follow the guidelines. You can use `yarn commit` to open a [Text-Based User Interface (TUI)](https://en.wikipedia.org/wiki/Text-based_user_interface) that follows conventional commits guidelines.
Run `yarn commit` to open [TUI](https://en.wikipedia.org/wiki/Text-based_user_interface) that follows conventional commits guidelines.
### Development environment ### Development Environment
To set up a development environment, please follow these steps: To set up a development environment, follow these steps:
1. Clone the repo 1. Clone the repo
@ -298,37 +276,35 @@ yarn dev
4. Navigate to http://localhost:3000 4. Navigate to http://localhost:3000
It is also required to install the ZeroTier controller. On Linux installing the `zerotier-one` package is enough, other platforms require some tweaking. Firstly you should get the controller token. On macOS, you could find it with the following command: You will also need to install the ZeroTier controller. On Linux, installing the `zerotier-one` package is sufficient, but other platforms may require some adjustments. First, you should obtain the controller token. On macOS, you can find it using the following command:
```sh ```sh
sudo cat "/Library/Application Support/ZeroTier/One/authtoken.secret" sudo cat "/Library/Application Support/ZeroTier/One/authtoken.secret"
``` ```
After you could start the ZeroUI development environment: Afterward, you can start the ZeroUI development environment:
```sh ```sh
ZU_CONTROLLER_TOKEN=TOKEN_FROM_authtoken.secret yarn dev ZU_CONTROLLER_TOKEN=TOKEN_FROM_authtoken.secret yarn dev
``` ```
_For other platforms, please refer to [ZeroTier manual](https://www.zerotier.com/manual/#4)._ For other platforms, please refer to the [ZeroTier manual](https://www.zerotier.com/manual/#4).
## Support ## Support
Reach out to me at one of the following places: If you need assistance or have questions, reach out through [GitHub Discussions](https://github.com/dec0dOS/zero-ui/discussions).
- [GitHub Discussions](https://github.com/dec0dOS/zero-ui/discussions)
## Security ## Security
ZeroUI follows good practices of security, but 100% security cannot be assured. ZeroUI is provided "as is" without any warranty. Use at your own risk. ZeroUI follows best practices for security, but complete security cannot be guaranteed. ZeroUI is provided "as is" without any warranty. Use at your own risk.
For enterprise support, a more reliable and scalable solution, please use ZeroTier Central. For enterprise support and a more reliable and scalable solution, please consider using ZeroTier Central.
_For more information and to report security issues, please refer to our [security documentation](docs/SECURITY.md)._ For more information and to report security issues, please refer to our [security documentation](docs/SECURITY.md).
## Copyright notice ## Copyright Notice
ZeroUI is not affiliated or associated with or endorsed by ZeroTier Central or ZeroTier, Inc. ZeroUI is not affiliated with, associated with, or endorsed by ZeroTier Central or ZeroTier, Inc.
## License ## License

63
backend/.eslintrc.json Normal file
View file

@ -0,0 +1,63 @@
{
"plugins": [
"@typescript-eslint",
"unicorn",
"jsdoc",
"import",
"promise",
"sonarjs"
],
"extends": [
"eslint:recommended",
"plugin:n/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:unicorn/recommended",
"plugin:jsdoc/recommended",
"plugin:import/recommended",
"plugin:promise/recommended",
"plugin:sonarjs/recommended",
"plugin:security/recommended"
],
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json",
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"ignoreRestSiblings": true
}
],
"@typescript-eslint/no-misused-promises": [
"error",
{
"checksVoidReturn": false
}
],
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/ban-ts-comment": "off",
"jsdoc/require-jsdoc": ["warn", { "publicOnly": true }],
"jsdoc/require-description": "off",
"import/no-unresolved": "off",
"unicorn/no-empty-file": "off",
"unicorn/consistent-function-scoping": [
"error",
{
"checkArrowFunctions": false
}
],
"unicorn/prefer-module": "off",
"unicorn/prevent-abbreviations": "off",
"unicorn/catch-error-name": "off",
"unicorn/prefer-ternary": "off",
"unicorn/prefer-event-target": "off",
"security/detect-object-injection": "off",
"security/detect-non-literal-fs-filename": "off"
}
}

View file

@ -36,6 +36,7 @@ if (
process.env.NODE_ENV === "production" && process.env.NODE_ENV === "production" &&
process.env.ZU_SECURE_HEADERS !== "false" process.env.ZU_SECURE_HEADERS !== "false"
) { ) {
// @ts-ignore
app.use(helmet()); app.use(helmet());
} }

1
backend/global.d.ts vendored Normal file
View file

@ -0,0 +1 @@
declare module "axios";

View file

@ -1,6 +0,0 @@
{
"exclude": ["node_modules", "**/node_modules/*"],
"typeAcquisition": {
"exclude": ["dotenv"]
}
}

View file

@ -2,20 +2,36 @@
"name": "backend", "name": "backend",
"private": true, "private": true,
"scripts": { "scripts": {
"start": "node ./bin/www" "start": "node ./bin/www",
"lint": "eslint . --report-unused-disable-directives --max-warnings 0",
"typecheck": "tsc --pretty --noEmit -p tsconfig.json"
}, },
"dependencies": { "dependencies": {
"axios": "^0.27.2", "axios": "^0.27.2",
"compression": "^1.7.4", "compression": "^1.7.4",
"debug": "~4.3.4", "debug": "^4.3.4",
"dotenv": "^16.0.1", "dotenv": "^16.3.1",
"express": "~4.18.1", "express": "^4.18.2",
"express-bearer-token": "^2.4.0", "express-bearer-token": "^2.4.0",
"helmet": "^5.1.1", "helmet": "^5.1.1",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"lowdb": "^1.0.0", "lowdb": "^1.0.0",
"morgan": "~1.10.0", "morgan": "^1.10.0",
"node-cron": "^3.0.2", "node-cron": "^3.0.2",
"pbkdf2-wrapper": "^1.3.4" "pbkdf2-wrapper": "^1.3.4"
},
"devDependencies": {
"@types/express": "^4.17.18",
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"eslint": "^8.50.0",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-jsdoc": "^46.8.2",
"eslint-plugin-n": "^16.1.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-security": "^1.7.1",
"eslint-plugin-sonarjs": "^0.21.0",
"eslint-plugin-unicorn": "^48.0.1",
"typescript": "^5.2.2"
} }
} }

View file

@ -8,6 +8,7 @@ const api = require("../utils/controller-api");
// get all members // get all members
router.get("/", auth.isAuthorized, async function (req, res) { router.get("/", auth.isAuthorized, async function (req, res) {
// @ts-ignore
const nwid = req.params.nwid; const nwid = req.params.nwid;
api api
.get("controller/network/" + nwid + "/member") .get("controller/network/" + nwid + "/member")
@ -23,6 +24,7 @@ router.get("/", auth.isAuthorized, async function (req, res) {
// get member // get member
router.get("/:mid", auth.isAuthorized, async function (req, res) { router.get("/:mid", auth.isAuthorized, async function (req, res) {
// @ts-ignore
const nwid = req.params.nwid; const nwid = req.params.nwid;
const mid = req.params.mid; const mid = req.params.mid;
const data = await member.getMembersData(nwid, [mid]); const data = await member.getMembersData(nwid, [mid]);
@ -35,6 +37,7 @@ router.get("/:mid", auth.isAuthorized, async function (req, res) {
// update member // update member
router.post("/:mid", auth.isAuthorized, async function (req, res) { router.post("/:mid", auth.isAuthorized, async function (req, res) {
// @ts-ignore
const nwid = req.params.nwid; const nwid = req.params.nwid;
const mid = req.params.mid; const mid = req.params.mid;
member.updateMemberAdditionalData(nwid, mid, req.body); member.updateMemberAdditionalData(nwid, mid, req.body);
@ -56,6 +59,7 @@ router.post("/:mid", auth.isAuthorized, async function (req, res) {
// delete member // delete member
router.delete("/:mid", auth.isAuthorized, async function (req, res) { router.delete("/:mid", auth.isAuthorized, async function (req, res) {
// @ts-ignore
const nwid = req.params.nwid; const nwid = req.params.nwid;
const mid = req.params.mid; const mid = req.params.mid;
member.deleteMemberAdditionalData(nwid, mid); member.deleteMemberAdditionalData(nwid, mid);

View file

@ -71,6 +71,7 @@ async function getMemberAdditionalData(data) {
networkId: data.nwid, networkId: data.nwid,
nodeId: data.id, nodeId: data.id,
controllerId: ZT_ADDRESS, controllerId: ZT_ADDRESS,
// @ts-ignore
lastOnline: lastOnline, lastOnline: lastOnline,
...additionalData, ...additionalData,
...peerData, ...peerData,

10
backend/tsconfig.json Normal file
View file

@ -0,0 +1,10 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"rootDir": ".",
"baseUrl": ".",
"module": "CommonJS",
"moduleResolution": "Node"
},
"include": ["."]
}

View file

@ -6,6 +6,7 @@ module.exports = async function () {
return res.data.address; return res.data.address;
} catch (err) { } catch (err) {
console.error( console.error(
// @ts-ignore
"Couldn't connect to the controller on " + err.config.baseURL "Couldn't connect to the controller on " + err.config.baseURL
); );
} }

View file

@ -1,31 +1,30 @@
FROM --platform=$BUILDPLATFORM node:lts-alpine as frontend-build FROM --platform=$BUILDPLATFORM node:lts-alpine as frontend-build
ENV INLINE_RUNTIME_CHUNK=false
ENV GENERATE_SOURCEMAP=false ENV GENERATE_SOURCEMAP=false
ENV NODE_OPTIONS=--openssl-legacy-provider
WORKDIR /app/
COPY --link tsconfig.json package.json yarn.lock* .yarnrc.yml ./
COPY --link .yarn/ ./.yarn
WORKDIR /app/frontend WORKDIR /app/frontend
COPY yarn.lock .yarnrc.yml ./ COPY --link ./frontend/package.json /app/frontend
COPY .yarn/ ./.yarn/ RUN yarn workspaces focus frontend
COPY ./frontend/package*.json /app/frontend COPY --link ./frontend /app/frontend
RUN yarn install
COPY ./frontend /app/frontend
RUN yarn build RUN yarn build
FROM node:lts-alpine FROM node:lts-alpine
WORKDIR /app/frontend/build WORKDIR /app/frontend/build
COPY --from=frontend-build /app/frontend/build /app/frontend/build/ COPY --link --from=frontend-build /app/frontend/build /app/frontend/build/
WORKDIR /app/
COPY --link package.json yarn.lock* .yarnrc.yml ./
COPY --link .yarn/ ./.yarn
WORKDIR /app/backend WORKDIR /app/backend
COPY yarn.lock .yarnrc.yml ./ COPY --link ./backend/package.json /app/backend
COPY .yarn/ ./.yarn/ RUN yarn workspaces focus --production backend && yarn cache clean
COPY ./backend/package*.json /app/backend
RUN yarn install
COPY ./backend /app/backend COPY --link ./backend /app/backend
EXPOSE 4000 EXPOSE 4000
ENV NODE_ENV=production ENV NODE_ENV=production

22
frontend/.eslintrc.json Normal file
View file

@ -0,0 +1,22 @@
{
"root": true,
"env": { "browser": true, "es2020": true },
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:react/jsx-runtime",
"plugin:react-hooks/recommended"
],
"ignorePatterns": ["dist", ".eslintrc.cjs"],
"parserOptions": { "ecmaVersion": "latest", "sourceType": "module" },
"settings": { "react": { "version": "17.0.2" } },
"plugins": ["react-refresh"],
"rules": {
"react-refresh/only-export-components": [
"warn",
{ "allowConstantExport": true }
],
"react/prop-types": ["off"],
"no-unused-vars": ["off"]
}
}

View file

@ -2,18 +2,18 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<base href="%PUBLIC_URL%/" /> <link rel="icon" href="/favicon.ico" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta <meta
name="viewport" name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/> />
<meta name="description" content="ZeroUI" /> <meta name="description" content="ZeroUI" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <link rel="manifest" href="/manifest.json" />
<title>ZeroUI</title> <title>ZeroUI</title>
</head> </head>
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div> <div id="root"></div>
<script type="module" src="/src/index.jsx"></script>
</body> </body>
</html> </html>

View file

@ -1,10 +0,0 @@
{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"],
"exclude": ["node_modules", "**/node_modules/*"],
"typeAcquisition": {
"exclude": ["dotenv", "harmony-reflect"]
}
}

View file

@ -18,23 +18,32 @@
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-is": "^17.0.2", "react-is": "^17.0.2",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"react-use": "^17.4.0", "react-use": "^17.4.0",
"styled-components": "^5.3.5" "styled-components": "^5.3.5"
}, },
"devDependencies": { "devDependencies": {
"source-map-explorer": "^2.5.2" "@types/react": "^18.2.24",
"@types/react-dom": "^18.2.9",
"@vitejs/plugin-react": "^4.1.0",
"eslint": "^8.50.0",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
"rimraf": "^5.0.5",
"source-map-explorer": "^2.5.3",
"typescript": "^5.2.2",
"vite": "^4.4.10"
}, },
"scripts": { "scripts": {
"start": "BROWSER=none react-scripts start", "start": "vite",
"build": "react-scripts build", "build": "vite build",
"serve": "vite preview",
"clean": "rimraf build",
"lint": "eslint src --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"typecheck": "tsc --pretty --noEmit -p tsconfig.json",
"analyze": "source-map-explorer 'build/static/js/*.js'" "analyze": "source-map-explorer 'build/static/js/*.js'"
}, },
"homepage": "/app", "homepage": "/app",
"proxy": "http://127.0.0.1:4000",
"eslintConfig": {
"extends": "react-app"
},
"browserslist": { "browserslist": {
"production": [ "production": [
">0.2%", ">0.2%",

View file

@ -90,7 +90,7 @@ function Bar() {
> >
{menuItems.map((menuItem, index) => { {menuItems.map((menuItem, index) => {
if ( if (
menuItem.hasOwnProperty("condition") && Object.prototype.hasOwnProperty.call(menuItem, "condition") &&
!menuItem.condition !menuItem.condition
) { ) {
return null; return null;

View file

@ -6,7 +6,7 @@ import LogInToken from "./components/LogInToken";
function LogIn() { function LogIn() {
return ( return (
<> <>
{process.env.NODE_ENV === "development" && ( {import.meta.env.DEV && (
<> <>
<LogInToken /> <LogInToken />
<Divider orientation="vertical" /> <Divider orientation="vertical" />

View file

@ -124,7 +124,7 @@ function NetworkRules({ network, callback }) {
width: "250px", width: "250px",
}} }}
> >
{!!errors.length ? ( {errors.length ? (
<Typography color="error"> <Typography color="error">
{"[" + errors[0] + ":" + errors[1] + "] " + errors[2]} {"[" + errors[0] + ":" + errors[1] + "] " + errors[2]}
</Typography> </Typography>

View file

@ -1,3 +1,4 @@
// @ts-nocheck
/* eslint-disable */ /* eslint-disable */
// rule-compiler.js from ZeroTierOne before its relicensing // rule-compiler.js from ZeroTierOne before its relicensing
// source: // source:

1
frontend/src/types.d.ts vendored Normal file
View file

@ -0,0 +1 @@
declare module "*.png";

11
frontend/tsconfig.json Normal file
View file

@ -0,0 +1,11 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"rootDir": ".",
"baseUrl": "src",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"jsx": "preserve"
},
"include": ["src"]
}

27
frontend/vite.config.js Normal file
View file

@ -0,0 +1,27 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
base: "/app",
server: {
port: 3000,
strictPort: true,
proxy: {
"/auth": "http://127.0.0.1:4000",
"/api": "http://127.0.0.1:4000",
"/controller": "http://127.0.0.1:4000",
},
},
resolve: {
alias: {
components: "/src/components",
utils: "/src/utils",
external: "/src/external",
},
},
build: {
outDir: "build",
chunkSizeWarningLimit: 1000,
},
plugins: [react()],
});

View file

@ -7,28 +7,30 @@
], ],
"scripts": { "scripts": {
"postinstall": "husky install", "postinstall": "husky install",
"upgradeDeps": "yarn upgrade-interactive", "upgrade:deps": "yarn upgrade-interactive",
"upgradeYarn": "yarn set version latest", "upgrade:yarn": "yarn set version latest",
"cleanDeps": "cd frontend && rimraf node_modules && cd ../backend && rimraf node_modules && cd .. && rimraf node_modules", "clean:deps": "cd frontend && rimraf node_modules && cd ../backend && rimraf node_modules && cd .. && rimraf node_modules",
"lint": "yarn prettier --write .", "format": "yarn prettier",
"format:fix": "yarn prettier --write .",
"lint": "yarn workspaces foreach --all --parallel run lint",
"dev": "concurrently \"cd frontend && cross-env FAST_REFRESH=true yarn start\" \"cd backend && cross-env NODE_ENV=development ZU_DEFAULT_USERNAME=admin ZU_DEFAULT_PASSWORD=zero-ui nodemon ./bin/www --ignore data/db.json\"", "dev": "concurrently \"cd frontend && cross-env FAST_REFRESH=true yarn start\" \"cd backend && cross-env NODE_ENV=development ZU_DEFAULT_USERNAME=admin ZU_DEFAULT_PASSWORD=zero-ui nodemon ./bin/www --ignore data/db.json\"",
"build": "cd frontend && cross-env INLINE_RUNTIME_CHUNK=false GENERATE_SOURCEMAP=false yarn build", "build": "cd frontend && cross-env GENERATE_SOURCEMAP=false yarn build",
"prod": "cd backend && cross-env NODE_ENV=production ZU_SECURE_HEADERS=false yarn start", "prod": "cd backend && cross-env NODE_ENV=production ZU_SECURE_HEADERS=false yarn start",
"release": "standard-version && git push --follow-tags origin main && git add CHANGELOG.md", "release": "standard-version && git push --follow-tags origin main && git add CHANGELOG.md",
"commit": "yarn git-cz" "commit": "yarn git-cz"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "^17.0.3", "@commitlint/cli": "^17.7.2",
"@commitlint/config-conventional": "^17.0.3", "@commitlint/config-conventional": "^17.7.0",
"commitizen": "^4.2.5", "commitizen": "^4.3.0",
"concurrently": "^7.3.0", "concurrently": "^8.2.1",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"cz-conventional-changelog": "^3.3.0", "cz-conventional-changelog": "^3.3.0",
"husky": "^8.0.1", "husky": "^8.0.3",
"lint-staged": "^13.0.3", "lint-staged": "^14.0.1",
"nodemon": "^2.0.19", "nodemon": "^3.0.1",
"prettier": "^2.7.1", "prettier": "^3.0.3",
"rimraf": "^3.0.2", "rimraf": "^5.0.5",
"standard-version": "^9.5.0" "standard-version": "^9.5.0"
}, },
"prettier": { "prettier": {
@ -52,5 +54,5 @@
"yarn prettier --write" "yarn prettier --write"
] ]
}, },
"packageManager": "yarn@3.3.1" "packageManager": "yarn@4.0.0-rc.53"
} }

13
tsconfig.json Normal file
View file

@ -0,0 +1,13 @@
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"noEmit": true,
"skipLibCheck": true,
"target": "ESNext",
"lib": ["ESNext", "dom"],
"strict": true,
"noImplicitAny": false,
"allowSyntheticDefaultImports": true
}
}

17559
yarn.lock

File diff suppressed because it is too large Load diff