diff options
Diffstat (limited to 'api')
39 files changed, 529 insertions, 148 deletions
diff --git a/api/config.js b/api/config.js index 41eb9dd..82f90b8 100644 --- a/api/config.js +++ b/api/config.js @@ -18,11 +18,14 @@ const config = { blocksFile : env.AK_ZBLOCKSFILE, pairsFile : env.AK_ZPAIRSFILE, peersFile : env.AK_ZPEERSFILE, + peersDir : env.AK_ZPEERSDIR, cacheDir : env.AK_CACHEDIR, + ipfsArtifactsDir: `${env.AK_WORKDIR}/ipfs_artifacts`, minedBlocksDir: env.AK_MINEDBLOCKSDIR, chunksDir: env.AK_CHUNKSDIR, leafsDir: env.AK_LEAFSDIR, mapsDir: env.AK_MAPSDIR, - printDebug: env.AK_DEBUG + printDebug: env.AK_DEBUG, + akNSDir: `${env.AK_WORKDIR}/akns` } module.exports = config; diff --git a/api/index.js b/api/index.js index d1a18a6..6fd2066 100755 --- a/api/index.js +++ b/api/index.js @@ -1,23 +1,34 @@ const http = require("node:http"); +// Route functions const welcomeMessage = require("./routes/default/index.js"); +const getAKNSKey = require("./routes/getAKNSKey/index.js"); +const getAKNSKeyFromBase = require("./routes/getAKNSKeyFromBase/index.js"); const getNodeInfo = require('./routes/getNodeInfo/index.js'); const getPeers = require('./routes/getPeers/index.js'); -const getZblock = require('./routes/getZblock/index.js'); +const getIPFSHash = require('./routes/getIPFSHash/index.js'); const getZlatest = require('./routes/getZLatest/index.js'); const getSblock = require('./routes/getSBlock/index.js'); const getChunk = require('./routes/getChunk/index.js'); const getLeaf = require('./routes/getLeaf/index.js'); const getMap = require('./routes/getMap/index.js'); const getSlatest = require('./routes/getSLatest/index.js'); +const getRemoteNodeInfo = require('./routes/getRemoteNodeInfo/index.js'); +const getRemotePeers = require('./routes/getRemotePeers/index.js'); +// Libraries const akLogMessage = require('./lib/akLogMessage'); +const checkIfAllowedIP = require('./lib/checkIfAllowedIP/index.js'); +const storeIncomingIP = require("./lib/storeIncomingIP/index.js"); +akLogMessage('INFO', 'akLogMessage loaded'); const serverOptions = { keepAliveTimeout: 60000 }; function printRequest(req) { + storeIncomingIP(req.connection.remoteAddress); console.log(req.connection.remoteAddress); + console.log(req.headers.host); console.log(req.headers); console.log(req.method, req.url); console.log('HTTP/' + req.httpVersion); @@ -51,13 +62,18 @@ function getRoutes(req, res) case 'root': testRootRoute(req, res); break; case 'peers': getPeers(req, res); break; case 'node_info': getNodeInfo(req, res); break; - case 'zblock': getZblock(req, res); break; + case 'ipfs_hash': getIPFSHash(req, res); break; + case 'ipfs': getIPFSHash(req, res); break; case 'zlatest': getZlatest(req, res); break; case 'sblock': getSblock(req, res); break; case 'slatest': getSlatest(req, res); break; case 'chunk': getChunk(req, res); break; case 'leaf': getLeaf(req, res); break; case 'map': getMap(req, res); break; + case 'remote_node_info': getRemoteNodeInfo(req, res); break; + case 'remote_peers': getRemotePeers(req, res); break; + case 'ns_get': getAKNSKey(req, res); break; + case 'ns_get_base': getAKNSKeyFromBase(req, res); break; default: notImplemented(req, res); } } @@ -93,11 +109,6 @@ function processMethod(req, res) } } -function checkIfAllowedIP(address) -{ - return address.startsWith('fc') ? true : false; -} - function requestParser(req, res) { printRequest(req); diff --git a/api/lib/akLogMessage/index.js b/api/lib/akLogMessage/index.js index 0df974a..59a1300 100644 --- a/api/lib/akLogMessage/index.js +++ b/api/lib/akLogMessage/index.js @@ -1,10 +1,11 @@ const { spawn } = require('child_process'); const config = require('../../config') -module.exports = (type, message) => { +function akLogMessage(type, message) +{ const command = spawn( - "ak", - ["log", "-m", "ak-daemon", type, message] + "ak-log", + ["-m", "ak-daemon", type, message] ); var buffer = ""; @@ -20,9 +21,10 @@ module.exports = (type, message) => { console.log(`error: ${error.message}`); }); - command.on("close", code => { - // res.send(JSON.parse(buffer)); + command.on("close", (code) => { + console.log(buffer); if (config.printDebug === "yes") console.log(buffer); console.log(`child process exited with code ${code}`); }); }; +module.exports = akLogMessage; diff --git a/api/lib/checkIfAllowedIP/index.js b/api/lib/checkIfAllowedIP/index.js new file mode 100644 index 0000000..2e50418 --- /dev/null +++ b/api/lib/checkIfAllowedIP/index.js @@ -0,0 +1,9 @@ +function checkIfAllowedIP(address) +{ + var test_cjdns = /^fc[0-9a-z]{1,2}:([0-9a-z]{1,4}:){1,6}[0-9a-z]{1,4}/ + var test_yggdrasil = /^2[0-9a-z]{1,2}:([0-9a-z]{1,4}:){1,6}[0-9a-z]{1,4}/ + var test_yggdrasil_sub = /^3[0-9a-z]{1,2}:([0-9a-z]{1,4}:){1,6}[0-9a-z]{1,4}/ + return (test_cjdns.test(address) || test_yggdrasil.test(address) || test_yggdrasil_sub.test(address)) ? true : false; +}; + +module.exports = checkIfAllowedIP; diff --git a/api/lib/storeIncomingIP/index.js b/api/lib/storeIncomingIP/index.js new file mode 100644 index 0000000..72273d0 --- /dev/null +++ b/api/lib/storeIncomingIP/index.js @@ -0,0 +1,8 @@ +const fs = require("node:fs"); +const config = require("../../config"); + +function storeIncomingIP(ip_address) +{ + fs.appendFileSync(`${config.peersDir}/incomingRequests`, `${ip_address}\n`); +} +module.exports = storeIncomingIP; diff --git a/api/make_cache.sh b/api/make_cache.sh index c075f27..cce86bd 100755 --- a/api/make_cache.sh +++ b/api/make_cache.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash ak schain --get-latest > $AK_CACHEDIR/ak-find-latest-mined-sblock.json ak zchain --crawl > $AK_CACHEDIR/ak-get-chain-minified.json ak zchain --get-latest > $AK_CACHEDIR/ak-get-zlatest.json diff --git a/api/routes/announceZBlock/index.js b/api/routes/announceZBlock/index.js index 254e1dc..dc1467a 100644 --- a/api/routes/announceZBlock/index.js +++ b/api/routes/announceZBlock/index.js @@ -13,7 +13,8 @@ * */ const getvalidity = require('../../validators/ZblockValidator') -module.exports = (req, res) => { +function announceZBlock(req, res) +{ console.log(req); if ( (req.body.zblock) && typeof req.body.zblock === "string" && req.body.zblock.length === 46 ){ let zblock = req.body.zblock; @@ -27,3 +28,4 @@ module.exports = (req, res) => { res.send({error:"Invalid data"}); } } +module.exports = announceZBlock; diff --git a/api/routes/announceZChain/index.js b/api/routes/announceZChain/index.js index 0261aa4..ca23a72 100644 --- a/api/routes/announceZChain/index.js +++ b/api/routes/announceZChain/index.js @@ -14,7 +14,8 @@ */ const getNSvalidity = require('../../validators/ZchainValidator'); -module.exports = (req, res) => { +function announceZChain(req, res) +{ console.log(req); if ( (req.body.zchain) && typeof req.body.zchain === "string" && req.body.zchain.length === 62 ){ let zchain = req.body.zchain; @@ -30,3 +31,4 @@ module.exports = (req, res) => { res.end(JSON.stringify({error:"Invalid data"})); } } +module.exports = announceZChain; diff --git a/api/routes/default/index.js b/api/routes/default/index.js index 6cdb5f4..db1495f 100644 --- a/api/routes/default/index.js +++ b/api/routes/default/index.js @@ -1,7 +1,8 @@ const rsettings = require('../../settings'); const settings = rsettings(); -module.exports = (req, res) => { +function welcome(req, res) +{ res.writeHead(404, { 'Content-Type': 'application/json'}); res.end(JSON.stringify({ message:"Hello! Welcome to Arching Kaos API! See available routes below!", @@ -9,20 +10,31 @@ module.exports = (req, res) => { routes:{ GET:[ - {welcome:settings.DEF_PROTO+"["+settings.LOCAL_IP+"]:"+settings.PORT+"/"}, - {gathered_zblocks:settings.DEF_PROTO+"["+settings.LOCAL_IP+"]:"+settings.PORT+settings.URL_PREFIX+"/see"}, - {node_local_chain:settings.DEF_PROTO+"["+settings.LOCAL_IP+"]:"+settings.PORT+settings.URL_PREFIX+"/chain"}, - {node_local_peers:settings.DEF_PROTO+"["+settings.LOCAL_IP+"]:"+settings.PORT+settings.URL_PREFIX+"/peers"}, - {node_local_info:settings.DEF_PROTO+"["+settings.LOCAL_IP+"]:"+settings.PORT+settings.URL_PREFIX+"/node_info"}, - {node_local_zlatest:settings.DEF_PROTO+"["+settings.LOCAL_IP+"]:"+settings.PORT+settings.URL_PREFIX+"/zlatest"}, - {latest_known_mined_block:settings.DEF_PROTO+"["+settings.LOCAL_IP+"]:"+settings.PORT+settings.URL_PREFIX+"/slatest"}, - {show_mined_block:settings.DEF_PROTO+"["+settings.LOCAL_IP+"]:"+settings.PORT+settings.URL_PREFIX+"/sblock"}, - {getMerkleTree:settings.DEF_PROTO+"["+settings.LOCAL_IP+"]:"+settings.PORT+settings.URL_PREFIX+"/mrk/:mkr"}, + {welcome:settings.DEF_PROTO+req.headers.host+"/"}, + {peers:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/peers"}, + {node_info:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/node_info"}, + {ipfs_hash:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/ipfs_hash/<hash>"}, + {zlatest:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/zlatest"}, + {sblock:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/sblock/<hash>"}, + {slatest:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/slatest"}, + {chunk:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/chunk/<hash>"}, + {leaf:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/leaf/<hash>"}, + {map:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/map/<hash>"}, ], - POST:[ - {send_me_a_zblock:settings.DEF_PROTO+"["+settings.LOCAL_IP+"]:"+settings.PORT+settings.URL_PREFIX+"/announce/zblock"}, + oldGET:[ + {gathered_zblocks:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/see"}, + {node_local_chain:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/chain"}, + {node_local_peers:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/peers"}, + {node_local_info:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/node_info"}, + {node_local_zlatest:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/zlatest"}, + {latest_known_mined_block:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/slatest"}, + {show_mined_block:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/sblock"}, + {getMerkleTree:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/mrk/:mkr"}, + ], + oldPOST:[ + {send_me_a_zblock:settings.DEF_PROTO+req.headers.host+settings.URL_PREFIX+"/announce/zblock"}, ] } })); } - +module.exports = welcome; diff --git a/api/routes/getAKNSKey/index.js b/api/routes/getAKNSKey/index.js new file mode 100644 index 0000000..5e78f81 --- /dev/null +++ b/api/routes/getAKNSKey/index.js @@ -0,0 +1,75 @@ +const { spawn } = require('child_process'); +const fs = require('fs'); +const config = require("../../config.js"); + +/* + * Gets the local latest zblock AKA zlatest + * + * Returns: + * - JSON object + * { zlatest: "Qm..." } + * + */ +function replyIfOkay(key, res) +{ + const program = "ak-ns"; + const command = spawn(program, ["-rj", key]); + var buffer = ""; + command.stdout.on("data", data => { + buffer += data; + }); + command.stderr.on("data", data => { + console.log(`stderr: ${data}`); + }); + command.on('error', (error) => { + console.log(`error: ${error.message}`); + }); + command.on("close", code => { + console.log(`child process ${program} exited with code ${code}`); + if (code === 0){ + buffer = buffer.trim() + res.writeHead(200, {'Content-Type': 'application/json'}); + res.end(`${buffer}`); + } else { + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end({"error":"unreachable"}); + } + }); +} + +function getAKNSKey(req, res) +{ + var args = req.url.split("/"); + var key = args[3]; + regex= /[a-fA-F0-9]{40}/ + if (regex.test(key)) + { + key = key.toUpperCase(); + var path = config.akNSDir+"/"+key; + try + { + if(fs.existsSync(path)) + { + replyIfOkay(key, res) + } + else + { + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({"error":"not found"})); + } + } + catch (error) + { + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({"error":error.message})); + } + } + else + { + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({error:"No hash"})); + } +} + +module.exports = getAKNSKey; + diff --git a/api/routes/getAKNSKeyFromBase/index.js b/api/routes/getAKNSKeyFromBase/index.js new file mode 100644 index 0000000..7da3d9b --- /dev/null +++ b/api/routes/getAKNSKeyFromBase/index.js @@ -0,0 +1,91 @@ +const { spawn } = require('child_process'); +const fs = require('fs'); +const config = require("../../config.js"); + +/* + * Gets the local latest zblock AKA zlatest + * + * Returns: + * - JSON object + * { zlatest: "Qm..." } + * + */ +function decodeBase64ToHex(base64String) { + // Decode the Base64 string + const binaryString = atob(base64String); + + // Convert the binary string to a byte array + const byteArray = new Uint8Array(binaryString.length); + for (let i = 0; i < binaryString.length; i++) { + byteArray[i] = binaryString.charCodeAt(i); + } + + // Convert the byte array to a hex string representation + return Array.from(byteArray) + .map(byte => byte.toString(16).padStart(2, '0')) // Convert to hex and pad with zeros + .join(''); // Join with spaces for readability +} + +// Example usage + + +function replyIfOkay(key, res) +{ + const program = "ak-ns"; + const base64String = key; + const decodedHexString = decodeBase64ToHex(base64String); + formatted_key = decodedHexString.toUpperCase(); + const command = spawn(program, ["-rj", `${formatted_key}`]); + + var buffer = ""; + command.stdout.on("data", data => { + buffer += data; + }); + command.stderr.on("data", data => { + console.log(`stderr: ${data}`); + }); + command.on('error', (error) => { + console.log(`error: ${error.message}`); + }); + command.on("close", code => { + console.log(`child process ${program} exited with code ${code}`); + if (code === 0){ + buffer = buffer.trim() + res.writeHead(200, {'Content-Type': 'application/json'}); + res.end(`${buffer}`); + } else { + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({error:"unreachable"})); + } + }); +} + +function getAKNSKeyFromBase(req, res) +{ + var args = req.url.split("/"); + var key = args[3]; + regex= /[a-zA-Z0-9+\/=]{29}/ + const base64Regex = /^[A-Z0-9+\/=]{28}/i; + if (base64Regex.test(key)) + { + // key = key.toUpperCase(); + // var path = config.akNSDir+"/"+key; + try + { + replyIfOkay(key, res) + } + catch (error) + { + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({"error":error.message})); + } + } + else + { + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({error:"No hash"})); + } +} + +module.exports = getAKNSKeyFromBase; + diff --git a/api/routes/getChunk/index.js b/api/routes/getChunk/index.js index d848ce9..dc86bd8 100644 --- a/api/routes/getChunk/index.js +++ b/api/routes/getChunk/index.js @@ -7,7 +7,8 @@ const fs = require('fs'); const config = require("../../config.js"); -module.exports = (req, res) => { +function getChunk(req, res) +{ var args = req.url.split("/"); var hash = args[3]; regex= /[a-f0-9]{128}/ @@ -18,12 +19,19 @@ module.exports = (req, res) => { { if(fs.existsSync(path)) { - res.send(fs.readFileSync(path)); + res.writeHead(200, {'Content-Type': 'application/json'}); + res.end(fs.readFileSync(path)); + } + else + { + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({"error":"not found"})); } } catch (error) { - res.send({"error":error.message}); + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({"error":error.message})); } } else @@ -32,4 +40,4 @@ module.exports = (req, res) => { res.end(JSON.stringify({error:"No hash"})); } } - +module.exports = getChunk; diff --git a/api/routes/getIPFSHash/index.js b/api/routes/getIPFSHash/index.js new file mode 100644 index 0000000..d1bdc5f --- /dev/null +++ b/api/routes/getIPFSHash/index.js @@ -0,0 +1,76 @@ +const { spawn } = require('child_process'); +const fs = require("fs"); +const config = require("../../config"); +const akLogMessage = require("../../lib/akLogMessage"); +akLogMessage('lol'); + +/* + * Returns a cached ipfs_hash + * + * Returns: + * - JSON object + * + */ +function fetchIPFShash(ipfs_hash, res) +{ + regex= /Qm[A-Za-z0-9]{44}/; + if (regex.test(ipfs_hash)){ + const path = `${config.ipfsArtifactsDir}/${ipfs_hash}`; + console.log(path) + try + { + if(fs.existsSync(path)) + { + res.writeHead(200); //, {'Content-Type': 'application/json'}); + // res.end(JSON.stringify(JSON.parse(fs.readFileSync(path)))); + res.end(fs.readFileSync(path)); + } + else + { + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({error:"invalid or unreachable"})); + } + } + catch (error) + { + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({error:error.message})); + } + } + else + { + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({error:"Invalid data: regexp failed to pass"})); + } +}; + +function getIPFSHash(req, res) +{ + var args = req.url.split("/"); + if ( (args[2] === 'ipfs_hash'||args[2] === 'ipfs') && args[3] && typeof args[3] === "string" && args[3].length === 46 ){ + regex= /Qm[A-Za-z0-9]{44}/; + if (regex.test(args[3])) + { + if (args[3] === "QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH" ) + { + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({error:"Genesis block"})); + } + else + { + fetchIPFShash(args[3],res); + } + } + else + { + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({error:"Invalid data: regexp failed to pass"})); + } + } + else + { + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({error:"Invalid data: no valid ipfs_hash was provided"})); + } +} +module.exports = getIPFSHash; diff --git a/api/routes/getInnerIPFSContent/index.js b/api/routes/getInnerIPFSContent/index.js index 721e836..a45b507 100644 --- a/api/routes/getInnerIPFSContent/index.js +++ b/api/routes/getInnerIPFSContent/index.js @@ -15,7 +15,8 @@ function fetchZblock(zblock, res){ res.end(JSON.stringify(JSON.parse(fs.readFileSync(path)))); }; -module.exports = (req, res) => { +function getInnerIPFSContent(req, res) +{ console.log(req.query) if ( (req.query.ipfs) && typeof req.query.ipfs === "string" && req.query.ipfs.length === 46 ){ let ipfs = req.query.ipfs; @@ -36,3 +37,4 @@ module.exports = (req, res) => { res.end(JSON.stringify({error:"Invalid data: no valid zblock was provided"})); } } +module.exports = getInnerIPFSContent; diff --git a/api/routes/getLeaf/index.js b/api/routes/getLeaf/index.js index 593d52a..5afbe70 100644 --- a/api/routes/getLeaf/index.js +++ b/api/routes/getLeaf/index.js @@ -7,7 +7,8 @@ const fs = require('fs'); const config = require("../../config.js"); -module.exports = (req, res) => { +function getLeaf(req, res) +{ var args = req.url.split("/"); var hash = args[3]; regex= /[a-f0-9]{128}/ @@ -18,12 +19,19 @@ module.exports = (req, res) => { { if(fs.existsSync(path)) { - res.send(fs.readFileSync(path)); + res.writeHead(200, {'Content-Type': 'application/json'}); + res.end(fs.readFileSync(path)); + } + else + { + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({"error":"not found"})); } } catch (error) { - res.send({"error":error.message}); + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({"error":error.message})); } } else @@ -33,3 +41,4 @@ module.exports = (req, res) => { } } +module.exports = getLeaf; diff --git a/api/routes/getMap/index.js b/api/routes/getMap/index.js index fa834ab..23b4e58 100644 --- a/api/routes/getMap/index.js +++ b/api/routes/getMap/index.js @@ -7,7 +7,8 @@ const fs = require('fs'); const config = require("../../config.js"); -module.exports = (req, res) => { +function getMap(req, res) +{ var args = req.url.split("/"); var hash = args[3]; regex= /[a-f0-9]{128}/ @@ -18,12 +19,19 @@ module.exports = (req, res) => { { if(fs.existsSync(path)) { - res.send(fs.readFileSync(path)); + res.writeHead(200, {'Content-Type': 'application/json'}); + res.end(fs.readFileSync(path)); + } + else + { + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({"error":"not found"})); } } catch (error) { - res.send({"error":error.message}); + res.writeHead(404, {'Content-Type': 'application/json'}); + res.end(JSON.stringify({"error":error.message})); } } else @@ -32,4 +40,4 @@ module.exports = (req, res) => { res.end(JSON.stringify({error:"No hash"})); } } - +module.exports = getMap; diff --git a/api/routes/getNodeInfo/index.js b/api/routes/getNodeInfo/index.js index d99382a..b267749 100644 --- a/api/routes/getNodeInfo/index.js +++ b/api/routes/getNodeInfo/index.js @@ -1,11 +1,11 @@ const { spawn } = require('child_process'); -const akLogMessage = require('../../lib/akLogMessage'); -module.exports = (req, res) => { - akLogMessage('INFO', `Incoming from [${req.connection.remoteAddress}]:${req.socket._peername.port} @ ${req.url}`); +function getNodeInfo(req, res) +{ const command = spawn("ak-config", ["--get-published"]); var buffer = ""; command.stdout.on("data", data => { + console.log(`stdout: ${data}`); buffer = buffer + data; }); @@ -23,3 +23,4 @@ module.exports = (req, res) => { console.log(`child process exited with code ${code}`); }); }; +module.exports = getNodeInfo; diff --git a/api/routes/getPeers/index.js b/api/routes/getPeers/index.js index b18a015..47c075d 100644 --- a/api/routes/getPeers/index.js +++ b/api/routes/getPeers/index.js @@ -1,7 +1,8 @@ const config = require('../../config'); const fs = require('fs'); -module.exports = (req, res) => { +function getPeers(req, res) +{ const path = config.peersFile; if(fs.existsSync(path)){ res.writeHead(200, {'Content-Type': 'application/json'}); @@ -11,3 +12,4 @@ module.exports = (req, res) => { res.end({"error":"No peers :("}) } }; +module.exports = getPeers; diff --git a/api/routes/getRemoteNodeInfo/index.js b/api/routes/getRemoteNodeInfo/index.js new file mode 100644 index 0000000..4b766c0 --- /dev/null +++ b/< |
