forked from mirrors/amnezia-wg-easy
		
	Merge branch 'master' into remember-me
This commit is contained in:
		
						commit
						f5885e335c
					
				
					 13 changed files with 72 additions and 10 deletions
				
			
		| 
						 | 
				
			
			@ -38,3 +38,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';
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,6 +33,7 @@ const {
 | 
			
		|||
  LANG,
 | 
			
		||||
  UI_TRAFFIC_STATS,
 | 
			
		||||
  UI_CHART_TYPE,
 | 
			
		||||
  UI_SHOW_LINKS,
 | 
			
		||||
} = require('../config');
 | 
			
		||||
 | 
			
		||||
const requiresPassword = !!PASSWORD_HASH;
 | 
			
		||||
| 
						 | 
				
			
			@ -98,6 +99,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
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +115,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, remember } = await readBody(event);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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');
 | 
			
		||||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										21
									
								
								src/package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										21
									
								
								src/package-lock.json
									
										
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -10,6 +10,7 @@
 | 
			
		|||
      "license": "CC BY-NC-SA 4.0",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "bcryptjs": "^2.4.3",
 | 
			
		||||
        "crc-32": "^1.2.2",
 | 
			
		||||
        "debug": "^4.3.6",
 | 
			
		||||
        "express-session": "^1.18.0",
 | 
			
		||||
        "h3": "^1.12.0",
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +19,7 @@
 | 
			
		|||
      "devDependencies": {
 | 
			
		||||
        "eslint-config-athom": "^3.1.3",
 | 
			
		||||
        "nodemon": "^3.1.4",
 | 
			
		||||
        "tailwindcss": "^3.4.9"
 | 
			
		||||
        "tailwindcss": "^3.4.10"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=18"
 | 
			
		||||
| 
						 | 
				
			
			@ -1209,6 +1210,18 @@
 | 
			
		|||
      "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==",
 | 
			
		||||
      "license": "MIT"
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/crc-32": {
 | 
			
		||||
      "version": "1.2.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
 | 
			
		||||
      "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
 | 
			
		||||
      "license": "Apache-2.0",
 | 
			
		||||
      "bin": {
 | 
			
		||||
        "crc32": "bin/crc32.njs"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=0.8"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/cross-spawn": {
 | 
			
		||||
      "version": "7.0.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -4687,9 +4700,9 @@
 | 
			
		|||
      "peer": true
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/tailwindcss": {
 | 
			
		||||
      "version": "3.4.9",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.9.tgz",
 | 
			
		||||
      "integrity": "sha512-1SEOvRr6sSdV5IDf9iC+NU4dhwdqzF4zKKq3sAbasUWHEM6lsMhX+eNN5gkPx1BvLFEnZQEUFbXnGj8Qlp83Pg==",
 | 
			
		||||
      "version": "3.4.10",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz",
 | 
			
		||||
      "integrity": "sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,12 +19,13 @@
 | 
			
		|||
    "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",
 | 
			
		||||
    "nodemon": "^3.1.4",
 | 
			
		||||
    "tailwindcss": "^3.4.9"
 | 
			
		||||
    "tailwindcss": "^3.4.10"
 | 
			
		||||
  },
 | 
			
		||||
  "nodemonConfig": {
 | 
			
		||||
    "ignore": [
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
/*
 | 
			
		||||
! tailwindcss v3.4.9 | MIT License | https://tailwindcss.com
 | 
			
		||||
! tailwindcss v3.4.10 | MIT License | https://tailwindcss.com
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,7 +43,7 @@
 | 
			
		|||
                <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" />
 | 
			
		||||
| 
						 | 
				
			
			@ -225,7 +225,7 @@
 | 
			
		|||
                          </svg>
 | 
			
		||||
                          {{client.transferTxCurrent | bytes}}/s
 | 
			
		||||
                        </span>
 | 
			
		||||
                        
 | 
			
		||||
 | 
			
		||||
                        <!-- Inline Transfer RX -->
 | 
			
		||||
                        <span v-if="!uiTrafficStats && client.transferRx" class="whitespace-nowrap" :title="$t('totalUpload') + bytes(client.transferRx)">
 | 
			
		||||
                          ·
 | 
			
		||||
| 
						 | 
				
			
			@ -242,6 +242,9 @@
 | 
			
		|||
                          {{!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 -->
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,6 +64,13 @@ class API {
 | 
			
		|||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async getUIShowLinks() {
 | 
			
		||||
    return this.call({
 | 
			
		||||
      method: 'get',
 | 
			
		||||
      path: '/ui-show-links',
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async getSession() {
 | 
			
		||||
    return this.call({
 | 
			
		||||
      method: 'get',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,6 +73,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)'),
 | 
			
		||||
| 
						 | 
				
			
			@ -392,6 +393,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)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -342,6 +342,12 @@ const messages = { // eslint-disable-line no-unused-vars
 | 
			
		|||
    downloadConfig: '구성 다운로드',
 | 
			
		||||
    madeBy: '만든 사람',
 | 
			
		||||
    donate: '기부',
 | 
			
		||||
    toggleCharts: '차트 표시/숨기기',
 | 
			
		||||
    theme: { dark: '어두운 테마', light: '밝은 테마', auto: '자동 테마' },
 | 
			
		||||
    restore: '복원',
 | 
			
		||||
    backup: '백업',
 | 
			
		||||
    titleRestoreConfig: '구성 파일 복원',
 | 
			
		||||
    titleBackupConfig: '구성 파일 백업',
 | 
			
		||||
  },
 | 
			
		||||
  vi: {
 | 
			
		||||
    name: 'Tên',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue