From 2028832ccdc93f3f54e6c77ab244a39ca61ff925 Mon Sep 17 00:00:00 2001 From: Keith Irwin Date: Thu, 15 Sep 2022 08:49:45 -0600 Subject: [PATCH] Added admin frontend --- front/admin.js | 112 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/front/admin.js b/front/admin.js index e69de29..c434bd2 100644 --- a/front/admin.js +++ b/front/admin.js @@ -0,0 +1,112 @@ +const API_URL = 'https://wgapi-test-admin-backend.ksn.gf4' + +function Peer(data) { + this.name = data.domain.split('.')[0] + this.pubkey = data.pubkey + this.ipv4 = data.ipv4 + this.ipv6 = data.ipv6 + this.isDeleting = ko.observable(false) + this.deleteText = ko.computed(() => this.isDeleting()?'Deleting...':'Delete') +} + +function PeerList() { + let self = this + self.peers = ko.observableArray([]) + self.newPeerName = ko.observable('') + self.newConfigText = ko.observable('') + self.isAdding = ko.observable(false) + self.addText = ko.computed(() => self.isAdding()?'Adding...':'Add') + + // Initial loading + self.getUser = async () => { + let res; try { + res = await fetch(`${API_URL}/`) + } catch (err) { + if (err) console.error(err) + alert('Failed to contact API and load peers list. Check your wireguard connection. ') + } if (!res.ok) { + if (res.status) console.log(res.status) + alert('Failed to contact API and load peers list. Check your wireguard connection. ') + } else { + let user; try { + user = await res.json() + } catch (err) { + console.error('Failed to parse JSON!') + if (err) console.error(err) + } + self.peers( + user.peers.sort( + (a,b) => a.ipv4.split('.')[3] - b.ipv4.split('.')[3]) + .map( (i)=>new Peer(i)) + ) + self.token = user.token + } + } + + self.addPeer = async () => { + self.isAdding(true) + const validName = self.newPeerName().trim().toLowerCase() + if (validName.length === 0) { + alert('Please enter a hostname.') + self.isAdding(false) + } else if (!/^([\-\_a-z0-9]{3,12})$/.test(validName)) { + alert('Name must be 3-12 alphanumeric chars.') + self.isAdding(false) + } else if (self.peers().map((peer)=>peer.name).includes(validName)) { + alert(`You already have a peer named ${validName}!`) + self.isAdding(false) + } else { + const url = `${API_URL}/?t=${self.token}&name=${validName}` + let res; try { + res = await fetch(url, {method: 'POST'}) + } catch (err) { + alert('Failed to contact server. Are you online?') + if (err) console.error(err) + self.isAdding(false) + } + let parsedRes; try { + parsedRes = await res.text() + } catch (err) { + if (err) console.error(err) + } finally { self.isAdding(false) } + if (!res.ok) { + alert(res.status) + } else { + self.newPeerName('') + self.peers.push(new Peer({domain:`${validName}`})) + self.newConfigText(parsedRes) + } + } + } + // Listen for user hitting enter key + self.addKeyPress = (d,e) => { + if (e.keyCode === 13) self.addPeer() + return true + } + + self.delPeer = async (peer) => { + if (confirm(`Are you sure you want to delete ${peer.name}?`)) { + peer.isDeleting(true) + const url = `${API_URL}/?t=${self.token}&pubkey=${peer.pubkey}` + try { + const res = await fetch(url, {method: 'DELETE'}) + if (res.ok) self.peers.remove(peer) + else { + if (res.status===404) self.peers.remove(peer) + try { + alert(await res.text()) + } catch (err) { + console.error(`Failed to parse DELETE response into text`) + if (err) console.error(err) + } finally { peer.isDeleting(false) } + } + } catch (err) { + alert(`Failed to contact the server. Are you online?`) + } finally { peer.isDeleting(false) } + } + } + + self.getUser() +} + +ko.applyBindings(new PeerList())