Browse Source

Merge pull request #3 from spcfox/dev

Prepare release 1
pull/1239/head
Viktor Yudov 2 years ago
committed by GitHub
parent
commit
86ea93c07a
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      .env
  2. 3
      .github/FUNDING.yml
  3. 1
      .github/workflows/codeql.yml
  4. 6
      .github/workflows/deploy-development.yml
  5. 39
      .github/workflows/deploy-nightly.yml
  6. 4
      .github/workflows/deploy.yml
  7. 1
      .github/workflows/lint.yml
  8. 3
      .github/workflows/npm-update-bot.yml
  9. 35
      .github/workflows/stale.yml
  10. 45
      README.md
  11. 15
      contributing.md
  12. 10
      docker-compose.dev.yml
  13. 2
      docker-compose.yml
  14. 12
      docs/changelog.json
  15. 11
      package-lock.json
  16. 8
      package.json
  17. 5
      src/config.js
  18. 5
      src/lib/Server.js
  19. 1
      src/lib/WireGuard.js
  20. 150
      src/package-lock.json
  21. 10
      src/package.json
  22. 3
      src/www/img/_logo.svg
  23. 16
      src/www/index.html
  24. 7
      src/www/js/api.js
  25. 7
      src/www/js/app.js
  26. 81
      src/www/js/i18n.js
  27. 6
      src/www/manifest.json
  28. 22
      wg-easy.service

1
.env

@ -1,5 +1,6 @@
WG_HOST=🚨YOUR_SERVER_IP WG_HOST=🚨YOUR_SERVER_IP
PASSWORD=🚨YOUR_ADMIN_PASSWORD PASSWORD=🚨YOUR_ADMIN_PASSWORD
# (Supports: en, ru, tr, no, pl, fr, de, ca, es)
LANGUAGE=en LANGUAGE=en
PORT=51821 PORT=51821
WG_DEVICE=eth0 WG_DEVICE=eth0

3
.github/FUNDING.yml

@ -1,3 +0,0 @@
# These are supported funding model platforms
github: weejewel

1
.github/workflows/codeql.yml

@ -12,7 +12,6 @@ jobs:
analyze: analyze:
name: Analyze name: Analyze
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository_owner == 'wg-easy'
permissions: permissions:
actions: read actions: read
contents: read contents: read

6
.github/workflows/deploy-development.yml

@ -7,14 +7,14 @@ jobs:
deploy: deploy:
name: Build & Deploy name: Build & Deploy
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository_owner == 'wg-easy' if: github.repository_owner == 'spcfox'
permissions: permissions:
packages: write packages: write
contents: read contents: read
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
ref: production ref: master
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v3 uses: docker/setup-qemu-action@v3
@ -34,4 +34,4 @@ jobs:
with: with:
push: true push: true
platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8 platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8
tags: ghcr.io/wg-easy/wg-easy:development tags: ghcr.io/spcfox/amnezia-wg-easy:development

39
.github/workflows/deploy-nightly.yml

@ -1,39 +0,0 @@
name: Build & Publish Nightly
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * *"
jobs:
deploy:
name: Build & Deploy
runs-on: ubuntu-latest
if: github.repository_owner == 'wg-easy'
permissions:
packages: write
contents: read
steps:
- uses: actions/checkout@v4
with:
ref: production
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build & Publish Docker Image
uses: docker/build-push-action@v5
with:
push: true
platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8
tags: ghcr.io/wg-easy/wg-easy:nightly

4
.github/workflows/deploy.yml

@ -10,7 +10,7 @@ jobs:
deploy: deploy:
name: Build & Deploy name: Build & Deploy
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository_owner == 'wg-easy' if: github.repository_owner == 'spcfox'
permissions: permissions:
packages: write packages: write
contents: read contents: read
@ -40,4 +40,4 @@ jobs:
with: with:
push: true push: true
platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8 platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8
tags: ghcr.io/wg-easy/wg-easy:latest, ghcr.io/wg-easy/wg-easy:${{ env.RELEASE }} tags: ghcr.io/spcfox/amnezia-wg-easy:latest, ghcr.io/spcfox/amnezia-wg-easy:${{ env.RELEASE }}

1
.github/workflows/lint.yml

@ -11,7 +11,6 @@ jobs:
lint: lint:
name: Lint name: Lint
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository_owner == 'wg-easy'
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4

3
.github/workflows/npm-update-bot.yml

@ -10,12 +10,11 @@ jobs:
npmupbot: npmupbot:
name: NPM Update Bot 🤖 name: NPM Update Bot 🤖
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository_owner == 'wg-easy'
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
repository: wg-easy/wg-easy repository: spcfox/amnezia-wg-easy
ref: master ref: master
- name: Setup Node - name: Setup Node
uses: actions/setup-node@v4 uses: actions/setup-node@v4

35
.github/workflows/stale.yml

@ -1,35 +0,0 @@
# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
#
# You can adjust the behavior by modifying this file.
# For more information, see:
# https://github.com/actions/stale
name: Mark stale issues and pull requests
on:
workflow_dispatch:
schedule:
- cron: '*/5 * * * *'
jobs:
stale:
runs-on: ubuntu-latest
if: github.repository_owner == 'wg-easy'
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v9
with:
days-before-issue-stale: 30
days-before-issue-close: 14
stale-issue-label: "stale"
stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
days-before-pr-stale: 30
days-before-pr-close: 14
stale-pr-message: "This PR is stale because it has been open for 30 days with no activity."
close-pr-message: "This PR was closed because it has been inactive for 14 days since being marked as stale."
repo-token: ${{ secrets.GITHUB_TOKEN }}
operations-per-run: 100

45
README.md

@ -35,16 +35,24 @@ $ exit
And log in again. And log in again.
### 2. Set environment variables ### 2. Run AmneziaWG Easy
In [.env](.env) set the following environment variables:
- Replace `YOUR_SERVER_IP` with your WAN IP, or a Dynamic DNS hostname.
- Replace `YOUR_ADMIN_PASSWORD` with a password to log in on the Web UI.
### 3. Build & run the Docker image
```bash ```bash
$ docker-compose up -d $ docker run -d \
--name=amnezia-wg-easy \
-e LANG=en \
-e WG_HOST=<b>🚨YOUR_SERVER_IP</b> \
-e PASSWORD=<b>🚨YOUR_ADMIN_PASSWORD</b> \
-v ~/.amnezia-wg-easy:/etc/wireguard \
-p 51820:51820/udp \
-p 51821:51821/tcp \
--cap-add=NET_ADMIN \
--cap-add=SYS_MODULE \
--sysctl="net.ipv4.conf.all.src_valid_mark=1" \
--sysctl="net.ipv4.ip_forward=1" \
--device=/dev/net/tun:/dev/net/tun \
--restart unless-stopped \
ghcr.io/spcfox/amnezia-wg-easy
``` ```
The Web UI will now be available on `http://0.0.0.0:51821`. The Web UI will now be available on `http://0.0.0.0:51821`.
@ -57,7 +65,8 @@ These options can be configured by setting environment variables using `-e KEY="
| Env | Default | Example | Description | | Env | Default | Example | Description |
| - | - | - | - | | - | - | - | - |
| `LANGUAGE` | `en` | `de` | Web UI language. List of available languages in [i18n.js]() | | `LANGUAGE` | `en` | `de` | Web UI language (Supports: en, ru, tr, no, pl, fr, de, ca, es). |
| `CHECK_UPDATE` | `true` | `false` | Check for a new version and display a notification about its availability |
| `PORT` | `51821` | `6789` | TCP port for Web UI. | | `PORT` | `51821` | `6789` | TCP port for Web UI. |
| `WEBUI_HOST` | `0.0.0.0` | `localhost` | IP address web UI binds to. | | `WEBUI_HOST` | `0.0.0.0` | `localhost` | IP address web UI binds to. |
| `PASSWORD` | - | `foobar123` | When set, requires a password when logging in to the Web UI. | | `PASSWORD` | - | `foobar123` | When set, requires a password when logging in to the Web UI. |
@ -78,10 +87,20 @@ These options can be configured by setting environment variables using `-e KEY="
| `JMAX` | `1000` | `250` | Junk packet maximum size — maximum size for Junk packets. | | `JMAX` | `1000` | `250` | Junk packet maximum size — maximum size for Junk packets. |
| `S1` | `random` | `75` | Init packet junk size — the size of random data that will be added to the init packet, the size of which is initially fixed. | | `S1` | `random` | `75` | Init packet junk size — the size of random data that will be added to the init packet, the size of which is initially fixed. |
| `S2` | `random` | `75` | Response packet junk size — the size of random data that will be added to the response packet, the size of which is initially fixed. | | `S2` | `random` | `75` | Response packet junk size — the size of random data that will be added to the response packet, the size of which is initially fixed. |
| `H1` | `random` | `59869232` | Init packet magic header — the header of the first byte of the handshake. Must be < uint_max. | | `H1` | `random` | `1234567891` | Init packet magic header — the header of the first byte of the handshake. Must be < uint_max. |
| `H2` | `random` | `869587260` | Response packet magic header — header of the first byte of the handshake response. Must be < uint_max. | | `H2` | `random` | `1234567892` | Response packet magic header — header of the first byte of the handshake response. Must be < uint_max. |
| `H3` | `random` | `1632311713` | Underload packet magic header — UnderLoad packet header. Must be < uint_max. | | `H3` | `random` | `1234567893` | Underload packet magic header — UnderLoad packet header. Must be < uint_max. |
| `H4` | `random` | `820711365` | Transport packet magic header — header of the packet of the data packet. Must be < uint_max. | | `H4` | `random` | `1234567894` | Transport packet magic header — header of the packet of the data packet. Must be < uint_max. |
## Updating
To update to the latest version, simply run:
```bash
docker stop amnezia-wg-easy
docker rm amnezia-wg-easy
docker pull ghcr.io/spcfox/amnezia-wg-easy
```
## Thanks ## Thanks

15
contributing.md

@ -1,6 +1,6 @@
# Contributing to wg-easy # Contributing to amnezia-wg-easy
First and foremost, thank you! We appreciate that you want to contribute to wg-easy, your time is valuable, and your contributions mean a lot to us. First and foremost, thank you! We appreciate that you want to contribute to amnezia-wg-easy, your time is valuable, and your contributions mean a lot to us.
## Important! ## Important!
@ -25,14 +25,13 @@ Creating an issue is the simplest form of contributing to a project. But there a
- Bug reports - Bug reports
## Showing support for wg-easy ## Showing support for amnezia-wg-easy
Please keep in mind that open source software is built by people like you, who spend their free time creating things the rest the community can use. Please keep in mind that open source software is built by people like you, who spend their free time creating things the rest the community can use.
Don't have time to contribute? No worries, here are some other ways to show your support for wg-easy: Don't have time to contribute? No worries, here are some other ways to show your support for amnezia-wg-easy:
- star the [project](https://github.com/wg-easy/wg-easy) - star the [project](https://github.com/spcfox/amnezia-wg-easy)
- tweet your support for wg-easy
## Issues ## Issues
@ -67,14 +66,14 @@ Please be as descriptive as possible when creating an issue. Give us the informa
- **description**: (required) What is the bug you're experiencing? How are you using this library/app? - **description**: (required) What is the bug you're experiencing? How are you using this library/app?
- **OS**: (required) what operating system are you on? - **OS**: (required) what operating system are you on?
- **version**: (required) please note the version of wg-easy are you using - **version**: (required) please note the version of amnezia-wg-easy are you using
- **error messages**: (required) please paste any error messages into the issue, or a [gist](https://gist.github.com/) - **error messages**: (required) please paste any error messages into the issue, or a [gist](https://gist.github.com/)
- **extensions, plugins, helpers, etc** (if applicable): please list any extensions you're using - **extensions, plugins, helpers, etc** (if applicable): please list any extensions you're using
### Closing issues ### Closing issues
The original poster or the maintainers of wg-easy may close an issue at any time. Typically, but not exclusively, issues are closed when: The original poster or the maintainers of amnezia-wg-easy may close an issue at any time. Typically, but not exclusively, issues are closed when:
- The issue is resolved - The issue is resolved
- The project's maintainers have determined the issue is out of scope - The project's maintainers have determined the issue is out of scope

10
docker-compose.dev.yml

@ -1,10 +0,0 @@
version: "3.8"
services:
wg-easy:
image: wg-easy
command: npm run serve
volumes:
- ./src/:/app/
environment:
# - PASSWORD=p
- WG_HOST=192.168.1.233

2
docker-compose.yml

@ -6,7 +6,7 @@ services:
amnezia-wg-easy: amnezia-wg-easy:
env_file: env_file:
- .env - .env
build: . image: ghcr.io/spcfox/amnezia-wg-easy
container_name: amnezia-wg-easy container_name: amnezia-wg-easy
volumes: volumes:
- ~/.amnezia-wg-easy:/etc/wireguard - ~/.amnezia-wg-easy:/etc/wireguard

12
docs/changelog.json

@ -1,13 +1,3 @@
{ {
"1": "Initial version. Enjoy!", "1": "Initial version. Enjoy!"
"2": "You can now rename a client, and update the address. Enjoy!",
"3": "Many improvements and small changes. Enjoy!",
"4": "Now with pretty charts for client's network speed. Enjoy!",
"5": "Many small improvements & feature requests. Enjoy!",
"6": "Many small performance improvements & bug fixes. Enjoy!",
"7": "Improved the look & performance of the upload/download chart.",
"8": "Updated to Node.js v18.",
"9": "Fixed issue running on devices with older kernels.",
"10": "Added sessionless HTTP API auth & automatic dark mode."
"11": "Multilanguage Support & various bugfixes"
} }

11
package-lock.json

@ -1,11 +0,0 @@
{
"name": "wg-easy",
"version": "1.0.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"version": "1.0.1"
}
}
}

8
package.json

@ -1,8 +0,0 @@
{
"version": "1.0.1",
"scripts": {
"build": "DOCKER_BUILDKIT=1 docker build --tag wg-easy .",
"serve": "docker-compose -f docker-compose.yml -f docker-compose.dev.yml up",
"start": "docker run --env WG_HOST=0.0.0.0 --name wg-easy --cap-add=NET_ADMIN --cap-add=SYS_MODULE --sysctl=\"net.ipv4.conf.all.src_valid_mark=1\" --mount type=bind,source=\"$(pwd)\"/config,target=/etc/wireguard -p 51820:51820/udp -p 51821:51821/tcp wg-easy"
}
}

5
src/config.js

@ -2,6 +2,7 @@
const { release } = require('./package.json'); const { release } = require('./package.json');
module.exports.CHECK_UPDATE = process.env.CHECK_UPDATE ? process.env.CHECK_UPDATE.toLowerCase() === 'true' : true;
module.exports.RELEASE = release; module.exports.RELEASE = release;
module.exports.PORT = process.env.PORT || 51821; module.exports.PORT = process.env.PORT || 51821;
module.exports.WEBUI_HOST = process.env.WEBUI_HOST || '0.0.0.0'; module.exports.WEBUI_HOST = process.env.WEBUI_HOST || '0.0.0.0';
@ -31,8 +32,8 @@ module.exports.WG_POST_DOWN = process.env.WG_POST_DOWN || '';
module.exports.LANG = process.env.LANGUAGE || 'en'; module.exports.LANG = process.env.LANGUAGE || 'en';
const getRandomInt = (min, max) => min + Math.floor(Math.random() * (max - min)); const getRandomInt = (min, max) => min + Math.floor(Math.random() * (max - min));
const getRandomJunkSize = () => getRandomInt(15, 150) const getRandomJunkSize = () => getRandomInt(15, 150);
const getRandomHeader = () => getRandomInt(1, 2_147_483_647) const getRandomHeader = () => getRandomInt(1, 2_147_483_647);
module.exports.JC = process.env.JC || getRandomInt(3, 10); module.exports.JC = process.env.JC || getRandomInt(3, 10);
module.exports.JMIN = process.env.JMIN || 50; module.exports.JMIN = process.env.JMIN || 50;

5
src/lib/Server.js

@ -13,6 +13,7 @@ const ServerError = require('./ServerError');
const WireGuard = require('../services/WireGuard'); const WireGuard = require('../services/WireGuard');
const { const {
CHECK_UPDATE,
PORT, PORT,
WEBUI_HOST, WEBUI_HOST,
RELEASE, RELEASE,
@ -37,6 +38,10 @@ module.exports = class Server {
}, },
})) }))
.get('/api/check-update', (Util.promisify(async () => {
return CHECK_UPDATE;
})))
.get('/api/release', (Util.promisify(async () => { .get('/api/release', (Util.promisify(async () => {
return RELEASE; return RELEASE;
}))) })))

1
src/lib/WireGuard.js

@ -75,7 +75,6 @@ module.exports = class WireGuard {
clients: {}, clients: {},
}; };
debug('Configuration generated.'); debug('Configuration generated.');
} }

150
src/package-lock.json

@ -1,12 +1,12 @@
{ {
"name": "wg-easy", "name": "amnezia-wg-easy",
"version": "1.0.1", "version": "1.0.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "wg-easy", "name": "amnezia-wg-easy",
"version": "1.0.1", "version": "1.0.0",
"license": "GPL", "license": "GPL",
"dependencies": { "dependencies": {
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
@ -486,9 +486,9 @@
"dev": true "dev": true
}, },
"node_modules/@types/semver": { "node_modules/@types/semver": {
"version": "7.5.6", "version": "7.5.7",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz",
"integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==",
"dev": true "dev": true
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
@ -1053,14 +1053,15 @@
} }
}, },
"node_modules/call-bind": { "node_modules/call-bind": {
"version": "1.0.6", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"dependencies": { "dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0", "es-errors": "^1.3.0",
"function-bind": "^1.1.2", "function-bind": "^1.1.2",
"get-intrinsic": "^1.2.3", "get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.0" "set-function-length": "^1.2.1"
}, },
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@ -1286,17 +1287,19 @@
"peer": true "peer": true
}, },
"node_modules/define-data-property": { "node_modules/define-data-property": {
"version": "1.1.2", "version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"dependencies": { "dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0", "es-errors": "^1.3.0",
"get-intrinsic": "^1.2.2", "gopd": "^1.0.1"
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.1"
}, },
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/define-properties": { "node_modules/define-properties": {
@ -1419,50 +1422,52 @@
} }
}, },
"node_modules/es-abstract": { "node_modules/es-abstract": {
"version": "1.22.3", "version": "1.22.4",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.4.tgz",
"integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", "integrity": "sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"array-buffer-byte-length": "^1.0.0", "array-buffer-byte-length": "^1.0.1",
"arraybuffer.prototype.slice": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.3",
"available-typed-arrays": "^1.0.5", "available-typed-arrays": "^1.0.6",
"call-bind": "^1.0.5", "call-bind": "^1.0.7",
"es-set-tostringtag": "^2.0.1", "es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"es-set-tostringtag": "^2.0.2",
"es-to-primitive": "^1.2.1", "es-to-primitive": "^1.2.1",
"function.prototype.name": "^1.1.6", "function.prototype.name": "^1.1.6",
"get-intrinsic": "^1.2.2", "get-intrinsic": "^1.2.4",
"get-symbol-description": "^1.0.0", "get-symbol-description": "^1.0.2",
"globalthis": "^1.0.3", "globalthis": "^1.0.3",
"gopd": "^1.0.1", "gopd": "^1.0.1",
"has-property-descriptors": "^1.0.0", "has-property-descriptors": "^1.0.2",
"has-proto": "^1.0.1", "has-proto": "^1.0.1",
"has-symbols": "^1.0.3", "has-symbols": "^1.0.3",
"hasown": "^2.0.0", "hasown": "^2.0.1",
"internal-slot": "^1.0.5", "internal-slot": "^1.0.7",
"is-array-buffer": "^3.0.2", "is-array-buffer": "^3.0.4",
"is-callable": "^1.2.7", "is-callable": "^1.2.7",
"is-negative-zero": "^2.0.2", "is-negative-zero": "^2.0.2",
"is-regex": "^1.1.4", "is-regex": "^1.1.4",
"is-shared-array-buffer": "^1.0.2", "is-shared-array-buffer": "^1.0.2",
"is-string": "^1.0.7", "is-string": "^1.0.7",
"is-typed-array": "^1.1.12", "is-typed-array": "^1.1.13",
"is-weakref": "^1.0.2", "is-weakref": "^1.0.2",
"object-inspect": "^1.13.1", "object-inspect": "^1.13.1",
"object-keys": "^1.1.1", "object-keys": "^1.1.1",
"object.assign": "^4.1.4", "object.assign": "^4.1.5",
"regexp.prototype.flags": "^1.5.1", "regexp.prototype.flags": "^1.5.2",
"safe-array-concat": "^1.0.1", "safe-array-concat": "^1.1.0",
"safe-regex-test": "^1.0.0", "safe-regex-test": "^1.0.3",
"string.prototype.trim": "^1.2.8", "string.prototype.trim": "^1.2.8",
"string.prototype.trimend": "^1.0.7", "string.prototype.trimend": "^1.0.7",
"string.prototype.trimstart": "^1.0.7", "string.prototype.trimstart": "^1.0.7",
"typed-array-buffer": "^1.0.0", "typed-array-buffer": "^1.0.1",
"typed-array-byte-length": "^1.0.0", "typed-array-byte-length": "^1.0.0",
"typed-array-byte-offset": "^1.0.0", "typed-array-byte-offset": "^1.0.0",
"typed-array-length": "^1.0.4", "typed-array-length": "^1.0.4",
"unbox-primitive": "^1.0.2", "unbox-primitive": "^1.0.2",
"which-typed-array": "^1.1.13" "which-typed-array": "^1.1.14"
}, },
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@ -1477,6 +1482,17 @@
"integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==",
"dev": true "dev": true
}, },
"node_modules/es-define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
"dependencies": {
"get-intrinsic": "^1.2.4"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": { "node_modules/es-errors": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
@ -2380,20 +2396,6 @@
"dev": true, "dev": true,
"peer": true "peer": true
}, },
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/function-bind": { "node_modules/function-bind": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@ -2463,13 +2465,14 @@
} }
}, },
"node_modules/get-symbol-description": { "node_modules/get-symbol-description": {
"version": "1.0.1", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.1.tgz", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz",
"integrity": "sha512-KmuibvwbWaM4BHcBRYwJfZ1JxyJeBwB8ct9YYu67SvYdbEIlcQ2e56dHxfbobqW38GXo8/zDFqJeGtHiVbWyQw==", "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"call-bind": "^1.0.5", "call-bind": "^1.0.5",
"es-errors": "^1.3.0" "es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4"
}, },
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@ -2623,11 +2626,11 @@
} }
}, },
"node_modules/has-property-descriptors": { "node_modules/has-property-descriptors": {
"version": "1.0.1", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"dependencies": { "dependencies": {
"get-intrinsic": "^1.2.2" "es-define-property": "^1.0.0"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
@ -2671,9 +2674,9 @@
} }
}, },
"node_modules/hasown": { "node_modules/hasown": {
"version": "2.0.0", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz",
"integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==",
"dependencies": { "dependencies": {
"function-bind": "^1.1.2" "function-bind": "^1.1.2"
}, },
@ -3690,9 +3693,9 @@
} }
}, },
"node_modules/postcss": { "node_modules/postcss": {
"version": "8.4.34", "version": "8.4.35",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.34.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
"integrity": "sha512-4eLTO36woPSocqZ1zIrFD2K1v6wH7pY1uBh0JIM2KKfrVtGvPFiAku6aNOP0W1Wr9qwnaCsF0Z+CrVnryB2A8Q==", "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@ -3986,14 +3989,15 @@
} }
}, },
"node_modules/regexp.prototype.flags": { "node_modules/regexp.prototype.flags": {
"version": "1.5.1", "version": "1.5.2",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
"integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"call-bind": "^1.0.2", "call-bind": "^1.0.6",
"define-properties": "^1.2.0", "define-properties": "^1.2.1",
"set-function-name": "^2.0.0" "es-errors": "^1.3.0",
"set-function-name": "^2.0.1"
}, },
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"

10
src/package.json

@ -1,8 +1,8 @@
{ {
"release": "11", "release": "1",
"name": "wg-easy", "name": "amnezia-wg-easy",
"version": "1.0.1", "version": "1.0.0",
"description": "The easiest way to run WireGuard VPN + Web-based Admin UI.", "description": "The easiest way to run AmneziaWG VPN + Web-based Admin UI.",
"main": "server.js", "main": "server.js",
"scripts": { "scripts": {
"serve": "DEBUG=Server,WireGuard nodemon server.js", "serve": "DEBUG=Server,WireGuard nodemon server.js",
@ -10,7 +10,7 @@
"lint": "eslint .", "lint": "eslint .",
"buildcss": "npx tailwindcss -i ./www/src/css/app.css -o ./www/css/app.css" "buildcss": "npx tailwindcss -i ./www/src/css/app.css -o ./www/css/app.css"
}, },
"author": "Emile Nijssen", "author": "Viktor Yudov",
"license": "GPL", "license": "GPL",
"dependencies": { "dependencies": {
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",

3
src/www/img/_logo.svg

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.0 KiB

16
src/www/index.html

@ -40,6 +40,22 @@
</h1> </h1>
<h2 class="text-sm text-gray-400 dark:text-neutral-400 mb-10"></h2> <h2 class="text-sm text-gray-400 dark:text-neutral-400 mb-10"></h2>
<div v-if="latestRelease"
class="bg-red-800 dark:bg-red-100 p-4 text-white dark:text-red-600 text-sm font-small mb-10 rounded-md shadow-lg"
:title="`v${currentRelease} → v${latestRelease.version}`">
<div class="container mx-auto flex flex-row flex-auto items-center">
<div class="flex-grow">
<p class="font-bold">{{$t("updateAvailable")}}</p>
<p>{{latestRelease.changelog}}</p>
</div>
<a href="https://github.com/spcfox/amnezia-wg-easy#updating" target="_blank"
class="p-3 rounded-md bg-white dark:bg-red-100 float-right font-sm font-semibold text-red-800 dark:text-red-600 flex-shrink-0 border-2 border-red-800 dark:border-red-600 hover:border-white dark:hover:border-red-600 hover:text-white dark:hover:text-red-100 hover:bg-red-800 dark:hover:bg-red-600 transition-all">
{{$t("update")}} →
</a>
</div>
</div>
<div class="shadow-md rounded-lg bg-white dark:bg-neutral-700 overflow-hidden"> <div class="shadow-md rounded-lg bg-white dark:bg-neutral-700 overflow-hidden">
<div class="flex flex-row flex-auto items-center p-3 px-5 border-b-2 border-gray-100 dark:border-neutral-600"> <div class="flex flex-row flex-auto items-center p-3 px-5 border-b-2 border-gray-100 dark:border-neutral-600">
<div class="flex-grow"> <div class="flex-grow">

7
src/www/js/api.js

@ -29,6 +29,13 @@ class API {
return json; return json;
} }
async getCheckUpdate() {
return this.call({
method: 'get',
path: '/check-update',
});
}
async getRelease() { async getRelease() {
return this.call({ return this.call({
method: 'get', method: 'get',

7
src/www/js/app.js

@ -5,6 +5,8 @@
'use strict'; 'use strict';
const CHANGELOG_URL = 'https://raw.githubusercontent.com/spcfox/amnezia-wg-easy/production/docs/changelog.json';
function bytes(bytes, decimals, kib, maxunit) { function bytes(bytes, decimals, kib, maxunit) {
kib = kib || false; kib = kib || false;
if (bytes === 0) return '0 B'; if (bytes === 0) return '0 B';
@ -299,8 +301,11 @@ new Vue({
i18n.locale = lang; i18n.locale = lang;
} }
const checkUpdate = await this.api.getCheckUpdate();
if (!checkUpdate) return;
const currentRelease = await this.api.getRelease(); const currentRelease = await this.api.getRelease();
const latestRelease = await fetch('https://wg-easy.github.io/wg-easy/changelog.json') const latestRelease = await fetch(CHANGELOG_URL)
.then((res) => res.json()) .then((res) => res.json())
.then((releases) => { .then((releases) => {
const releasesArray = Object.entries(releases).map(([version, changelog]) => ({ const releasesArray = Object.entries(releases).map(([version, changelog]) => ({

81
src/www/js/i18n.js

@ -191,4 +191,85 @@ const messages = { // eslint-disable-line no-unused-vars
madeBy: 'Erstellt von', madeBy: 'Erstellt von',
donate: 'Spenden', donate: 'Spenden',
}, },
ca: { // github.com/guillembonet
name: 'Nom',
password: 'Contrasenya',
signIn: 'Iniciar sessió',
logout: 'Tanca sessió',
updateAvailable: 'Hi ha una actualització disponible!',
update: 'Actualitza',
clients: 'Clients',
new: 'Nou',
deleteClient: 'Esborra client',
deleteDialog1: 'Estàs segur que vols esborrar aquest client?',
deleteDialog2: 'Aquesta acció no es pot desfer.',
cancel: 'Cancel·la',
create: 'Crea',
createdOn: 'Creat el ',
lastSeen: 'Última connexió el ',
totalDownload: 'Baixada total: ',
totalUpload: 'Pujada total: ',
newClient: 'Nou client',
disableClient: 'Desactiva client',
enableClient: 'Activa client',
noClients: 'Encara no hi ha cap client.',
showQR: 'Mostra codi QR',
downloadConfig: 'Descarrega configuració',
madeBy: 'Fet per',
donate: 'Donatiu',
},
es: { // github.com/amarqz
name: 'Nombre',
password: 'Contraseña',
signIn: 'Iniciar sesión',
logout: 'Cerrar sesión',
updateAvailable: '¡Hay una actualización disponible!',
update: 'Actualizar',
clients: 'Clientes',
new: 'Nuevo',
deleteClient: 'Eliminar cliente',
deleteDialog1: '¿Estás seguro de que quieres borrar este cliente?',
deleteDialog2: 'Esta acción no podrá ser revertida.',
cancel: 'Cancelar',
create: 'Crear',
createdOn: 'Creado el ',
lastSeen: 'Última conexión el ',
totalDownload: 'Total descargado: ',
totalUpload: 'Total subido: ',
newClient: 'Nuevo cliente',
disableClient: 'Desactivar cliente',
enableClient: 'Activar cliente',
noClients: 'Aún no hay ningún cliente.',
showQR: 'Mostrar código QR',
downloadConfig: 'Descargar configuración',
madeBy: 'Hecho por',
donate: 'Donar',
},
ko: {
name: '이름',
password: '암호',
signIn: '로그안',
logout: '로그아웃',
updateAvailable: '업데이트가 있습니다!',
update: '업데이트',
clients: '클라이언트',
new: '추가',
deleteClient: '클라이언트 삭제',
deleteDialog1: '삭제 하시겠습니까?',
deleteDialog2: '이 작업은 취소할 수 없습니다.',
cancel: '취소',
create: '생성',
createdOn: '생성일: ',
lastSeen: '마지막 사용 날짜: ',
totalDownload: '총 다운로드: ',
totalUpload: '총 업로드: ',
newClient: '새로운 클라이언트',
disableClient: '클라이언트 비활성화',
enableClient: '클라이언트 활성화',
noClients: '아직 클라이언트가 없습니다.',
showQR: 'QR 코드 표시',
downloadConfig: '구성 다운로드',
madeBy: '만든 사람',
donate: '기부',
},
}; };

6
src/www/manifest.json

@ -1,11 +1,11 @@
{ {
"name": "WireGuard", "name": "AmneziaWG",
"display": "standalone", "display": "standalone",
"background_color": "#fff", "background_color": "#fff",
"icons": [ "icons": [
{ {
"src": "img/favicon.png", "src": "img/favicon.ico",
"type": "image/png" "type": "image/x-icon"
} }
] ]
} }

22
wg-easy.service

@ -1,22 +0,0 @@
[Unit]
Description=Wireguard VPN + + Web-based Admin UI
After=network-online.target nss-lookup.target
[Service]
Environment="WG_HOST=raspberrypi.local" # Change this to your host's public address or static public ip.
Environment="PASSWORD=REPLACEME" # When set, requires a password when logging in to the Web UI, to disable add a hashtag
#Environment="WG_DEFAULT_ADDRESS=10.0.8.x" #Clients IP address range.
#Environment="WG_DEFAULT_DNS=10.0.8.1, 1.1.1.1" #DNS server clients will use. If set to blank value, clients will not use any DNS.
#Environment="WG_ALLOWED_IPS=0.0.0.0/0,::/0" #Allowed IPs clients will use.
#Environment="WG_DEVICE=ens1" #Ethernet device the wireguard traffic should be forwarded through.
#Environment="PORT=80" #TCP port for Web UI. Default : 51821
#Environment="WG_MTU=1420" #The MTU the clients will use. Server uses default WG MTU
#Environment="WG_PERSISTENT_KEEPALIVE=25" #Value in seconds to keep the "connection" open. If this value is 0, then connections won't be kept alive.
Type=simple
RemainAfterExit=no
ExecStart=/usr/bin/env node /app/server.js
Restart=on-failure
RestartSec=1
[Install]
WantedBy=multi-user.target
Loading…
Cancel
Save