Browse Source

Added last IP number selection for new client (auto if empty)

pull/38/head
Raul 5 years ago
parent
commit
b44422441a
  1. 3
      .gitignore
  2. 4
      src/lib/Server.js
  3. 19
      src/lib/WireGuard.js
  4. 18
      src/www/index.html
  5. 4
      src/www/js/api.js
  6. 4
      src/www/js/app.js

3
.gitignore

@ -1 +1,2 @@
/config /config
.idea

4
src/lib/Server.js

@ -99,8 +99,8 @@ module.exports = class Server {
res.send(config); res.send(config);
})) }))
.post('/api/wireguard/client', Util.promisify(async req => { .post('/api/wireguard/client', Util.promisify(async req => {
const { name } = req.body; const { name, number } = req.body;
return WireGuard.createClient({ name }); return WireGuard.createClient({ name, number });
})) }))
.delete('/api/wireguard/client/:clientId', Util.promisify(async req => { .delete('/api/wireguard/client/:clientId', Util.promisify(async req => {
const { clientId } = req.params; const { clientId } = req.params;

19
src/lib/WireGuard.js

@ -202,15 +202,17 @@ Endpoint = ${WG_HOST}:${WG_PORT}`;
const publicKey = await Util.exec(`echo ${privateKey} | wg pubkey`); const publicKey = await Util.exec(`echo ${privateKey} | wg pubkey`);
const preSharedKey = await Util.exec('wg genpsk'); const preSharedKey = await Util.exec('wg genpsk');
// Calculate next IP // IP address operations
let address; let address;
if (!number) {
// Calculate next IP
for (let i = 2; i < 255; i++) { for (let i = 2; i < 255; i++) {
const client = Object.values(config.clients).find(client => { const client = Object.values(config.clients).find(client => {
return client.address === WG_DEFAULT_ADDRESS.replace('x', i); return client.address === WG_DEFAULT_ADDRESS.replace('x', i.toString());
}); });
if (!client) { if (!client) {
address = WG_DEFAULT_ADDRESS.replace('x', i); address = WG_DEFAULT_ADDRESS.replace('x', i.toString());
break; break;
} }
} }
@ -218,6 +220,17 @@ Endpoint = ${WG_HOST}:${WG_PORT}`;
if (!address) { if (!address) {
throw new Error('Maximum number of clients reached.'); throw new Error('Maximum number of clients reached.');
} }
} else {
// Search & use selected number for IP
const client = Object.values(config.clients).find(client => {
return client.address === WG_DEFAULT_ADDRESS.replace('x', number);
});
if (client) {
throw new Error('Number in use, please select another or leave empty.');
}
address = WG_DEFAULT_ADDRESS.replace('x', number);
}
// Create Client // Create Client
const clientId = uuid.v4(); const clientId = uuid.v4();

18
src/www/index.html

@ -35,7 +35,7 @@
<p class="text-2xl font-medium">Clients</p> <p class="text-2xl font-medium">Clients</p>
</div> </div>
<div class="flex-shrink-0"> <div class="flex-shrink-0">
<button @click="clientCreate = true; clientCreateName = '';" <button @click="clientCreate = true; clientCreateName = ''; clientCreateNumber = '';"
class="hover:bg-red-800 hover:border-red-800 hover:text-white text-gray-700 border-2 border-gray-100 py-2 px-4 rounded inline-flex items-center transition"> class="hover:bg-red-800 hover:border-red-800 hover:text-white text-gray-700 border-2 border-gray-100 py-2 px-4 rounded inline-flex items-center transition">
<svg class="w-4 mr-2" inline xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" <svg class="w-4 mr-2" inline xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
stroke="currentColor"> stroke="currentColor">
@ -143,7 +143,7 @@
</div> </div>
<div v-if="clients && clients.length === 0"> <div v-if="clients && clients.length === 0">
<p class="text-center m-10 text-gray-400 text-sm">There are no clients yet.<br /><br /> <p class="text-center m-10 text-gray-400 text-sm">There are no clients yet.<br /><br />
<button @click="clientCreate = true; clientCreateName = '';" <button @click="clientCreate = true; clientCreateName = ''; clientCreateNumber = '';"
class="bg-red-800 text-white hover:bg-red-700 border-2 border-none py-2 px-4 rounded inline-flex items-center transition"> class="bg-red-800 text-white hover:bg-red-700 border-2 border-none py-2 px-4 rounded inline-flex items-center transition">
<svg class="w-4 mr-2" inline xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" <svg class="w-4 mr-2" inline xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
stroke="currentColor"> stroke="currentColor">
@ -232,12 +232,20 @@
type="text" v-model.trim="clientCreateName" placeholder="Name" /> type="text" v-model.trim="clientCreateName" placeholder="Name" />
</p> </p>
</div> </div>
<div class="mt-2">
<p class="text-sm text-gray-500">
<input class="rounded p-2 border-2 border-gray-100 focus:border-gray-200 outline-none w-full"
type="number" min="2" max="254" step="1" v-model="clientCreateNumber"
placeholder="Last number of client IP (optional)"/>
</p>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse"> <div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<button v-if="clientCreateName.length" type="button" @click="createClient(); clientCreate = null" <button v-if="clientCreateName.length && (!clientCreateNumber || (clientCreateNumber > 1 && clientCreateNumber < 255))"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-800 text-base font-medium text-white hover:bg-red-700 focus:outline-none sm:ml-3 sm:w-auto sm:text-sm"> type="button" @click="createClient(); clientCreate = null"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-800 text-base font-medium text-white hover:bg-red-700 focus:outline-none sm:ml-3 sm:w-auto sm:text-sm">
Create Create
</button> </button>
<button v-else type="button" <button v-else type="button"
@ -382,4 +390,4 @@
<script src="/js/app.js"></script> <script src="/js/app.js"></script>
</body> </body>
</html> </html>

4
src/www/js/api.js

@ -65,11 +65,11 @@ class API {
}))); })));
} }
async createClient({ name }) { async createClient({ name, number }) {
return this.call({ return this.call({
method: 'post', method: 'post',
path: '/wireguard/client', path: '/wireguard/client',
body: { name }, body: { name, number },
}); });
} }

4
src/www/js/app.js

@ -17,6 +17,7 @@ new Vue({
clientDelete: null, clientDelete: null,
clientCreate: null, clientCreate: null,
clientCreateName: '', clientCreateName: '',
clientCreateNumber: '',
qrcode: null, qrcode: null,
}, },
methods: { methods: {
@ -80,9 +81,10 @@ new Vue({
}, },
createClient() { createClient() {
const name = this.clientCreateName; const name = this.clientCreateName;
const number = this.clientCreateNumber;
if (!name) return; if (!name) return;
this.api.createClient({ name }) this.api.createClient({ name, number })
.catch(err => alert(err.message || err.toString())) .catch(err => alert(err.message || err.toString()))
.finally(() => this.refresh().catch(console.error)); .finally(() => this.refresh().catch(console.error));
}, },

Loading…
Cancel
Save