Code cleanup

master
wgapi Cloud9 2021-10-21 22:21:59 -06:00
parent 0a6c042b11
commit 37fa81eda4
6 changed files with 194 additions and 170 deletions

View File

@ -12,16 +12,23 @@ const local_secret = env.SERVERS.filter(
)[0].secret
module.exports = async (req, res) => {
// Check secret auth
if (req.query['secret']!==local_secret) {
console.log(`Peer sent from ${req.requester} without correct secret querystring!`)
return res.sendStatus(403)
} else try {
}
// Add request body to wg config
try {
await fs.appendFile(env.WG_CONFIG_FILE, req.body)
} catch (err) {
console.error(`Failed to save new peer config from ${req.requester} to ${env.WG_CONFIG_FILE}`,err)
return res.sendStatus(500)
} finally {
console.log(`Saved new peer from ${req.requester}`)
return res.sendStatus(200)
}
console.log(`Saved new peer from ${req.requester}`)
// Respond
return res.sendStatus(200)
}

View File

@ -19,41 +19,38 @@ module.exports = async (req, res) => {
if (req.query['secret']!==local_secret) {
console.log(`Peer sent from ${req.requester} without correct secret querystring!`)
return res.sendStatus(403)
}
// Read config file
} else try {
else try {
const config_file = await fs.readFile(env.WG_CONFIG_FILE)
config = config_file.toString()
} catch (err) {
}
catch (err) {
console.error(`Failed to load config from ${env.WG_CONFIG_FILE}:\n`,err)
res.sendStatus(500)
} finally {
// Find peer in config
const peer = config.split('\n\n')
.filter( (paragraph) => {
return paragraph.includes('[Peer]')
}).filter( (peer) => {
return peer.includes(`PublicKey = ${req.body}`)
})
// Delete peer
try {
await fs.writeFile(env.WG_CONFIG_FILE,
config.replace(`\n\n${peer}`,'')
.replace('\n\n\n','\n\n')
)
} catch (err) {
console.error(`Failed to delete peer config from ${env.WG_CONFIG_FILE}:\n`,err)
return res.sendStatus(500)
} finally {
// Success
console.log(`Saved new peer from ${req.requester}`)
return res.sendStatus(200)
}
}
// Find peer in config
const peer = config.split('\n\n')
.filter( (paragraph) => {
return paragraph.includes('[Peer]')
}).filter( (peer) => {
return peer.includes(`PublicKey = ${req.body}`)
})
// Delete peer
try { await fs.writeFile(env.WG_CONFIG_FILE,
config.replace(`\n\n${peer}`,'')
.replace('\n\n\n','\n\n')
) }
catch (err) {
console.error(`Failed to delete peer config from ${env.WG_CONFIG_FILE}:\n`,err)
return res.sendStatus(500)
}
// Success
console.log(`Deleted peer by requested from ${req.requester}`)
return res.sendStatus(200)
}

View File

@ -1,5 +1,5 @@
'use strict'
/* add.js
/* app/add.js
* route for a client to add a peer
*/
@ -34,7 +34,7 @@ module.exports = async (req, res) => {
return res.sendStatus(err)
} console.log(`${req.requester} must be ${user.name}`)
// Check user token
// Check token
if (req.query['token']!==helper.getToken(req.requester)) {
console.log(`Invalid token from ${req.requester}: ${req.query['token']}`)
return res.sendStatus(403)
@ -129,7 +129,7 @@ update add *.${domain} ${env.DNS_TTL} CNAME ${domain}`)
console.error(`Failed to add ns record:\n${err}`)
return res.sendStatus(500)
}
finally { console.log(`Updated nameserver to add ${domain}.`) }
console.log(`Updated nameserver to add ${domain}.`)
// Generate user config
const listen_port = Math.floor(50000 + Math.random() * 10000)

View File

@ -1,5 +1,5 @@
'use strict'
/* del.js
/* app/del.js
* route to let clients delete a peer
*/
@ -28,127 +28,120 @@ module.exports = async (req, res) => {
catch (err) {
console.error(`Failed to get user from ${req.requester}`)
return res.sendStatus(err)
} finally {
console.log(`${req.requester} must be ${user.name}`)
// Check user token
if (req.query['token']!==helper.getToken(req.requester)) {
console.log(`Invalid token from ${req.requester}: ${req.query['token']}`)
return res.sendStatus(403)
}
}
console.log(`${req.requester} must be ${user.name}`)
// Load wg.conf
let config_file
try { config_file = await fs.readFile(env.WG_CONFIG_FILE) }
catch (err) { console.error(err); return res.sendStatus(500) }
finally {
// Search for peer
let peer_pubkey
const config = config_file.toString()
const peer = config.split('\n\n')
.filter( (paragraph) => {
return paragraph.includes('[Peer]')
}).filter( (peer) => {
if (req.query['name']) {
return peer.includes(`[Peer] # ${req.query['name']}.`)
} else if (req.query['pubkey']) {
peer_pubkey = req.query['pubkey']
return peer.includes(`PublicKey = ${req.query['pubkey']}`)
} else if (req.query['psk']) {
return peer.includes(`PresharedKey = ${req.query['psk']}`)
} else if (req.query['ip']) {
return peer.split('\n').some( (line) => (
line.includes('AllowedIPs') &&
line.includes(` ${req.query['ip']}/`)
) )
} else if (req.query['privkey']) {
// .filter() doesn't support async so use then/catch in this block
wg.getPubkeyFromPrivkey(req.query['privkey'])
.then((pubkey) => {
peer_pubkey = pubkey
return peer.includes(`PublicKey = ${pubkey}`)
})
.catch((err) => {
console.error(`Failed to generate public key from private key during delete request\n`,err)
return res.sendStatus(500)
})
} else {
console.error(`${req.requester} sent delete request without specifying a peer`)
return res.sendStatus(400)
}
})[0]
if (peer===undefined) {
console.log(`No peer found for delete request from ${req.requester}`)
return res.sendStatus(404)
// Check token
if (req.query['token']!==helper.getToken(req.requester)) {
console.log(`Invalid token from ${req.requester}: ${req.query['token']}`)
return res.sendStatus(403)
}
// Load wg.conf
let config_file
try { config_file = await fs.readFile(env.WG_CONFIG_FILE) }
catch (err) { console.error(err); return res.sendStatus(500) }
// Search for peer
let peer_pubkey
const config = config_file.toString()
const peer = config.split('\n\n')
.filter( (paragraph) => {
return paragraph.includes('[Peer]')
}).filter( (peer) => {
if (req.query['name']) {
return peer.includes(`[Peer] # ${req.query['name']}.`)
} else if (req.query['pubkey']) {
peer_pubkey = req.query['pubkey']
return peer.includes(`PublicKey = ${req.query['pubkey']}`)
} else if (req.query['psk']) {
return peer.includes(`PresharedKey = ${req.query['psk']}`)
} else if (req.query['ip']) {
return peer.split('\n').some( (line) => (
line.includes('AllowedIPs') &&
line.includes(` ${req.query['ip']}/`)
) )
} else if (req.query['privkey']) {
// .filter() doesn't support async so use then/catch in this block
wg.getPubkeyFromPrivkey(req.query['privkey'])
.then((pubkey) => {
peer_pubkey = pubkey
return peer.includes(`PublicKey = ${pubkey}`)
})
.catch((err) => {
console.error(`Failed to generate public key from private key during delete request\n`,err)
return res.sendStatus(500)
})
} else {
console.error(`${req.requester} sent delete request without specifying a peer`)
return res.sendStatus(400)
}
// Parse peer
const peer_lines = peer.split('\n')
const peer_name = peer_lines
.filter( (line) => line.includes('[Peer] # ') )[0]
.split(' # ')[1]
const peer_ips = peer_lines
.filter( (line) => line.includes('AllowedIPs = '))[0]
.split(' = ')[1]
if (peer_pubkey===undefined) {
peer_pubkey = peer_lines
.filter( (line) => line.includes('PublicKey = ') )[0]
.split(' = ')[1]
}
// Make sure requester can't delete self
if (peer_ips.includes(req.requester)) {
console.log(`Refused to let ${req.requester} delete self: ${peer_name}`)
return res.sendStatus(409) // "Conflict"
}
// Delete from local wg config
console.log(`Deleting ${peer_name}`); try {
await fs.writeFile(env.WG_CONFIG_FILE,
config.replace(`\n\n${peer}`,'')
.replace('\n\n\n','\n\n')
)
})[0]
if (peer===undefined) {
console.log(`No peer found for delete request from ${req.requester}`)
return res.sendStatus(404)
}
// Parse peer
const peer_lines = peer.split('\n')
const peer_name = peer_lines
.filter( (line) => line.includes('[Peer] # ') )[0]
.split(' # ')[1]
const peer_ips = peer_lines
.filter( (line) => line.includes('AllowedIPs = '))[0]
.split(' = ')[1]
if (peer_pubkey===undefined) {
peer_pubkey = peer_lines
.filter( (line) => line.includes('PublicKey = ') )[0]
.split(' = ')[1]
}
// Make sure requester can't delete self
if (peer_ips.includes(req.requester)) {
console.log(`Refused to let ${req.requester} delete self: ${peer_name}`)
return res.sendStatus(409) // "Conflict"
}
// Delete from local wg config
console.log(`Deleting ${peer_name}`); try {
await fs.writeFile(env.WG_CONFIG_FILE,
config.replace(`\n\n${peer}`,'')
.replace('\n\n\n','\n\n')
)
} catch (err) {
console.error(`Failed to delete ${peer_name}:\n`,err)
return res.sendStatus(500)
}
// Inform other servers
for (const server of env.SERVERS) {
if (server.host!==env.LOCAL_SERVER) {
try {
console.log(`Informing ${server.host} to delete ${peer_name}`)
await axios.post(`${server.admin_endpoint}/del?secret=${server.secret}`, peer_pubkey, {
headers: {'Content-Type': 'text/plain'},
})
} catch (err) {
console.error(`Failed to delete ${peer_name}:\n`,err)
console.error(`Failed to inform ${server.host} to delete ${peer_name}:\n\n`,err)
return res.sendStatus(500)
} finally {
// Inform other servers
for (const server of env.SERVERS) {
if (server.host!==env.LOCAL_SERVER) {
try {
console.log(`Informing ${server.host} to delete ${peer_name}`)
await axios.post(`${server.admin_endpoint}/del?secret=${server.secret}`, peer_pubkey, {
headers: {'Content-Type': 'text/plain'},
})
} catch (err) {
console.error(`Failed to inform ${server.host} to delete ${peer_name}:\n\n`,err)
return res.sendStatus(500)
}
}
}
// Delete domains from nameserver
try {
await helper.nsUpdate(dns_key, env.DNS_MASTER,
}
}
}
// Delete domains from nameserver
try {
await helper.nsUpdate(dns_key, env.DNS_MASTER,
`update delete ${peer_name}. A
update delete ${peer_name}. AAAA
update delete *.${peer_name}. CNAME`)
}
catch (err) {
console.error(`Failed to delete ns record:\n${err}`)
return res.sendStatus(500)
}
finally { console.log(`Updated nameserver to delete ${peer_name}.`) }
// Inform user that delete was successful
res.sendStatus(200)
}
}
}
catch (err) {
console.error(`Failed to delete ns record`)
if (err) console.error(err)
return res.sendStatus(500)
}
console.log(`Updated nameserver to delete ${peer_name}.`)
return res.sendStatus(200)
}

View File

@ -15,23 +15,17 @@ module.exports = async (req, res) => {
console.error(`Failed to get user from ${req.requester}`)
return res.sendStatus(err)
}
finally {
console.log(`${req.requester} must be ${user.name}`)
// Get or generate token
try { user.token = helper.getToken(req.requester) || await helper.setToken(req.requester) }
catch (err) {
console.error(`Failed to set token for ${req.requester}`)
return res.sendStatus(err)
}
finally {
// Send user
res.setHeader('content-type', 'text/json')
res.send(user)
}
console.log(`${req.requester} must be ${user.name}`)
// Get or generate token
try { user.token = helper.getToken(req.requester) || await helper.setToken(req.requester) }
catch (err) {
console.error(`Failed to set token for ${req.requester}`)
return res.sendStatus(err)
}
// Send user
res.setHeader('content-type', 'text/json')
res.send(user)
}

View File

@ -25,7 +25,7 @@ module.exports = {
}).filter( (peer) => {
return peer.includes(`${env.IPV4_NET}.${subnet}`) || peer.includes(`${env.IPV6_NET}:${subnet}`)
})
} catch (err) { console.log(err) }
} catch (err) { console.log(err); reject(500) }
let found_usernames = []
let found_hosts = []
for (const userpeer of userpeers) {
@ -73,6 +73,39 @@ module.exports = {
}
}),
getAllUsers: () =>
new Promise( async (resolve, reject) => {
let users = {}
let peers; try {
peers = (await fs.readFile(env.WG_CONFIG_FILE)).toString()
.split('\n\n').filter( (paragraph) => {
return paragraph.includes('[Peer]')
})
} catch (err) { console.log(err) }
for (const peer of peers) {
let peer_obj = {}
let peer_username
for (const line of peer.split('\n')) {
if (line.includes('[Peer] # ')) {
const domain = line.split(' # ')[1].split('.')
peer_obj.name = domain[0]
peer_username = domain[1]
}
else if (line.includes('AllowedIPs = ')) {
const ips = line.split('=')[1].split(', ')
peer_obj.ipv4 = ips.filter( (ip) => ip.includes(env.IPV4_NET) )[0].trim()
peer_obj.ipv6 = ips.filter( (ip) => ip.includes(env.IPV6_NET) )[0].trim()
}
}
if (!users[peer_username]) users[peer_username] = {
name: peer_username,
peers: [],
}
users[peer_username].peers.push(peer_obj)
}
resolve(users)
}),
getToken: (ip) => tokens[ip],
setToken: (ip) =>
new Promise ( async (resolve, reject) => {