Browse Source

Merge branch 'wg-easy:master' into master

pull/1605/head
Andreas 1 year ago
committed by GitHub
parent
commit
30e3c8fd96
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 7
      .github/dependabot.yml
  2. 1
      .github/workflows/codeql.yml
  3. 1
      .github/workflows/deploy-development.yml
  4. 1
      .github/workflows/deploy-nightly.yml
  5. 1
      .github/workflows/deploy.yml
  6. 1
      .github/workflows/lint.yml
  7. 1
      .github/workflows/npm-update-bot.yml
  8. 7
      .github/workflows/stale.yml
  9. 3
      Dockerfile
  10. 1
      README.md
  11. 2
      docker-compose.yml
  12. 3
      docs/changelog.json
  13. 7
      src/lib/WireGuard.js
  14. 2
      src/package.json
  15. 8
      src/www/css/app.css
  16. 7
      src/www/index.html
  17. 2
      src/www/js/app.js
  18. 270
      src/www/js/i18n.js
  19. 10
      src/www/js/vendor/apexcharts.min.js
  20. 9
      src/www/js/vendor/sha256.min.js
  21. 1
      src/www/js/vendor/sha512.min.js
  22. 2
      wg-easy.service

7
.github/dependabot.yml

@ -0,0 +1,7 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
rebase-strategy: "auto"

1
.github/workflows/codeql.yml

@ -12,6 +12,7 @@ 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

1
.github/workflows/deploy-development.yml

@ -7,6 +7,7 @@ jobs:
deploy: deploy:
name: Build & Deploy name: Build & Deploy
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository_owner == 'wg-easy'
permissions: permissions:
packages: write packages: write
contents: read contents: read

1
.github/workflows/deploy-nightly.yml

@ -9,6 +9,7 @@ jobs:
deploy: deploy:
name: Build & Deploy name: Build & Deploy
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository_owner == 'wg-easy'
permissions: permissions:
packages: write packages: write
contents: read contents: read

1
.github/workflows/deploy.yml

@ -10,6 +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'
permissions: permissions:
packages: write packages: write
contents: read contents: read

1
.github/workflows/lint.yml

@ -11,6 +11,7 @@ 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

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

@ -10,6 +10,7 @@ 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

7
.github/workflows/stale.yml

@ -14,6 +14,7 @@ jobs:
stale: stale:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository_owner == 'wg-easy'
permissions: permissions:
issues: write issues: write
pull-requests: write pull-requests: write
@ -21,8 +22,8 @@ jobs:
steps: steps:
- uses: actions/stale@v9 - uses: actions/stale@v9
with: with:
days-before-issue-stale: 14 days-before-issue-stale: 30
days-before-issue-close: 7 days-before-issue-close: 14
stale-issue-label: "stale" stale-issue-label: "stale"
stale-issue-message: "This issue is stale because it has been open for 30 days with no activity." 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." close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
@ -31,4 +32,4 @@ jobs:
stale-pr-message: "This PR is stale because it has been open for 30 days with no activity." 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." 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 }} repo-token: ${{ secrets.GITHUB_TOKEN }}
operations-per-run: 5 operations-per-run: 100

3
Dockerfile

@ -25,6 +25,9 @@ RUN mv /app/node_modules /node_modules
# Enable this to run `npm run serve` # Enable this to run `npm run serve`
RUN npm i -g nodemon RUN npm i -g nodemon
# Workaround CVE-2023-42282
RUN npm uninstall -g ip
# Install Linux packages # Install Linux packages
RUN apk add --no-cache \ RUN apk add --no-cache \
dpkg \ dpkg \

1
README.md

@ -97,6 +97,7 @@ These options can be configured by setting environment variables using `-e KEY="
| `WG_POST_UP` | `...` | `iptables ...` | See [config.js](https://github.com/wg-easy/wg-easy/blob/master/src/config.js#L20) for the default value. | | `WG_POST_UP` | `...` | `iptables ...` | See [config.js](https://github.com/wg-easy/wg-easy/blob/master/src/config.js#L20) for the default value. |
| `WG_PRE_DOWN` | `...` | - | See [config.js](https://github.com/wg-easy/wg-easy/blob/master/src/config.js#L27) for the default value. | | `WG_PRE_DOWN` | `...` | - | See [config.js](https://github.com/wg-easy/wg-easy/blob/master/src/config.js#L27) for the default value. |
| `WG_POST_DOWN` | `...` | `iptables ...` | See [config.js](https://github.com/wg-easy/wg-easy/blob/master/src/config.js#L28) for the default value. | | `WG_POST_DOWN` | `...` | `iptables ...` | See [config.js](https://github.com/wg-easy/wg-easy/blob/master/src/config.js#L28) for the default value. |
| `LANG` | `en` | `de` | Web UI language (Supports: en, ru, tr, no, pl, fr, de, ca, es, vi, nl, is, chs, cht,). |
> If you change `WG_PORT`, make sure to also change the exposed port. > If you change `WG_PORT`, make sure to also change the exposed port.

2
docker-compose.yml

@ -6,7 +6,7 @@ services:
wg-easy: wg-easy:
environment: environment:
# Change Language: # Change Language:
# (Supports: en, ru, tr, no, pl, fr, de) # (Supports: en, ua, ru, tr, no, pl, fr, de, ca, es, pt, chs, cht)
- LANG=de - LANG=de
# ⚠️ Required: # ⚠️ Required:
# Change this to your host's public address # Change this to your host's public address

3
docs/changelog.json

@ -8,5 +8,6 @@
"7": "Improved the look & performance of the upload/download chart.", "7": "Improved the look & performance of the upload/download chart.",
"8": "Updated to Node.js v18.", "8": "Updated to Node.js v18.",
"9": "Fixed issue running on devices with older kernels.", "9": "Fixed issue running on devices with older kernels.",
"10": "Added sessionless HTTP API auth & automatic dark mode." "10": "Added sessionless HTTP API auth & automatic dark mode.",
"11": "Multilanguage Support & various bugfixes"
} }

7
src/lib/WireGuard.js

@ -202,12 +202,11 @@ AllowedIPs = ${client.address}/32`;
const config = await this.getConfig(); const config = await this.getConfig();
const client = await this.getClient({ clientId }); const client = await this.getClient({ clientId });
return ` return `[Interface]
[Interface]
PrivateKey = ${client.privateKey} PrivateKey = ${client.privateKey}
Address = ${client.address}/24 Address = ${client.address}/24
${WG_DEFAULT_DNS ? `DNS = ${WG_DEFAULT_DNS}` : ''} ${WG_DEFAULT_DNS ? `DNS = ${WG_DEFAULT_DNS}\n` : ''}\
${WG_MTU ? `MTU = ${WG_MTU}` : ''} ${WG_MTU ? `MTU = ${WG_MTU}\n` : ''}\
[Peer] [Peer]
PublicKey = ${config.server.publicKey} PublicKey = ${config.server.publicKey}

2
src/package.json

@ -1,5 +1,5 @@
{ {
"release": "10", "release": "11",
"name": "wg-easy", "name": "wg-easy",
"version": "1.0.1", "version": "1.0.1",
"description": "The easiest way to run WireGuard VPN + Web-based Admin UI.", "description": "The easiest way to run WireGuard VPN + Web-based Admin UI.",

8
src/www/css/app.css

@ -768,10 +768,6 @@ video {
height: 3rem; height: 3rem;
} }
.h-14 {
height: 3.5rem;
}
.h-2 { .h-2 {
height: 0.5rem; height: 0.5rem;
} }
@ -784,10 +780,6 @@ video {
height: 0.75rem; height: 0.75rem;
} }
.h-32 {
height: 8rem;
}
.h-4 { .h-4 {
height: 1rem; height: 1rem;
} }

7
src/www/index.html

@ -439,7 +439,10 @@
</div> </div>
<div v-if="authenticated === false"> <div v-if="authenticated === false">
<h1 class="text-4xl font-medium my-16 text-gray-700 dark:text-neutral-200 text-center">WireGuard</h1> <h1 class="text-4xl font-medium my-16 text-gray-700 dark:text-neutral-200 text-center">
<img src="./img/logo.png" width="32" class="inline align-middle dark:bg" />
<span class="align-middle">WireGuard</span>
</h1>
<form @submit="login" <form @submit="login"
class="shadow rounded-md bg-white dark:bg-neutral-700 mx-auto w-64 p-5 overflow-hidden mt-10"> class="shadow rounded-md bg-white dark:bg-neutral-700 mx-auto w-64 p-5 overflow-hidden mt-10">
@ -499,7 +502,7 @@
<script src="./js/vendor/vue-i18n.min.js"></script> <script src="./js/vendor/vue-i18n.min.js"></script>
<script src="./js/vendor/apexcharts.min.js"></script> <script src="./js/vendor/apexcharts.min.js"></script>
<script src="./js/vendor/vue-apexcharts.min.js"></script> <script src="./js/vendor/vue-apexcharts.min.js"></script>
<script src="./js/vendor/sha512.min.js"></script> <script src="./js/vendor/sha256.min.js"></script>
<script src="./js/vendor/timeago.full.min.js"></script> <script src="./js/vendor/timeago.full.min.js"></script>
<script src="./js/api.js"></script> <script src="./js/api.js"></script>
<script src="./js/i18n.js"></script> <script src="./js/i18n.js"></script>

2
src/www/js/app.js

@ -138,7 +138,7 @@ new Vue({
const clients = await this.api.getClients(); const clients = await this.api.getClients();
this.clients = clients.map((client) => { this.clients = clients.map((client) => {
if (client.name.includes('@') && client.name.includes('.')) { if (client.name.includes('@') && client.name.includes('.')) {
client.avatar = `https://www.gravatar.com/avatar/${sha512(client.name)}?d=blank`; client.avatar = `https://gravatar.com/avatar/${sha256(client.name.toLowerCase().trim())}.jpg`;
} }
if (!this.clientsPersist[client.id]) { if (!this.clientsPersist[client.id]) {

270
src/www/js/i18n.js

@ -28,6 +28,33 @@ const messages = { // eslint-disable-line no-unused-vars
madeBy: 'Made by', madeBy: 'Made by',
donate: 'Donate', donate: 'Donate',
}, },
ua: {
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: 'Пожертвувати',
},
ru: { ru: {
name: 'Имя', name: 'Имя',
password: 'Пароль', password: 'Пароль',
@ -191,4 +218,247 @@ 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: '기부',
},
vi: {
name: 'Tên',
password: 'Mật khẩu',
signIn: 'Đăng nhập',
logout: 'Đăng xuất',
updateAvailable: 'Có bản cập nhật mới!',
update: 'Cập nhật',
clients: 'Danh sách người dùng',
new: 'Mới',
deleteClient: 'Xóa người dùng',
deleteDialog1: 'Bạn có chắc chắn muốn xóa',
deleteDialog2: 'Thao tác này không thể hoàn tác.',
cancel: 'Huỷ',
create: 'Tạo',
createdOn: 'Được tạo lúc ',
lastSeen: 'Lần xem cuối vào ',
totalDownload: 'Tổng dung lượng tải xuống: ',
totalUpload: 'Tổng dung lượng tải lên: ',
newClient: 'Người dùng mới',
disableClient: 'Vô hiệu hóa người dùng',
enableClient: 'Kích hoạt người dùng',
noClients: 'Hiện chưa có người dùng nào.',
showQR: 'Hiển thị mã QR',
downloadConfig: 'Tải xuống cấu hình',
madeBy: 'Được tạo bởi',
donate: 'Ủng hộ',
},
nl: {
name: 'Naam',
password: 'Wachtwoord',
signIn: 'Inloggen',
logout: 'Uitloggen',
updateAvailable: 'Nieuw update beschikbaar!',
update: 'update',
clients: 'clients',
new: 'Nieuw',
deleteClient: 'client verwijderen',
deleteDialog1: 'Weet je zeker dat je wilt verwijderen',
deleteDialog2: 'Deze actie kan niet ongedaan worden gemaakt.',
cancel: 'Annuleren',
create: 'Creëren',
createdOn: 'Gemaakt op ',
lastSeen: 'Laatst gezien op ',
totalDownload: 'Totaal Gedownload: ',
totalUpload: 'Totaal Geupload: ',
newClient: 'Nieuwe client',
disableClient: 'client uitschakelen',
enableClient: 'client inschakelen',
noClients: 'Er zijn nog geen clients.',
showQR: 'QR-code weergeven',
downloadConfig: 'Configuratie downloaden',
madeBy: 'Gemaakt door',
donate: 'Doneren',
},
is: {
name: 'Nafn',
password: 'Lykilorð',
signIn: 'Skrá inn',
logout: 'Útskráning',
updateAvailable: 'Það er uppfærsla í boði!',
update: 'Uppfæra',
clients: 'Viðskiptavinir',
new: 'Nýtt',
deleteClient: 'Eyða viðskiptavin',
deleteDialog1: 'Ertu viss um að þú viljir eyða',
deleteDialog2: 'Þessi aðgerð getur ekki verið afturkallað.',
cancel: 'Hætta við',
create: 'Búa til',
createdOn: 'Búið til á ',
lastSeen: 'Síðast séð á ',
totalDownload: 'Samtals Niðurhlaða: ',
totalUpload: 'Samtals Upphlaða: ',
newClient: 'Nýr Viðskiptavinur',
disableClient: 'Gera viðskiptavin óvirkan',
enableClient: 'Gera viðskiptavin virkan',
noClients: 'Engir viðskiptavinir ennþá.',
showQR: 'Sýna QR-kóða',
downloadConfig: 'Niðurhal Stillingar',
madeBy: 'Gert af',
donate: 'Gefa',
},
pt: {
name: 'Nome',
password: 'Palavra Chave',
signIn: 'Entrar',
logout: 'Sair',
updateAvailable: 'Existe uma atualização disponível!',
update: 'Atualizar',
clients: 'Clientes',
new: 'Novo',
deleteClient: 'Apagar Clientes',
deleteDialog1: 'Tem certeza que pretende apagar',
deleteDialog2: 'Esta ação não pode ser revertida.',
cancel: 'Cancelar',
create: 'Criar',
createdOn: 'Criado em ',
lastSeen: 'Último acesso em ',
totalDownload: 'Total Download: ',
totalUpload: 'Total Upload: ',
newClient: 'Novo Cliente',
disableClient: 'Desativar Cliente',
enableClient: 'Ativar Cliente',
noClients: 'Não existem ainda clientes.',
showQR: 'Apresentar o código QR',
downloadConfig: 'Descarregar Configuração',
madeBy: 'Feito por',
donate: 'Doar',
},
chs: {
name: '名称',
password: '密码',
signIn: '登录',
logout: '退出',
updateAvailable: '有新版本可用!',
update: '更新',
clients: '客户端',
new: '新建',
deleteClient: '删除客户端',
deleteDialog1: '您确定要删除',
deleteDialog2: '此操作无法撤销。',
cancel: '取消',
create: '创建',
createdOn: '创建于 ',
lastSeen: '最后访问于 ',
totalDownload: '总下载: ',
totalUpload: '总上传: ',
newClient: '新建客户端',
disableClient: '禁用客户端',
enableClient: '启用客户端',
noClients: '目前没有客户端。',
showQR: '显示二维码',
downloadConfig: '下载配置',
madeBy: '由',
donate: '捐赠',
},
cht: {
name: '名字',
password: '密碼',
signIn: '登入',
logout: '登出',
updateAvailable: '有新版本可用!',
update: '更新',
clients: '客戶',
new: '新建',
deleteClient: '刪除客戶',
deleteDialog1: '您確定要刪除',
deleteDialog2: '此操作無法撤銷。',
cancel: '取消',
create: '建立',
createdOn: '建立於 ',
lastSeen: '最後訪問於 ',
totalDownload: '總下載: ',
totalUpload: '總上傳: ',
newClient: '新客戶',
disableClient: '禁用客戶',
enableClient: '啟用客戶',
noClients: '目前沒有客戶。',
showQR: '顯示二維碼',
downloadConfig: '下載配置',
madeBy: '由',
donate: '捐贈',
},
}; };

10
src/www/js/vendor/apexcharts.min.js

File diff suppressed because one or more lines are too long

9
src/www/js/vendor/sha256.min.js

File diff suppressed because one or more lines are too long

1
src/www/js/vendor/sha512.min.js

File diff suppressed because one or more lines are too long

2
wg-easy.service

@ -1,5 +1,5 @@
[Unit] [Unit]
Description=Wireguard VPN + + Web-based Admin UI Description=Wireguard VPN + Web-based Admin UI
After=network-online.target nss-lookup.target After=network-online.target nss-lookup.target
[Service] [Service]

Loading…
Cancel
Save