wagon/front/dashboard.js

146 lines
3.9 KiB
JavaScript
Raw Normal View History

2022-09-12 13:49:18 -06:00
const API_URL = 'http://ksn.gf4:8080'
function Peer(data) {
this.name = ko.observable(data.name)
this.ipv4 = ko.observable(data.ipv4)
this.ipv6 = ko.observable(`:${data.ipv6.split(':').slice(-2).join(':')}`)
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) {
console.error(`Failed to GET ${API_URL}/`)
if (err) console.error(err)
}
if (!res.ok) {
console.log(`Got ${res.status} from GET ${API_URL}/`)
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}/?token=${self.token}`
let res; try {
res = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: validName,
}),
})
} 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(parsedRes)
} else {
self.newPeerName('')
self.newConfigText(parsedRes)
let interfaceLines = parsedRes.split('\n\n').filter(
(paragraph) => paragraph.includes('[Interface]')
)[0].split('\n')
let addresses = interfaceLines.filter(
(line) => line.includes('Address = ')
)[0].split('=')[1].trim().split(', ')
self.peers.push(new Peer({
name: interfaceLines[0]
.split('#')[1].trim().split('.')[0],
ipv4: addresses.filter(
(addr) => addr.includes('10.4.')
)[0].split('/')[0],
ipv6: addresses.filter(
(addr) => addr.includes('fd69:1337:0:420:f4:f4:')
)[0].split('/')[0],
}))
}
}
}
// Listen for user hitting enter key
self.addKeyPress = (d,e) => {
if (e.keyCode === 13) self.addPeer()
return true
}
self.delPeer = async (peer) => {
const name = peer.name()
if (confirm(`Are you sure you want to delete ${name}?`)) {
peer.isDeleting(true)
const url = `${API_URL}/?token=${self.token}`
try {
const res = await fetch(url, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: name,
}),
})
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())