forked from mirrors/amnezia-wg-easy
		
	Fix short link. Generate One Time Link (#1301)
Co-authored-by: Vadim Babadzhanyan <vadim.babadzhanyan@my.games>
This commit is contained in:
		
							parent
							
								
									352a022f30
								
							
						
					
					
						commit
						968d2b90a0
					
				
					 6 changed files with 61 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -132,14 +132,15 @@ module.exports = class Server {
 | 
			
		|||
          authenticated,
 | 
			
		||||
        };
 | 
			
		||||
      }))
 | 
			
		||||
      .get('/:clientHash', defineEventHandler(async (event) => {
 | 
			
		||||
        const clientHash = getRouterParam(event, 'clientHash');
 | 
			
		||||
      .get('/cnf/:clientOneTimeLink', defineEventHandler(async (event) => {
 | 
			
		||||
        const clientOneTimeLink = getRouterParam(event, 'clientOneTimeLink');
 | 
			
		||||
        const clients = await WireGuard.getClients();
 | 
			
		||||
        const client = clients.find((client) => client.hash === clientHash);
 | 
			
		||||
        const client = clients.find((client) => client.oneTimeLink === clientOneTimeLink);
 | 
			
		||||
        if (!client) return;
 | 
			
		||||
        const clientId = client.id;
 | 
			
		||||
        const config = await WireGuard.getClientConfiguration({ clientId });
 | 
			
		||||
        setHeader(event, 'Content-Disposition', `attachment; filename="${clientHash}.conf"`);
 | 
			
		||||
        await WireGuard.eraseOneTimeLink({ clientId });
 | 
			
		||||
        setHeader(event, 'Content-Disposition', `attachment; filename="${clientOneTimeLink}.conf"`);
 | 
			
		||||
        setHeader(event, 'Content-Type', 'text/plain');
 | 
			
		||||
        return config;
 | 
			
		||||
      }))
 | 
			
		||||
| 
						 | 
				
			
			@ -252,6 +253,14 @@ module.exports = class Server {
 | 
			
		|||
        await WireGuard.enableClient({ clientId });
 | 
			
		||||
        return { success: true };
 | 
			
		||||
      }))
 | 
			
		||||
      .post('/api/wireguard/client/:clientId/generateOneTimeLink', defineEventHandler(async (event) => {
 | 
			
		||||
        const clientId = getRouterParam(event, 'clientId');
 | 
			
		||||
        if (clientId === '__proto__' || clientId === 'constructor' || clientId === 'prototype') {
 | 
			
		||||
          throw createError({ status: 403 });
 | 
			
		||||
        }
 | 
			
		||||
        await WireGuard.generateOneTimeLink({ clientId });
 | 
			
		||||
        return { success: true };
 | 
			
		||||
      }))
 | 
			
		||||
      .post('/api/wireguard/client/:clientId/disable', defineEventHandler(async (event) => {
 | 
			
		||||
        const clientId = getRouterParam(event, 'clientId');
 | 
			
		||||
        if (clientId === '__proto__' || clientId === 'constructor' || clientId === 'prototype') {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -152,7 +152,7 @@ ${client.preSharedKey ? `PresharedKey = ${client.preSharedKey}\n` : ''
 | 
			
		|||
        ? new Date(client.expiredAt)
 | 
			
		||||
        : null,
 | 
			
		||||
      allowedIPs: client.allowedIPs,
 | 
			
		||||
      hash: Math.abs(CRC32.str(clientId)).toString(16),
 | 
			
		||||
      oneTimeLink: client.oneTimeLink ? client.oneTimeLink : null,
 | 
			
		||||
      downloadableConfig: 'privateKey' in client,
 | 
			
		||||
      persistentKeepalive: null,
 | 
			
		||||
      latestHandshakeAt: null,
 | 
			
		||||
| 
						 | 
				
			
			@ -306,6 +306,21 @@ Endpoint = ${WG_HOST}:${WG_CONFIG_PORT}`;
 | 
			
		|||
    await this.saveConfig();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async generateOneTimeLink({ clientId }) {
 | 
			
		||||
    const client = await this.getClient({ clientId });
 | 
			
		||||
    const key = `${clientId}-${Math.floor(Math.random() * 1000)}`;
 | 
			
		||||
    client.oneTimeLink = Math.abs(CRC32.str(key)).toString(16);
 | 
			
		||||
    client.updatedAt = new Date();
 | 
			
		||||
    await this.saveConfig();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async eraseOneTimeLink({ clientId }) {
 | 
			
		||||
    const client = await this.getClient({ clientId });
 | 
			
		||||
    client.oneTimeLink = null;
 | 
			
		||||
    client.updatedAt = new Date();
 | 
			
		||||
    await this.saveConfig();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async disableClient({ clientId }) {
 | 
			
		||||
    const client = await this.getClient({ clientId });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -256,8 +256,8 @@
 | 
			
		|||
                          {{!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 v-if="uiShowLinks && client.oneTimeLink !== null && client.oneTimeLink !== ''" :ref="'client-' + client.id + '-link'" class="text-gray-400 text-xs">
 | 
			
		||||
                        <a :href="'./cnf/' + client.oneTimeLink + ''">{{document.location.protocol}}//{{document.location.host}}/cnf/{{client.oneTimeLink}}</a>
 | 
			
		||||
                      </div>
 | 
			
		||||
                      <!-- Expire Date -->
 | 
			
		||||
                      <div v-show="enableExpireTime" class=" block md:inline-block pb-1 md:pb-0 text-gray-500 dark:text-neutral-400 text-xs">
 | 
			
		||||
| 
						 | 
				
			
			@ -384,6 +384,22 @@
 | 
			
		|||
                      </svg>
 | 
			
		||||
                    </a>
 | 
			
		||||
 | 
			
		||||
                    <!-- Short OneTime Link -->
 | 
			
		||||
                    <button v-if="uiShowLinks" :disabled="!client.downloadableConfig"
 | 
			
		||||
                      class="align-middle inline-block bg-gray-100 dark:bg-neutral-600 dark:text-neutral-300 p-2 rounded transition"
 | 
			
		||||
                      :class="{
 | 
			
		||||
                        'hover:bg-red-800 dark:hover:bg-red-800 hover:text-white dark:hover:text-white': client.downloadableConfig,
 | 
			
		||||
                        'is-disabled': !client.downloadableConfig
 | 
			
		||||
                      }"
 | 
			
		||||
                      :title="!client.downloadableConfig ? $t('noPrivKey') : $t('OneTimeLink')"
 | 
			
		||||
                      @click="if(client.downloadableConfig) { showOneTimeLink(client); }">
 | 
			
		||||
                      <svg class="w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
 | 
			
		||||
                        stroke="currentColor">
 | 
			
		||||
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
 | 
			
		||||
                          d="M13.213 9.787a3.391 3.391 0 0 0-4.795 0l-3.425 3.426a3.39 3.39 0 0 0 4.795 4.794l.321-.304m-.321-4.49a3.39 3.39 0 0 0 4.795 0l3.424-3.426a3.39 3.39 0 0 0-4.794-4.795l-1.028.961"/>
 | 
			
		||||
                      </svg>
 | 
			
		||||
                    </button>
 | 
			
		||||
 | 
			
		||||
                    <!-- Delete -->
 | 
			
		||||
 | 
			
		||||
                    <button
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -132,6 +132,13 @@ class API {
 | 
			
		|||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async showOneTimeLink({ clientId }) {
 | 
			
		||||
    return this.call({
 | 
			
		||||
      method: 'post',
 | 
			
		||||
      path: `/wireguard/client/${clientId}/generateOneTimeLink`,
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async enableClient({ clientId }) {
 | 
			
		||||
    return this.call({
 | 
			
		||||
      method: 'post',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -312,6 +312,11 @@ new Vue({
 | 
			
		|||
        .catch((err) => alert(err.message || err.toString()))
 | 
			
		||||
        .finally(() => this.refresh().catch(console.error));
 | 
			
		||||
    },
 | 
			
		||||
    showOneTimeLink(client) {
 | 
			
		||||
      this.api.showOneTimeLink({ clientId: client.id })
 | 
			
		||||
        .catch((err) => alert(err.message || err.toString()))
 | 
			
		||||
        .finally(() => this.refresh().catch(console.error));
 | 
			
		||||
    },
 | 
			
		||||
    enableClient(client) {
 | 
			
		||||
      this.api.enableClient({ clientId: client.id })
 | 
			
		||||
        .catch((err) => alert(err.message || err.toString()))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,7 @@ const messages = { // eslint-disable-line no-unused-vars
 | 
			
		|||
    sort: 'Sort',
 | 
			
		||||
    ExpireDate: 'Expire Date',
 | 
			
		||||
    Permanent: 'Permanent',
 | 
			
		||||
    OneTimeLink: 'Generate short one time link',
 | 
			
		||||
  },
 | 
			
		||||
  ua: {
 | 
			
		||||
    name: 'Ім`я',
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +113,7 @@ const messages = { // eslint-disable-line no-unused-vars
 | 
			
		|||
    sort: 'Сортировка',
 | 
			
		||||
    ExpireDate: 'Дата истечения срока',
 | 
			
		||||
    Permanent: 'Бессрочно',
 | 
			
		||||
    OneTimeLink: 'Создать короткую одноразовую ссылку',
 | 
			
		||||
  },
 | 
			
		||||
  tr: { // Müslüm Barış Korkmazer @babico
 | 
			
		||||
    name: 'İsim',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue