Skip to content

Commit

Permalink
Supports displaying short links (wg-easy#1288)
Browse files Browse the repository at this point in the history
  • Loading branch information
pheiduck authored Aug 16, 2024
2 parents 2ea37dd + cd3d4ef commit 36b9ff6
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 4 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ You have found the easiest way to install & manage WireGuard on any Linux host!
* Automatic Light / Dark Mode
* Multilanguage Support
* UI_TRAFFIC_STATS (default off)
* UI_SHOW_LINKS (default off)

## Requirements

Expand Down Expand Up @@ -120,6 +121,7 @@ These options can be configured by setting environment variables using `-e KEY="
| `LANG` | `en` | `de` | Web UI language (Supports: en, ua, ru, tr, no, pl, fr, de, ca, es, ko, vi, nl, is, pt, chs, cht, it, th, hi). |
| `UI_TRAFFIC_STATS` | `false` | `true` | Enable detailed RX / TX client stats in Web UI |
| `UI_CHART_TYPE` | `0` | `1` | UI_CHART_TYPE=0 # Charts disabled, UI_CHART_TYPE=1 # Line chart, UI_CHART_TYPE=2 # Area chart, UI_CHART_TYPE=3 # Bar chart |
| `UI_SHOW_LINKS` | `false` | `true` | Enable display of a short download link in Web UI |

> If you change `WG_PORT`, make sure to also change the exposed port.
Expand Down
3 changes: 2 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ services:
# - WG_POST_DOWN=echo "Post Down" > /etc/wireguard/post-down.txt
# - UI_TRAFFIC_STATS=true
# - UI_CHART_TYPE=0 # (0 Charts disabled, 1 # Line chart, 2 # Area chart, 3 # Bar chart)
# - UI_SHOW_LINKS=true

image: ghcr.io/wg-easy/wg-easy
container_name: wg-easy
Expand All @@ -39,7 +40,7 @@ services:
cap_add:
- NET_ADMIN
- SYS_MODULE
# - NET_RAW # ⚠️ Uncomment if using Podman
# - NET_RAW # ⚠️ Uncomment if using Podman
sysctls:
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.src_valid_mark=1
1 change: 1 addition & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ iptables -D FORWARD -o wg0 -j ACCEPT;
module.exports.LANG = process.env.LANG || 'en';
module.exports.UI_TRAFFIC_STATS = process.env.UI_TRAFFIC_STATS || 'false';
module.exports.UI_CHART_TYPE = process.env.UI_CHART_TYPE || 0;
module.exports.UI_SHOW_LINKS = process.env.UI_SHOW_LINKS || 'false';
17 changes: 17 additions & 0 deletions src/lib/Server.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const {
LANG,
UI_TRAFFIC_STATS,
UI_CHART_TYPE,
UI_SHOW_LINKS,
} = require('../config');

const requiresPassword = !!PASSWORD_HASH;
Expand Down Expand Up @@ -92,6 +93,11 @@ module.exports = class Server {
return `"${UI_CHART_TYPE}"`;
}))

.get('/api/ui-show-links', defineEventHandler((event) => {
setHeader(event, 'Content-Type', 'application/json');
return `${UI_SHOW_LINKS}`;
}))

// Authentication
.get('/api/session', defineEventHandler((event) => {
const authenticated = requiresPassword
Expand All @@ -103,6 +109,17 @@ module.exports = class Server {
authenticated,
};
}))
.get('/:clientHash', defineEventHandler(async (event) => {
const clientHash = getRouterParam(event, 'clientHash');
const clients = await WireGuard.getClients();
const client = clients.find((client) => client.hash === clientHash);
if (!client) return;
const clientId = client.id;
const config = await WireGuard.getClientConfiguration({ clientId });
setHeader(event, 'Content-Disposition', `attachment; filename="${clientHash}.conf"`);
setHeader(event, 'Content-Type', 'text/plain');
return config;
}))
.post('/api/session', defineEventHandler(async (event) => {
const { password } = await readBody(event);

Expand Down
2 changes: 2 additions & 0 deletions src/lib/WireGuard.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const path = require('path');
const debug = require('debug')('WireGuard');
const crypto = require('node:crypto');
const QRCode = require('qrcode');
const CRC32 = require('crc-32');

const Util = require('./Util');
const ServerError = require('./ServerError');
Expand Down Expand Up @@ -147,6 +148,7 @@ ${client.preSharedKey ? `PresharedKey = ${client.preSharedKey}\n` : ''
createdAt: new Date(client.createdAt),
updatedAt: new Date(client.updatedAt),
allowedIPs: client.allowedIPs,
hash: Math.abs(CRC32.str(clientId)).toString(16),
downloadableConfig: 'privateKey' in client,
persistentKeepalive: null,
latestHandshakeAt: null,
Expand Down
13 changes: 13 additions & 0 deletions src/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"debug": "^4.3.6",
"express-session": "^1.18.0",
"h3": "^1.12.0",
"qrcode": "^1.5.4"
"qrcode": "^1.5.4",
"crc-32": "^1.2.2"
},
"devDependencies": {
"eslint-config-athom": "^3.1.3",
Expand Down
7 changes: 5 additions & 2 deletions src/www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ <h1 class="text-4xl dark:text-neutral-200 font-medium flex-grow self-start mb-4"
<path stroke-linecap="round" stroke-linejoin="round"
d="M21.752 15.002A9.72 9.72 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998Z" />
</svg>
<svg v-else xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"
<svg v-else xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"
class="w-5 h-5 fill-gray-600 dark:fill-neutral-400">
<path
d="M12,2.2c-5.4,0-9.8,4.4-9.8,9.8s4.4,9.8,9.8,9.8s9.8-4.4,9.8-9.8S17.4,2.2,12,2.2z M3.8,12c0-4.5,3.7-8.2,8.2-8.2v16.5C7.5,20.2,3.8,16.5,3.8,12z" />
Expand Down Expand Up @@ -225,7 +225,7 @@ <h1 class="text-4xl dark:text-neutral-200 font-medium flex-grow self-start mb-4"
</svg>
{{client.transferTxCurrent | bytes}}/s
</span>

<!-- Inline Transfer RX -->
<span v-if="!uiTrafficStats && client.transferRx" class="whitespace-nowrap" :title="$t('totalUpload') + bytes(client.transferRx)">
·
Expand All @@ -242,6 +242,9 @@ <h1 class="text-4xl dark:text-neutral-200 font-medium flex-grow self-start mb-4"
{{!uiTrafficStats ? " · " : ""}}{{new Date(client.latestHandshakeAt) | timeago}}
</span>
</div>
<div v-if="uiShowLinks" :ref="'client-' + client.id + '-hash'" class="text-gray-400 text-xs">
<a :href="'./' + client.hash + ''">{{document.location.protocol}}//{{document.location.host}}/{{client.hash}}</a>
</div>
</div>

<!-- Info -->
Expand Down
7 changes: 7 additions & 0 deletions src/www/js/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ class API {
});
}

async getUIShowLinks() {
return this.call({
method: 'get',
path: '/ui-show-links',
});
}

async getSession() {
return this.call({
method: 'get',
Expand Down
9 changes: 9 additions & 0 deletions src/www/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ new Vue({
uiTrafficStats: false,

uiChartType: 0,
uiShowLinks: false,
uiShowCharts: localStorage.getItem('uiShowCharts') === '1',
uiTheme: localStorage.theme || 'auto',
prefersDarkScheme: window.matchMedia('(prefers-color-scheme: dark)'),
Expand Down Expand Up @@ -384,6 +385,14 @@ new Vue({
this.uiChartType = 0;
});

this.api.getUIShowLinks()
.then((res) => {
this.uiShowLinks = res;
})
.catch(() => {
this.uiShowLinks = false;
});

Promise.resolve().then(async () => {
const lang = await this.api.getLang();
if (lang !== localStorage.getItem('lang') && i18n.availableLocales.includes(lang)) {
Expand Down

0 comments on commit 36b9ff6

Please sign in to comment.