forked from mirrors/amnezia-wg-easy
		
	refactor: optimize build config, factorize code, enhance SVG icons (#1174)
* focus on syncing configuration without shutting down current wg session refactor build configuration logic to optimize code structure * enhance SVG icons for better visual appeal (https://github.com/wg-easy/wg-easy/pull/1166#issuecomment-2222418606) * update the screenshot to reflect the latest UI changes * fix: prevent logging private key during user creation
This commit is contained in:
		
						commit
						be8a592072
					
				
					 3 changed files with 67 additions and 56 deletions
				
			
		
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 104 KiB  | 
| 
						 | 
				
			
			@ -27,54 +27,60 @@ const {
 | 
			
		|||
 | 
			
		||||
module.exports = class WireGuard {
 | 
			
		||||
 | 
			
		||||
  async __buildConfig() {
 | 
			
		||||
    this.__configPromise = Promise.resolve().then(async () => {
 | 
			
		||||
      if (!WG_HOST) {
 | 
			
		||||
        throw new Error('WG_HOST Environment Variable Not Set!');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      debug('Loading configuration...');
 | 
			
		||||
      let config;
 | 
			
		||||
      try {
 | 
			
		||||
        config = await fs.readFile(path.join(WG_PATH, 'wg0.json'), 'utf8');
 | 
			
		||||
        config = JSON.parse(config);
 | 
			
		||||
        debug('Configuration loaded.');
 | 
			
		||||
      } catch (err) {
 | 
			
		||||
        const privateKey = await Util.exec('wg genkey');
 | 
			
		||||
        const publicKey = await Util.exec(`echo ${privateKey} | wg pubkey`, {
 | 
			
		||||
          log: 'echo ***hidden*** | wg pubkey',
 | 
			
		||||
        });
 | 
			
		||||
        const address = WG_DEFAULT_ADDRESS.replace('x', '1');
 | 
			
		||||
 | 
			
		||||
        config = {
 | 
			
		||||
          server: {
 | 
			
		||||
            privateKey,
 | 
			
		||||
            publicKey,
 | 
			
		||||
            address,
 | 
			
		||||
          },
 | 
			
		||||
          clients: {},
 | 
			
		||||
        };
 | 
			
		||||
        debug('Configuration generated.');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return config;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return this.__configPromise;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async getConfig() {
 | 
			
		||||
    if (!this.__configPromise) {
 | 
			
		||||
      this.__configPromise = Promise.resolve().then(async () => {
 | 
			
		||||
        if (!WG_HOST) {
 | 
			
		||||
          throw new Error('WG_HOST Environment Variable Not Set!');
 | 
			
		||||
      const config = await this.__buildConfig();
 | 
			
		||||
 | 
			
		||||
      await this.__saveConfig(config);
 | 
			
		||||
      await Util.exec('wg-quick down wg0').catch(() => {});
 | 
			
		||||
      await Util.exec('wg-quick up wg0').catch((err) => {
 | 
			
		||||
        if (err && err.message && err.message.includes('Cannot find device "wg0"')) {
 | 
			
		||||
          throw new Error('WireGuard exited with the error: Cannot find device "wg0"\nThis usually means that your host\'s kernel does not support WireGuard!');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        debug('Loading configuration...');
 | 
			
		||||
        let config;
 | 
			
		||||
        try {
 | 
			
		||||
          config = await fs.readFile(path.join(WG_PATH, 'wg0.json'), 'utf8');
 | 
			
		||||
          config = JSON.parse(config);
 | 
			
		||||
          debug('Configuration loaded.');
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
          const privateKey = await Util.exec('wg genkey');
 | 
			
		||||
          const publicKey = await Util.exec(`echo ${privateKey} | wg pubkey`, {
 | 
			
		||||
            log: 'echo ***hidden*** | wg pubkey',
 | 
			
		||||
          });
 | 
			
		||||
          const address = WG_DEFAULT_ADDRESS.replace('x', '1');
 | 
			
		||||
 | 
			
		||||
          config = {
 | 
			
		||||
            server: {
 | 
			
		||||
              privateKey,
 | 
			
		||||
              publicKey,
 | 
			
		||||
              address,
 | 
			
		||||
            },
 | 
			
		||||
            clients: {},
 | 
			
		||||
          };
 | 
			
		||||
          debug('Configuration generated.');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        await this.__saveConfig(config);
 | 
			
		||||
        await Util.exec('wg-quick down wg0').catch(() => { });
 | 
			
		||||
        await Util.exec('wg-quick up wg0').catch((err) => {
 | 
			
		||||
          if (err && err.message && err.message.includes('Cannot find device "wg0"')) {
 | 
			
		||||
            throw new Error('WireGuard exited with the error: Cannot find device "wg0"\nThis usually means that your host\'s kernel does not support WireGuard!');
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          throw err;
 | 
			
		||||
        });
 | 
			
		||||
        // await Util.exec(`iptables -t nat -A POSTROUTING -s ${WG_DEFAULT_ADDRESS.replace('x', '0')}/24 -o ' + WG_DEVICE + ' -j MASQUERADE`);
 | 
			
		||||
        // await Util.exec('iptables -A INPUT -p udp -m udp --dport 51820 -j ACCEPT');
 | 
			
		||||
        // await Util.exec('iptables -A FORWARD -i wg0 -j ACCEPT');
 | 
			
		||||
        // await Util.exec('iptables -A FORWARD -o wg0 -j ACCEPT');
 | 
			
		||||
        await this.__syncConfig();
 | 
			
		||||
 | 
			
		||||
        return config;
 | 
			
		||||
        throw err;
 | 
			
		||||
      });
 | 
			
		||||
      // await Util.exec(`iptables -t nat -A POSTROUTING -s ${WG_DEFAULT_ADDRESS.replace('x', '0')}/24 -o ' + WG_DEVICE + ' -j MASQUERADE`);
 | 
			
		||||
      // await Util.exec('iptables -A INPUT -p udp -m udp --dport 51820 -j ACCEPT');
 | 
			
		||||
      // await Util.exec('iptables -A FORWARD -i wg0 -j ACCEPT');
 | 
			
		||||
      // await Util.exec('iptables -A FORWARD -o wg0 -j ACCEPT');
 | 
			
		||||
      await this.__syncConfig();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return this.__configPromise;
 | 
			
		||||
| 
						 | 
				
			
			@ -227,7 +233,9 @@ Endpoint = ${WG_HOST}:${WG_CONFIG_PORT}`;
 | 
			
		|||
    const config = await this.getConfig();
 | 
			
		||||
 | 
			
		||||
    const privateKey = await Util.exec('wg genkey');
 | 
			
		||||
    const publicKey = await Util.exec(`echo ${privateKey} | wg pubkey`);
 | 
			
		||||
    const publicKey = await Util.exec(`echo ${privateKey} | wg pubkey`, {
 | 
			
		||||
      log: 'echo ***hidden*** | wg pubkey',
 | 
			
		||||
    });
 | 
			
		||||
    const preSharedKey = await Util.exec('wg genpsk');
 | 
			
		||||
 | 
			
		||||
    // Calculate next IP
 | 
			
		||||
| 
						 | 
				
			
			@ -319,25 +327,30 @@ Endpoint = ${WG_HOST}:${WG_CONFIG_PORT}`;
 | 
			
		|||
    await this.saveConfig();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async ___forceRestart() {
 | 
			
		||||
    this.__configPromise = null;
 | 
			
		||||
    await this.saveConfig();
 | 
			
		||||
  async __reloadConfig() {
 | 
			
		||||
    await this.__buildConfig();
 | 
			
		||||
    await this.__syncConfig();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async restoreConfiguration(config) {
 | 
			
		||||
    debug('Starting configuration restore process.');
 | 
			
		||||
    const _config = JSON.parse(config);
 | 
			
		||||
    await this.__saveConfig(_config);
 | 
			
		||||
    await this.___forceRestart();
 | 
			
		||||
    await this.__reloadConfig();
 | 
			
		||||
    debug('Configuration restore process completed.');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async backupConfiguration() {
 | 
			
		||||
    debug('Starting configuration backup.');
 | 
			
		||||
    const config = await this.getConfig();
 | 
			
		||||
    return JSON.stringify(config, null, 2);
 | 
			
		||||
    const backup = JSON.stringify(config, null, 2);
 | 
			
		||||
    debug('Configuration backup completed.');
 | 
			
		||||
    return backup;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Shutdown wireguard
 | 
			
		||||
  async Shutdown() {
 | 
			
		||||
    await Util.exec('wg-quick down wg0').catch(() => { });
 | 
			
		||||
    await Util.exec('wg-quick down wg0').catch(() => {});
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -94,9 +94,8 @@
 | 
			
		|||
              <!-- Restore configuration -->
 | 
			
		||||
              <label for="inputRC" :title="$t('titleRestoreConfig')"
 | 
			
		||||
                class="hover:cursor-pointer hover:bg-red-800 hover:border-red-800 hover:text-white text-gray-700 dark:text-neutral-200 border-2 border-gray-100 dark:border-neutral-600 py-2 px-4 rounded inline-flex items-center transition">
 | 
			
		||||
                <svg inline class="w-4 mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="-2 -2 18 18" stroke="currentColor">
 | 
			
		||||
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11.534 7h3.932a.25.25 0 0 1 .192.41l-1.966 2.36a.25.25 0 0 1-.384 0l-1.966-2.36a.25.25 0 0 1 .192-.41m-11 2h3.932a.25.25 0 0 0 .192-.41L2.692 6.23a.25.25 0 0 0-.384 0L.342 8.59A.25.25 0 0 0 .534 9" />
 | 
			
		||||
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 3c-1.552 0-2.94.707-3.857 1.818a.5.5 0 1 1-.771-.636A6.002 6.002 0 0 1 13.917 7H12.9A5 5 0 0 0 8 3M3.1 9a5.002 5.002 0 0 0 8.757 2.182.5.5 0 1 1 .771.636A6.002 6.002 0 0 1 2.083 9z" />
 | 
			
		||||
                <svg inline class="w-4 mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
 | 
			
		||||
                  <path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99"></path>
 | 
			
		||||
                </svg>
 | 
			
		||||
                <span class="text-sm">{{$t("restore")}}</span>
 | 
			
		||||
                <input id="inputRC" type="file" name="configurationfile" accept="text/*,.json" @change="restoreConfig" class="hidden"/>
 | 
			
		||||
| 
						 | 
				
			
			@ -104,9 +103,8 @@
 | 
			
		|||
              <!-- Backup configuration -->
 | 
			
		||||
              <a href="./api/wireguard/backup" :title="$t('titleBackupConfig')"
 | 
			
		||||
                class="hover:bg-red-800 hover:border-red-800 hover:text-white text-gray-700 dark:text-neutral-200 border-2 border-gray-100 dark:border-neutral-600 py-2 px-4 rounded inline-flex items-center transition">
 | 
			
		||||
                <svg inline class="w-4 mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="-2 -2 18 18" stroke="currentColor">
 | 
			
		||||
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 2H9v3h2z" />
 | 
			
		||||
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1.5 0h11.586a1.5 1.5 0 0 1 1.06.44l1.415 1.414A1.5 1.5 0 0 1 16 2.914V14.5a1.5 1.5 0 0 1-1.5 1.5h-13A1.5 1.5 0 0 1 0 14.5v-13A1.5 1.5 0 0 1 1.5 0M1 1.5v13a.5.5 0 0 0 .5.5H2v-4.5A1.5 1.5 0 0 1 3.5 9h9a1.5 1.5 0 0 1 1.5 1.5V15h.5a.5.5 0 0 0 .5-.5V2.914a.5.5 0 0 0-.146-.353l-1.415-1.415A.5.5 0 0 0 13.086 1H13v4.5A1.5 1.5 0 0 1 11.5 7h-7A1.5 1.5 0 0 1 3 5.5V1H1.5a.5.5 0 0 0-.5.5m3 4a.5.5 0 0 0 .5.5h7a.5.5 0 0 0 .5-.5V1H4zM3 15h10v-4.5a.5.5 0 0 0-.5-.5h-9a.5.5 0 0 0-.5.5z" />
 | 
			
		||||
                <svg inline class="w-4 mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
 | 
			
		||||
                  <path stroke-linecap="round" stroke-linejoin="round" d="M5.25 14.25h13.5m-13.5 0a3 3 0 0 1-3-3m3 3a3 3 0 1 0 0 6h13.5a3 3 0 1 0 0-6m-16.5-3a3 3 0 0 1 3-3h13.5a3 3 0 0 1 3 3m-19.5 0a4.5 4.5 0 0 1 .9-2.7L5.737 5.1a3.375 3.375 0 0 1 2.7-1.35h7.126c1.062 0 2.062.5 2.7 1.35l2.587 3.45a4.5 4.5 0 0 1 .9 2.7m0 0a3 3 0 0 1-3 3m0 3h.008v.008h-.008v-.008Zm0-6h.008v.008h-.008v-.008Zm-3 6h.008v.008h-.008v-.008Zm0-6h.008v.008h-.008v-.008Z"></path>
 | 
			
		||||
                </svg>
 | 
			
		||||
                <span class="text-sm">{{$t("backup")}}</span>
 | 
			
		||||
              </a>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue