From d0b7f57a9166cee5abcbebf193662724f45fdf4c Mon Sep 17 00:00:00 2001 From: Tadeas Kmenta Date: Mon, 31 Jan 2022 23:09:26 +0700 Subject: [PATCH 01/41] multiport support init --- HomeUI/src/views/apps/MyFluxShare.vue | 10 ++- README.md | 2 +- ZelBack/src/routes.js | 2 +- ZelBack/src/services/appsService.js | 4 +- ZelBack/src/services/fluxCommunication.js | 87 ++++++++++++----------- ZelBack/src/services/fluxService.js | 6 +- apiServer.js | 8 ++- app.js | 13 ++-- homeServer.js | 8 ++- init.js | 4 +- package.json | 4 +- sampleUserConfig.js | 2 + 12 files changed, 89 insertions(+), 61 deletions(-) diff --git a/HomeUI/src/views/apps/MyFluxShare.vue b/HomeUI/src/views/apps/MyFluxShare.vue index d9c7825fb..42e8f68b0 100644 --- a/HomeUI/src/views/apps/MyFluxShare.vue +++ b/HomeUI/src/views/apps/MyFluxShare.vue @@ -342,6 +342,8 @@ export default { }, computed: { ...mapState('flux', [ + 'userconfig', + 'config', ]), percentage() { const perc = (this.storage.used / this.storage.total) * 100; @@ -367,11 +369,12 @@ export default { return filteredFolder.filter((data) => data.name !== '.gitkeep'); }, getUploadFolder() { + const port = this.userconfig.apiPort || this.config.apiPort; if (this.currentFolder) { const folder = encodeURIComponent(this.currentFolder); - return `${this.ipAddress}:16127/apps/fluxshare/uploadfile/${folder}`; + return `${this.ipAddress}:${port}/apps/fluxshare/uploadfile/${folder}`; } - return `${this.ipAddress}:16127/apps/fluxshare/uploadfile`; + return `${this.ipAddress}:${port}/apps/fluxshare/uploadfile`; }, }, mounted() { @@ -638,7 +641,8 @@ export default { return true; }, createfluxshareLink(name, token) { - return `${this.ipAddress}:16127/apps/fluxshare/getfile/${name}?token=${token}`; + const port = this.userconfig.apiPort || this.config.apiPort; + return `${this.ipAddress}:${port}/apps/fluxshare/getfile/${name}?token=${token}`; }, copyLinkToClipboard(link) { const el = document.createElement('textarea'); diff --git a/README.md b/README.md index 231fb738b..176a8455a 100644 --- a/README.md +++ b/README.md @@ -188,7 +188,7 @@ sudo yum install git git clone https://github.com/runonflux/flux ``` -Allow Inbound Connections on UFW firewall (ONLY if ufw enabled): +Allow Inbound Connections on UFW firewall - default ports (ONLY if ufw enabled): ```bash sudo ufw allow 16126/tcp diff --git a/ZelBack/src/routes.js b/ZelBack/src/routes.js index bea1931b5..d3bc1533a 100644 --- a/ZelBack/src/routes.js +++ b/ZelBack/src/routes.js @@ -247,7 +247,7 @@ module.exports = (app, expressWs) => { app.get('/flux/incomingconnectionsinfo', cache('30 seconds'), (req, res) => { fluxCommunication.getIncomingConnectionsInfo(req, res, expressWs.getWss('/ws/flux')); }); - app.get('/flux/checkfluxavailability/:ip?', cache('30 seconds'), (req, res) => { + app.get('/flux/checkfluxavailability/:ip?/:port?', cache('30 seconds'), (req, res) => { fluxCommunication.checkFluxAvailability(req, res); }); diff --git a/ZelBack/src/services/appsService.js b/ZelBack/src/services/appsService.js index 538d7a446..4fd4c6a88 100644 --- a/ZelBack/src/services/appsService.js +++ b/ZelBack/src/services/appsService.js @@ -5424,9 +5424,10 @@ async function trySpawningGlobalApplication() { if (myIP === null) { throw new Error('Unable to detect Flux IP address'); } + myIP = myIP.split(':')[0]; // just IP // check if app not running on this device if (runningAppList.find((document) => document.ip === myIP)) { - log.info(`Application ${randomApp} is reported as already running on this Flux`); + log.info(`Application ${randomApp} is reported as already running on this IP`); await serviceHelper.delay(adjustedDelay); trySpawningGlobalAppCache.set(randomApp, randomApp); trySpawningGlobalApplication(); @@ -5570,6 +5571,7 @@ async function checkAndNotifyPeersOfRunningApps() { if (myIP === null) { throw new Error('Unable to detect Flux IP address'); } + myIP = myIP.split(':')[0]; // just IP address // get list of locally installed apps. Store them in database as running and send info to our peers. // check if they are running? const installedAppsRes = await installedApps(); diff --git a/ZelBack/src/services/fluxCommunication.js b/ZelBack/src/services/fluxCommunication.js index cceb4860b..7d962517a 100644 --- a/ZelBack/src/services/fluxCommunication.js +++ b/ZelBack/src/services/fluxCommunication.js @@ -83,9 +83,9 @@ class TokenBucket { let addingNodesToCache = false; // basic check for a version of other flux. -async function isFluxAvailable(ip) { +async function isFluxAvailable(ip, port = config.server.apiport) { try { - const fluxResponse = await serviceHelper.axiosGet(`http://${ip}:${config.server.apiport}/flux/version`, axiosConfig); + const fluxResponse = await serviceHelper.axiosGet(`http://${ip}:${port}/flux/version`, axiosConfig); if (fluxResponse.data.status === 'success') { let fluxVersion = fluxResponse.data.data; fluxVersion = fluxVersion.replace(/\./g, ''); @@ -104,12 +104,14 @@ async function isFluxAvailable(ip) { async function checkFluxAvailability(req, res) { let { ip } = req.params; ip = ip || req.query.ip; + let { port } = req.params; + port = port || req.query.port; if (ip === undefined || ip === null) { const errMessage = serviceHelper.createErrorMessage('No ip specified.'); return res.json(errMessage); } - const available = await isFluxAvailable(ip); + const available = await isFluxAvailable(ip, port); if (available === true) { const message = serviceHelper.createSuccessMessage('Asking Flux is available'); @@ -121,7 +123,7 @@ async function checkFluxAvailability(req, res) { return res.json(response); } -async function getMyFluxIP() { +async function getMyFluxIPandPort() { const benchmarkResponse = await daemonService.getBenchmarks(); let myIP = null; if (benchmarkResponse.status === 'success') { @@ -842,7 +844,7 @@ async function broadcastMessageFromUserPost(req, res) { }); } -async function getRandomConnection() { +async function getRandomConnection() { // returns ip:port or just ip if default const nodeList = await deterministicFluxList(); const zlLength = nodeList.length; if (zlLength === 0) { @@ -857,14 +859,20 @@ async function getRandomConnection() { return ip; } -async function initiateAndHandleConnection(ip) { - const wsuri = `ws://${ip}:${config.server.apiport}/ws/flux/`; +async function initiateAndHandleConnection(connection) { + let ip = connection; + let port = config.server.apiport; + if (connection.includes(':')) { + ip = connection.split(':')[0]; + port = connection.split(':')[1]; + } + const wsuri = `ws://${ip}:${port}/ws/flux/`; const websocket = new WebSocket(wsuri); websocket.onopen = () => { outgoingConnections.push(websocket); const peer = { - ip: websocket._socket.remoteAddress, + ip: connection, lastPingTime: null, latency: null, }; @@ -875,10 +883,7 @@ async function initiateAndHandleConnection(ip) { websocket.on('pong', () => { try { const curTime = new Date().getTime(); - const { url } = websocket; - let conIP = url.split('/')[2]; - conIP = conIP.split(`:${config.server.apiport}`).join(''); - const foundPeer = outgoingPeers.find((peer) => peer.ip === conIP); + const foundPeer = outgoingPeers.find((peer) => peer.ip === connection); if (foundPeer) { foundPeer.latency = Math.ceil((curTime - foundPeer.lastPingTime) / 2); } @@ -888,20 +893,17 @@ async function initiateAndHandleConnection(ip) { }); websocket.onclose = (evt) => { - const { url } = websocket; - let conIP = url.split('/')[2]; - conIP = conIP.split(`:${config.server.apiport}`).join(''); const ocIndex = outgoingConnections.indexOf(websocket); if (ocIndex > -1) { - log.info(`Connection to ${conIP} closed with code ${evt.code}`); + log.info(`Connection to ${connection} closed with code ${evt.code}`); outgoingConnections.splice(ocIndex, 1); } - const foundPeer = outgoingPeers.find((peer) => peer.ip === conIP); + const foundPeer = outgoingPeers.find((peer) => peer.ip === connection); if (foundPeer) { const peerIndex = outgoingPeers.indexOf(foundPeer); if (peerIndex > -1) { outgoingPeers.splice(peerIndex, 1); - log.info(`Connection ${conIP} removed from outgoingPeers`); + log.info(`Connection ${connection} removed from outgoingPeers`); } } }; @@ -928,15 +930,12 @@ async function initiateAndHandleConnection(ip) { } const messageOK = await verifyOriginalFluxBroadcast(evt.data, undefined, currentTimeStamp); if (messageOK === true) { - const { url } = websocket; - let conIP = url.split('/')[2]; - conIP = conIP.split(`:${config.server.apiport}`).join(''); if (msgObj.data.type === 'zelappregister' || msgObj.data.type === 'zelappupdate' || msgObj.data.type === 'fluxappregister' || msgObj.data.type === 'fluxappupdate') { - handleAppMessages(msgObj, conIP); + handleAppMessages(msgObj, connection); } else if (msgObj.data.type === 'zelapprequest' || msgObj.data.type === 'fluxapprequest') { respondWithAppMessage(msgObj, websocket); } else if (msgObj.data.type === 'zelapprunning' || msgObj.data.type === 'fluxapprunning') { - handleAppRunningMessage(msgObj, conIP); + handleAppRunningMessage(msgObj, connection); } } else { // we dont like this peer as it sent wrong message (wrong, or message belonging to node no longer on network). Lets close the connection @@ -945,13 +944,13 @@ async function initiateAndHandleConnection(ip) { // check if message comes from IP belonging to the public Key const zl = await deterministicFluxList(pubKey); // this itself is sufficient. const possibleNodes = zl.filter((key) => key.pubkey === pubKey); // another check in case sufficient check failed on daemon level - const nodeFound = possibleNodes.find((n) => n.ip === ip); + const nodeFound = possibleNodes.find((n) => n.ip === connection); if (!nodeFound) { - log.warn(`Message received from outgoing peer ${ip} but is not an originating node of ${pubKey}.`); + log.warn(`Message received from outgoing peer ${connection} but is not an originating node of ${pubKey}.`); websocket.close(1000, 'invalid message, disconnect'); // close as of policy violation } else { blockedPubKeysCache.set(pubKey, pubKey); // blocks ALL the nodes corresponding to the pubKey - log.warn(`closing outgoing connection, adding peers ${pubKey} to the blockedList. Originated from ${ip}.`); + log.warn(`closing outgoing connection, adding peers ${pubKey} to the blockedList. Originated from ${connection}.`); websocket.close(1000, 'invalid message, blocked'); // close as of policy violation? } } catch (e) { @@ -962,20 +961,17 @@ async function initiateAndHandleConnection(ip) { websocket.onerror = (evt) => { console.log(evt.code); - const { url } = websocket; - let conIP = url.split('/')[2]; - conIP = conIP.split(`:${config.server.apiport}`).join(''); const ocIndex = outgoingConnections.indexOf(websocket); if (ocIndex > -1) { - log.info(`Connection to ${conIP} errord with code ${evt.code}`); + log.info(`Connection to ${connection} errord with code ${evt.code}`); outgoingConnections.splice(ocIndex, 1); } - const foundPeer = outgoingPeers.find((peer) => peer.ip === conIP); + const foundPeer = outgoingPeers.find((peer) => peer.ip === connection); if (foundPeer) { const peerIndex = outgoingPeers.indexOf(foundPeer); if (peerIndex > -1) { outgoingPeers.splice(peerIndex, 1); - log.info(`Connection ${conIP} removed from outgoingPeers`); + log.info(`Connection ${connection} removed from outgoingPeers`); } } }; @@ -990,7 +986,7 @@ async function fluxDiscovery() { let nodeList = []; - const myIP = await getMyFluxIP(); + const myIP = await getMyFluxIPandPort(); if (myIP) { nodeList = await deterministicFluxList(); const fluxNode = nodeList.find((node) => node.ip === myIP); @@ -1259,19 +1255,23 @@ async function checkMyFluxAvailability(retryNumber = 0) { if (typeof askingIP !== 'string' || typeof myFluxIP !== 'string' || myFluxIP === askingIP) { return false; } - if (askingIP.includes(':')) { + let askingIpPort = config.server.apiport; + if (askingIP.includes(':')) { // has port specification // it is ipv6 - askingIP = `[${askingIP}]`; + const splittedIP = askingIP.split(':'); + askingIP = splittedIP[0]; + askingIpPort = splittedIP[1]; } let myIP = myFluxIP; - if (myIP.includes(':')) { - myIP = `[${myIP}]`; + if (myIP.includes(':')) { // has port specification + myIP = myIP.split(':')[0]; } let availabilityError = null; const axiosConfigAux = { timeout: 7000, }; - const resMyAvailability = await serviceHelper.axiosGet(`http://${askingIP}:${config.server.apiport}/flux/checkfluxavailability/${myIP}`, axiosConfigAux).catch((error) => { + const apiPort = userconfig.apiport || config.server.apiport; + const resMyAvailability = await serviceHelper.axiosGet(`http://${askingIP}:${askingIpPort}/flux/checkfluxavailability?ip=${myIP}&port=${apiPort}`, axiosConfigAux).catch((error) => { log.error(`${askingIP} is not reachable`); log.error(error); availabilityError = true; @@ -1350,9 +1350,10 @@ async function adjustExternalIP(ip) { initial: { ipaddress: '${ip}', zelid: '${userconfig.initial.zelid || config.fluxTeamZelId}', - cruxid: '${userconfig.initial.cruxid || ''}', kadena: '${userconfig.initial.kadena || ''}', testnet: ${userconfig.initial.testnet || false}, + homeport: ${userconfig.initial.homeport || 16126}, + apiport: ${userconfig.initial.apiport || 16127}, } }`; @@ -1368,7 +1369,7 @@ async function checkDeterministicNodesCollisions() { // get node list with filter on this ip address // if it returns more than 1 object, shut down. // another precatuion might be comparing node list on multiple nodes. evaulate in the future - const myIP = await getMyFluxIP(); + const myIP = await getMyFluxIPandPort(); if (myIP) { const syncStatus = daemonService.isDaemonSynced(); if (!syncStatus.data.synced) { @@ -1408,7 +1409,7 @@ async function checkDeterministicNodesCollisions() { } const availabilityOk = await checkMyFluxAvailability(); if (availabilityOk) { - adjustExternalIP(myIP); + adjustExternalIP(myIP.split(':')[0]); } } else { dosState += 1; @@ -1503,7 +1504,9 @@ async function adjustFirewall() { try { const cmdAsync = util.promisify(cmd.get); const execA = 'sudo ufw status | grep Status'; - const ports = [config.server.apiport, config.server.homeport, 80, 443, 16125]; + const apiPort = userconfig.apiport || config.server.apiport; + const homePort = userconfig.homeport || config.server.homeport; + const ports = [apiPort, homePort, 80, 443, 16125]; const cmdresA = await cmdAsync(execA); if (serviceHelper.ensureString(cmdresA).includes('Status: active')) { // eslint-disable-next-line no-restricted-syntax diff --git a/ZelBack/src/services/fluxService.js b/ZelBack/src/services/fluxService.js index 37c75fee0..8f1829450 100644 --- a/ZelBack/src/services/fluxService.js +++ b/ZelBack/src/services/fluxService.js @@ -657,9 +657,10 @@ async function adjustCruxID(req, res) { initial: { ipaddress: '${userconfig.initial.ipaddress || '127.0.0.1'}', zelid: '${userconfig.initial.zelid || config.fluxTeamZelId}', - cruxid: '${cruxid}', kadena: '${userconfig.initial.kadena || ''}', testnet: ${userconfig.initial.testnet || false}, + homeport: ${userconfig.initial.homeport || 16126}, + apiport: ${userconfig.initial.apiport || 16127}, } }`; @@ -702,9 +703,10 @@ async function adjustKadenaAccount(req, res) { initial: { ipaddress: '${userconfig.initial.ipaddress || '127.0.0.1'}', zelid: '${userconfig.initial.zelid || config.fluxTeamZelId}', - cruxid: '${userconfig.initial.cruxid || ''}', kadena: '${kadenaURI}', testnet: ${userconfig.initial.testnet || false}, + homeport: ${userconfig.initial.homeport || 16126}, + apiport: ${userconfig.initial.apiport || 16127}, } }`; diff --git a/apiServer.js b/apiServer.js index 69a936ebe..1fdc9df09 100644 --- a/apiServer.js +++ b/apiServer.js @@ -8,6 +8,8 @@ const app = require('./ZelBack/src/lib/server'); const log = require('./ZelBack/src/lib/log'); const serviceManager = require('./ZelBack/src/services/serviceManager'); +const userconfig = require('./config/userconfig'); + // const key = fs.readFileSync(path.join(__dirname, '../certs/selfsigned.key'), 'utf8'); // const cert = fs.readFileSync(path.join(__dirname, '../certs/selfsigned.crt'), 'utf8'); // const credentials = { key, cert }; @@ -17,7 +19,9 @@ const serviceManager = require('./ZelBack/src/services/serviceManager'); // log.info(`Flux https listening on port ${config.server.apiporthttps}!`); // }); -app.listen(config.server.apiport, () => { - log.info(`Flux listening on port ${config.server.apiport}!`); +const apiPort = userconfig.apiport || config.server.apiport; + +app.listen(apiPort, () => { + log.info(`Flux listening on port ${apiPort}!`); serviceManager.startFluxFunctions(); }); diff --git a/app.js b/app.js index 44214e731..7a6c38681 100644 --- a/app.js +++ b/app.js @@ -10,6 +10,8 @@ const app = require('./ZelBack/src/lib/server'); const log = require('./ZelBack/src/lib/log'); const serviceManager = require('./ZelBack/src/services/serviceManager'); +const userconfig = require('./config/userconfig'); + // const key = fs.readFileSync(path.join(__dirname, './certs/selfsigned.key'), 'utf8'); // const cert = fs.readFileSync(path.join(__dirname, './certs/selfsigned.crt'), 'utf8'); // const credentials = { key, cert }; @@ -19,8 +21,11 @@ const serviceManager = require('./ZelBack/src/services/serviceManager'); // log.info(`Flux https listening on port ${config.server.apiporthttps}!`); // }); -app.listen(config.server.apiport, () => { - log.info(`Flux running on port ${config.server.apiport}!`); +const apiPort = userconfig.apiport || config.server.apiport; +const homePort = userconfig.homeport || config.server.homeport; + +app.listen(apiPort, () => { + log.info(`Flux running on port ${apiPort}!`); serviceManager.startFluxFunctions(); }); @@ -40,6 +45,6 @@ homeApp.get('*', (req, res) => { res.sendFile(path.join(home, 'index.html')); }); -homeApp.listen(config.server.homeport, () => { - log.info(`Flux Home running on port ${config.server.homeport}!`); +homeApp.listen(homePort, () => { + log.info(`Flux Home running on port ${homePort}!`); }); diff --git a/homeServer.js b/homeServer.js index 0dfced6b9..22116db6a 100644 --- a/homeServer.js +++ b/homeServer.js @@ -7,6 +7,8 @@ const express = require('express'); const home = path.join(__dirname, './HomeUI/dist'); +const userconfig = require('./config/userconfig'); + const homeApp = express(); homeApp.use(compression()); homeApp.use(express.static(home)); @@ -20,6 +22,8 @@ homeApp.get('*', (req, res) => { res.sendFile(path.join(home, 'index.html')); }); -homeApp.listen(config.server.homeport, () => { - console.log(`Flux Home running on port ${config.server.homeport}!`); +const homePort = userconfig.homeport || config.server.homeport; + +homeApp.listen(homePort, () => { + console.log(`Flux Home running on port ${homePort}!`); }); diff --git a/init.js b/init.js index ca36a54e0..5a2ff8398 100644 --- a/init.js +++ b/init.js @@ -51,7 +51,9 @@ function showQuestions() { initial: { ipaddress: '${answers.ipaddr}', zelid: '${answers.zelid}', - testnet: false + testnet: false, + homeport: 16126, + apiport: 16127, } }`; diff --git a/package.json b/package.json index d7abedafd..488bf1787 100644 --- a/package.json +++ b/package.json @@ -44,8 +44,8 @@ "homepage": "https://github.com/runonflux/flux#readme", "scripts": { "vuelint": "vue-cli-service lint", - "lint": "eslint --ext .js,.vue ZelBack/ HomeUI/", - "lint:fix": "eslint --ext .js,.vue ZelBack/ HomeUI/ --fix", + "lint": "eslint --ext .js,.vue ./", + "lint:fix": "eslint --ext .js,.vue ./ --fix", "test:e2e": "vue-cli-service test:e2e", "test:unit": "vue-cli-service test:unit", "test:zelback": "mocha tests/ZelBack", diff --git a/sampleUserConfig.js b/sampleUserConfig.js index b1b513932..7a90cdcf0 100644 --- a/sampleUserConfig.js +++ b/sampleUserConfig.js @@ -4,5 +4,7 @@ module.exports = { zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', kadena: 'kadena:3a2e6166907d0c2fb28a16cd6966a705de129e8358b9872d9cefe694e910d5b2?chainid=0', testnet: false, + homeport: 16126, + apiport: 16127, }, }; From 3cd603458cc2baf78375f42757bd58d213731743 Mon Sep 17 00:00:00 2001 From: Tadeas Kmenta Date: Tue, 1 Feb 2022 11:30:29 +0700 Subject: [PATCH 02/41] automate homeport --- ZelBack/src/services/fluxCommunication.js | 3 +-- ZelBack/src/services/fluxService.js | 2 -- app.js | 2 +- homeServer.js | 2 +- init.js | 1 - sampleUserConfig.js | 1 - 6 files changed, 3 insertions(+), 8 deletions(-) diff --git a/ZelBack/src/services/fluxCommunication.js b/ZelBack/src/services/fluxCommunication.js index 7d962517a..9c8db5dbf 100644 --- a/ZelBack/src/services/fluxCommunication.js +++ b/ZelBack/src/services/fluxCommunication.js @@ -1352,7 +1352,6 @@ async function adjustExternalIP(ip) { zelid: '${userconfig.initial.zelid || config.fluxTeamZelId}', kadena: '${userconfig.initial.kadena || ''}', testnet: ${userconfig.initial.testnet || false}, - homeport: ${userconfig.initial.homeport || 16126}, apiport: ${userconfig.initial.apiport || 16127}, } }`; @@ -1505,7 +1504,7 @@ async function adjustFirewall() { const cmdAsync = util.promisify(cmd.get); const execA = 'sudo ufw status | grep Status'; const apiPort = userconfig.apiport || config.server.apiport; - const homePort = userconfig.homeport || config.server.homeport; + const homePort = apiPort - 1; const ports = [apiPort, homePort, 80, 443, 16125]; const cmdresA = await cmdAsync(execA); if (serviceHelper.ensureString(cmdresA).includes('Status: active')) { diff --git a/ZelBack/src/services/fluxService.js b/ZelBack/src/services/fluxService.js index 8f1829450..9d0bc632e 100644 --- a/ZelBack/src/services/fluxService.js +++ b/ZelBack/src/services/fluxService.js @@ -659,7 +659,6 @@ async function adjustCruxID(req, res) { zelid: '${userconfig.initial.zelid || config.fluxTeamZelId}', kadena: '${userconfig.initial.kadena || ''}', testnet: ${userconfig.initial.testnet || false}, - homeport: ${userconfig.initial.homeport || 16126}, apiport: ${userconfig.initial.apiport || 16127}, } }`; @@ -705,7 +704,6 @@ async function adjustKadenaAccount(req, res) { zelid: '${userconfig.initial.zelid || config.fluxTeamZelId}', kadena: '${kadenaURI}', testnet: ${userconfig.initial.testnet || false}, - homeport: ${userconfig.initial.homeport || 16126}, apiport: ${userconfig.initial.apiport || 16127}, } }`; diff --git a/app.js b/app.js index 7a6c38681..30d3ad54c 100644 --- a/app.js +++ b/app.js @@ -22,7 +22,7 @@ const userconfig = require('./config/userconfig'); // }); const apiPort = userconfig.apiport || config.server.apiport; -const homePort = userconfig.homeport || config.server.homeport; +const homePort = apiPort - 1; app.listen(apiPort, () => { log.info(`Flux running on port ${apiPort}!`); diff --git a/homeServer.js b/homeServer.js index 22116db6a..01a70f66a 100644 --- a/homeServer.js +++ b/homeServer.js @@ -22,7 +22,7 @@ homeApp.get('*', (req, res) => { res.sendFile(path.join(home, 'index.html')); }); -const homePort = userconfig.homeport || config.server.homeport; +const homePort = (userconfig.apiport || config.server.apiport) - 1; homeApp.listen(homePort, () => { console.log(`Flux Home running on port ${homePort}!`); diff --git a/init.js b/init.js index 5a2ff8398..11d7d2afd 100644 --- a/init.js +++ b/init.js @@ -52,7 +52,6 @@ function showQuestions() { ipaddress: '${answers.ipaddr}', zelid: '${answers.zelid}', testnet: false, - homeport: 16126, apiport: 16127, } }`; diff --git a/sampleUserConfig.js b/sampleUserConfig.js index 7a90cdcf0..3616677f2 100644 --- a/sampleUserConfig.js +++ b/sampleUserConfig.js @@ -4,7 +4,6 @@ module.exports = { zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', kadena: 'kadena:3a2e6166907d0c2fb28a16cd6966a705de129e8358b9872d9cefe694e910d5b2?chainid=0', testnet: false, - homeport: 16126, apiport: 16127, }, }; From 3f4cdc6a429e44068cc3d84a75f86081078f6e4c Mon Sep 17 00:00:00 2001 From: Tadeas Kmenta Date: Sat, 12 Feb 2022 12:06:35 +0700 Subject: [PATCH 03/41] add maxIdleTimeMS --- ZelBack/src/services/serviceHelper.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ZelBack/src/services/serviceHelper.js b/ZelBack/src/services/serviceHelper.js index c5c141359..30818edac 100644 --- a/ZelBack/src/services/serviceHelper.js +++ b/ZelBack/src/services/serviceHelper.js @@ -124,6 +124,7 @@ async function connectMongoDb(url) { useNewUrlParser: true, useUnifiedTopology: true, maxPoolSize: 100, + maxIdleTimeMS: 12 * 60 * 1000, }; const db = await MongoClient.connect(connectUrl, mongoSettings); return db; From ba21e0cdd2972c824b46602480c16d411484c7e7 Mon Sep 17 00:00:00 2001 From: JacekAdamczyk Date: Mon, 14 Feb 2022 09:49:52 +0100 Subject: [PATCH 04/41] add ensure functions tests --- package.json | 1 + tests/unit/example.spec.js | 13 ------------- 2 files changed, 1 insertion(+), 13 deletions(-) delete mode 100644 tests/unit/example.spec.js diff --git a/package.json b/package.json index a31e27dca..026ebcb50 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "test:e2e": "vue-cli-service test:e2e", "test:unit": "vue-cli-service test:unit", "test:zelback": "mocha tests/ZelBack", + "test:zelback:unit": "mocha tests/unit", "homedev": "vue-cli-service serve --port 16126", "homeprod": "nodemon homeServer.js", "homebuild": "vue-cli-service build", diff --git a/tests/unit/example.spec.js b/tests/unit/example.spec.js deleted file mode 100644 index aa4e7d338..000000000 --- a/tests/unit/example.spec.js +++ /dev/null @@ -1,13 +0,0 @@ -import { expect } from 'chai'; -import { shallowMount } from '@vue/test-utils'; -import HelloWorld from '@/components/HelloWorld'; - -describe('HelloWorld', () => { - it('renders props.msg when passed', () => { - const msg = 'new message'; - const wrapper = shallowMount(HelloWorld, { - propsData: { msg }, - }); - expect(wrapper.text()).to.include(msg); - }); -}); From 127a0120cedba718648868d0873befc20602128d Mon Sep 17 00:00:00 2001 From: JacekAdamczyk Date: Mon, 14 Feb 2022 09:50:12 +0100 Subject: [PATCH 05/41] add test file --- tests/unit/serviceHelperTest.spec.js | 165 +++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 tests/unit/serviceHelperTest.spec.js diff --git a/tests/unit/serviceHelperTest.spec.js b/tests/unit/serviceHelperTest.spec.js new file mode 100644 index 000000000..fb475528c --- /dev/null +++ b/tests/unit/serviceHelperTest.spec.js @@ -0,0 +1,165 @@ +process.env.NODE_CONFIG_DIR = `${process.cwd()}/ZelBack/config/`; +const chai = require('chai'); +const expect = chai.expect; +const serviceHelper = require("../../ZelBack/src/services/serviceHelper"); +describe('serviceHelper tests', () => { + describe('ensureBoolean function tests', () => { + const falseBools = ['false', false, 0, '0']; + const trueBools = ['true', true, 1, '1']; + const restOfTruthyValues = [3, 3n, 'test', [1, 2], { name: 'testobject' }]; + const restOfFalsyValues = [0n, null, undefined, NaN, '']; + + for (let falseBool of falseBools) { + it(`parameter ${typeof falseBool === 'string' ? `"${falseBool}"` : falseBool} should return false`, () => { + expect(serviceHelper.ensureBoolean(falseBool)).to.equal(false); + }); + } + for (let trueBool of trueBools) { + it(`parameter ${typeof trueBool === 'string' ? `"${trueBool}"` : trueBool} should return false`, () => { + expect(serviceHelper.ensureBoolean(trueBool)).to.equal(true); + }); + } + for (let truthyValue of restOfTruthyValues) { + it(`parameter ${typeof truthyValue === 'string' ? `"${truthyValue}"` : truthyValue} should return undefined`, () => { + expect(serviceHelper.ensureBoolean(truthyValue)).to.be.undefined; + }); + } + for (let falsyValue of restOfFalsyValues) { + it(`parameter ${typeof falsyValue === 'string' ? `"${falsyValue}"` : falsyValue} should return undefined`, () => { + expect(serviceHelper.ensureBoolean(falsyValue)).to.be.undefined; + }); + } + it('empty parameter should return undefined', () => { + expect(serviceHelper.ensureBoolean()).to.be.undefined; + }); + }); + + describe('ensureNumber function tests', () => { + it('parameter 1 should return 1', () => { + const ensureNumberOutput = serviceHelper.ensureNumber(1); + const expected = 1; + + expect(ensureNumberOutput).to.equal(expected) + expect(ensureNumberOutput).to.be.a('number') + }); + it('parameter "1" should return 1', () => { + const ensureNumberOutput = serviceHelper.ensureNumber("1"); + const expected = 1; + + expect(ensureNumberOutput).to.equal(expected) + expect(ensureNumberOutput).to.be.a('number') + }); + it('parameter "2.5" should return 2.5', () => { + const ensureNumberOutput = serviceHelper.ensureNumber("2.5"); + const expected = 2.5; + + expect(ensureNumberOutput).to.equal(expected) + expect(ensureNumberOutput).to.be.a('number') + }); + it('parameter 2.5 should return 2.5', () => { + const ensureNumberOutput = serviceHelper.ensureNumber(2.5); + const expected = 2.5; + + expect(ensureNumberOutput).to.equal(expected) + expect(ensureNumberOutput).to.be.a('number') + }); + it('parameter "test" should return NaN', () => { + const ensureNumberOutput = serviceHelper.ensureNumber("test"); + + expect(ensureNumberOutput).to.be.NaN + }); + it('parameter {name: 1} should return NaN', () => { + const ensureNumberOutput = serviceHelper.ensureNumber({ name: 1 }); + + expect(ensureNumberOutput).to.be.NaN + }); + }); + + describe('ensureObject tests', () => { + it('parameter of type object should return the same object', () => { + const testObject = { + id: 1, + username: 'Testing user' + } + + const ensureObjectOutput = serviceHelper.ensureObject(testObject); + + expect(ensureObjectOutput).to.be.an('object'); + expect(ensureObjectOutput).to.equal(testObject); + }); + + it('empty parameter should return an empty object', () => { + const ensureObjectOutput = serviceHelper.ensureObject(); + + expect(ensureObjectOutput).to.be.an('object').that.is.empty; + }); + + it('parameter of type json string should return an object', () => { + const stringObject = '{"id": 1,"username": "Testing user"}'; + const expected = { + id: 1, + username: 'Testing user' + } + + const ensureObjectOutput = serviceHelper.ensureObject(stringObject); + + expect(ensureObjectOutput).to.be.an('object'); + expect(ensureObjectOutput).to.eql(expected); + }); + + it('parameter of type query string should return an object', () => { + const queryString = 'username=Tester&id=1'; + const expected = { + id: '1', + username: 'Tester' + } + + const ensureObjectOutput = serviceHelper.ensureObject(queryString); + + expect(ensureObjectOutput).to.be.an('object'); + expect(ensureObjectOutput).to.eql(expected); + }); + + it('parameter of type string should return an object', () => { + const testString = 'test'; + const expected = { + test: "", + } + + const ensureObjectOutput = serviceHelper.ensureObject(testString); + + expect(ensureObjectOutput).to.be.an('object'); + expect(ensureObjectOutput).to.eql(expected); + }); + + it('parameter of type array should return an array', () => { + const testArr = ['1', 'testing', 3]; + + const ensureObjectOutput = serviceHelper.ensureObject(testArr); + + expect(ensureObjectOutput).to.be.an('array'); + expect(ensureObjectOutput).to.eql(testArr); + }); + + const otherTypes = [1, true] + for (let param of otherTypes) { + it(`parameter of type ${typeof param} should return undefined`, () => { + expect(serviceHelper.ensureObject(param)).to.be.an('object').that.is.empty; + }); + } + }); + + describe('ensureString tests', () => { + it('parameter of type string should return a string', () => { + const testString = 'testing string'; + + const ensureStringOutput = serviceHelper.ensureString(testString); + + expect(ensureStringOutput).to.be.a('string'); + expect(ensureStringOutput).to.eql(testString); + }); + + }); + +}); + From 7b92f810f74f0c789035d1056f873f810bc9a745 Mon Sep 17 00:00:00 2001 From: JacekAdamczyk Date: Tue, 15 Feb 2022 10:03:08 +0100 Subject: [PATCH 06/41] add more messages tests --- package.json | 2 +- tests/unit/serviceHelper.test.js | 320 +++++++++++++++++++++++++++ tests/unit/serviceHelperTest.spec.js | 165 -------------- 3 files changed, 321 insertions(+), 166 deletions(-) create mode 100644 tests/unit/serviceHelper.test.js delete mode 100644 tests/unit/serviceHelperTest.spec.js diff --git a/package.json b/package.json index 026ebcb50..f0a85ef1b 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "test:e2e": "vue-cli-service test:e2e", "test:unit": "vue-cli-service test:unit", "test:zelback": "mocha tests/ZelBack", - "test:zelback:unit": "mocha tests/unit", + "test:zelback:unit": "mocha tests/unit/*.test.js", "homedev": "vue-cli-service serve --port 16126", "homeprod": "nodemon homeServer.js", "homebuild": "vue-cli-service build", diff --git a/tests/unit/serviceHelper.test.js b/tests/unit/serviceHelper.test.js new file mode 100644 index 000000000..1eb3bd4f8 --- /dev/null +++ b/tests/unit/serviceHelper.test.js @@ -0,0 +1,320 @@ +process.env.NODE_CONFIG_DIR = `${process.cwd()}/ZelBack/config/`; +const chai = require('chai'); +const expect = chai.expect; +const serviceHelper = require("../../ZelBack/src/services/serviceHelper"); +describe('serviceHelper tests', () => { + describe('ensureBoolean function tests', () => { + const falseBools = ['false', false, 0, '0']; + const trueBools = ['true', true, 1, '1']; + const restOfTruthyValues = [3, 3n, 'test', [1, 2], { name: 'testobject' }]; + const restOfFalsyValues = [0n, null, undefined, NaN, '']; + + for (let falseBool of falseBools) { + it(`parameter ${typeof falseBool === 'string' ? `"${falseBool}"` : falseBool} should return false`, () => { + expect(serviceHelper.ensureBoolean(falseBool)).to.equal(false); + }); + } + for (let trueBool of trueBools) { + it(`parameter ${typeof trueBool === 'string' ? `"${trueBool}"` : trueBool} should return false`, () => { + expect(serviceHelper.ensureBoolean(trueBool)).to.equal(true); + }); + } + for (let truthyValue of restOfTruthyValues) { + it(`parameter ${typeof truthyValue === 'string' ? `"${truthyValue}"` : truthyValue} should return undefined`, () => { + expect(serviceHelper.ensureBoolean(truthyValue)).to.be.undefined; + }); + } + for (let falsyValue of restOfFalsyValues) { + it(`parameter ${typeof falsyValue === 'string' ? `"${falsyValue}"` : falsyValue} should return undefined`, () => { + expect(serviceHelper.ensureBoolean(falsyValue)).to.be.undefined; + }); + } + it('empty parameter should return undefined', () => { + expect(serviceHelper.ensureBoolean()).to.be.undefined; + }); + }); + + describe('ensureNumber function tests', () => { + it('parameter 1 should return 1', () => { + const ensureNumberOutput = serviceHelper.ensureNumber(1); + const expected = 1; + + expect(ensureNumberOutput).to.equal(expected) + expect(ensureNumberOutput).to.be.a('number') + }); + it('parameter "1" should return 1', () => { + const ensureNumberOutput = serviceHelper.ensureNumber("1"); + const expected = 1; + + expect(ensureNumberOutput).to.equal(expected) + expect(ensureNumberOutput).to.be.a('number') + }); + it('parameter "2.5" should return 2.5', () => { + const ensureNumberOutput = serviceHelper.ensureNumber("2.5"); + const expected = 2.5; + + expect(ensureNumberOutput).to.equal(expected) + expect(ensureNumberOutput).to.be.a('number') + }); + it('parameter 2.5 should return 2.5', () => { + const ensureNumberOutput = serviceHelper.ensureNumber(2.5); + const expected = 2.5; + + expect(ensureNumberOutput).to.equal(expected) + expect(ensureNumberOutput).to.be.a('number') + }); + it('parameter "test" should return NaN', () => { + const ensureNumberOutput = serviceHelper.ensureNumber("test"); + + expect(ensureNumberOutput).to.be.NaN + }); + it('parameter {name: 1} should return NaN', () => { + const ensureNumberOutput = serviceHelper.ensureNumber({ name: 1 }); + + expect(ensureNumberOutput).to.be.NaN + }); + }); + + describe('ensureObject tests', () => { + it('parameter of type object should return the same object', () => { + const testObject = { + id: 1, + username: 'Testing user' + } + + const ensureObjectOutput = serviceHelper.ensureObject(testObject); + + expect(ensureObjectOutput).to.be.an('object'); + expect(ensureObjectOutput).to.equal(testObject); + }); + + it('empty parameter should return an empty object', () => { + const ensureObjectOutput = serviceHelper.ensureObject(); + + expect(ensureObjectOutput).to.be.an('object').that.is.empty; + }); + + it('parameter of type json string should return an object', () => { + const stringObject = '{"id": 1,"username": "Testing user"}'; + const expected = { + id: 1, + username: 'Testing user' + } + + const ensureObjectOutput = serviceHelper.ensureObject(stringObject); + + expect(ensureObjectOutput).to.be.an('object'); + expect(ensureObjectOutput).to.eql(expected); + }); + + it('parameter of type query string should return an object', () => { + const queryString = 'username=Tester&id=1'; + const expected = { + id: '1', + username: 'Tester' + } + + const ensureObjectOutput = serviceHelper.ensureObject(queryString); + + expect(ensureObjectOutput).to.be.an('object'); + expect(ensureObjectOutput).to.eql(expected); + }); + + it('parameter of type string should return an object', () => { + const testString = 'test'; + const expected = { + test: "", + } + + const ensureObjectOutput = serviceHelper.ensureObject(testString); + + expect(ensureObjectOutput).to.be.an('object'); + expect(ensureObjectOutput).to.eql(expected); + }); + + it('parameter of type array should return an array', () => { + const testArr = ['1', 'testing', 3]; + + const ensureObjectOutput = serviceHelper.ensureObject(testArr); + + expect(ensureObjectOutput).to.be.an('array'); + expect(ensureObjectOutput).to.eql(testArr); + }); + + const otherTypes = [1, true] + for (let param of otherTypes) { + it(`parameter of type ${typeof param} should return undefined`, () => { + expect(serviceHelper.ensureObject(param)).to.be.an('object').that.is.empty; + }); + } + }); + + describe('ensureString tests', () => { + it('parameter of type string should return a string', () => { + const testString = 'testing string'; + + const ensureStringOutput = serviceHelper.ensureString(testString); + + expect(ensureStringOutput).to.be.a('string'); + expect(ensureStringOutput).to.eql(testString); + }); + + it('parameter of type object should return a string', () => { + const testObject = { + id: 1, + username: 'Testing user' + } + const expected = '{"id":1,"username":"Testing user"}' + + const ensureStringOutput = serviceHelper.ensureString(testObject); + + expect(ensureStringOutput).to.be.a('string'); + expect(ensureStringOutput).to.eql(expected); + }); + + it('parameter of type number should return a string', () => { + const testNumber = 42; + const expected = '42' + + const ensureStringOutput = serviceHelper.ensureString(testNumber); + + expect(ensureStringOutput).to.be.a('string'); + expect(ensureStringOutput).to.eql(expected); + }); + + it('empty parameter should return undefined', () => { + const ensureStringOutput = serviceHelper.ensureString(); + + expect(ensureStringOutput).to.be.undefined; + }); + }); + + describe('createDataMessage tests', () => { + it('should return a proper data message when called correctly', () => { + const testData = { id: 55, message: 'this is my test message' }; + + const createDataMessageOutput = serviceHelper.createDataMessage(testData); + + expect(createDataMessageOutput.status).to.equal('success'); + expect(createDataMessageOutput.data).to.equal(testData); + }); + }); + + describe('createSuccessMessage tests', () => { + it('should return a proper data message when called correctly', () => { + const code = 200; + const name = 'Successful transfer'; + const message = 'Your funds were transfered properly!'; + + const createSuccessMessageOutput = serviceHelper.createSuccessMessage(message, name, code); + + expect(createSuccessMessageOutput.status).to.equal('success'); + expect(createSuccessMessageOutput.data.code).to.equal(code); + expect(createSuccessMessageOutput.data.name).to.equal(name); + expect(createSuccessMessageOutput.data.message).to.equal(message); + }); + }); + + describe('createSuccessMessage tests', () => { + it('should return a proper success message when called with all parameters', () => { + const code = 200; + const name = 'Successful transfer'; + const message = 'Your funds were transfered properly!'; + + const createSuccessMessageOutput = serviceHelper.createSuccessMessage(message, name, code); + + expect(createSuccessMessageOutput.status).to.equal('success'); + expect(createSuccessMessageOutput.data.code).to.equal(code); + expect(createSuccessMessageOutput.data.name).to.equal(name); + expect(createSuccessMessageOutput.data.message).to.equal(message); + }); + + it('should return a proper success message when called with empty message', () => { + const code = 200; + const name = 'Successful transfer'; + const message = ''; + + const createSuccessMessageOutput = serviceHelper.createSuccessMessage(message, name, code); + + expect(createSuccessMessageOutput.status).to.equal('success'); + expect(createSuccessMessageOutput.data.code).to.equal(code); + expect(createSuccessMessageOutput.data.name).to.equal(name); + expect(createSuccessMessageOutput.data.message).to.equal(message); + }); + }); + + describe('createWarningMessage tests', () => { + it('should return a proper warning message when called with all parameters', () => { + const code = 214; + const name = 'Warning!'; + const message = 'There was a slight issue!'; + + const createWarningMessageOutput = serviceHelper.createWarningMessage(message, name, code); + + expect(createWarningMessageOutput.status).to.equal('warning'); + expect(createWarningMessageOutput.data.code).to.equal(code); + expect(createWarningMessageOutput.data.name).to.equal(name); + expect(createWarningMessageOutput.data.message).to.equal(message); + }); + + it('should return a proper warning message when called with empty message', () => { + const code = 214; + const name = 'Warning!'; + const message = ''; + + const createSuccessMessageOutput = serviceHelper.createWarningMessage(message, name, code); + + expect(createSuccessMessageOutput.status).to.equal('warning'); + expect(createSuccessMessageOutput.data.code).to.equal(code); + expect(createSuccessMessageOutput.data.name).to.equal(name); + expect(createSuccessMessageOutput.data.message).to.equal(message); + }); + }); + + describe('createErrorMessage tests', () => { + it('should return a proper error message when called with all parameters', () => { + const code = 503; + const name = 'Error happened!!'; + const message = 'There was a big error!'; + + const createErrorMessageOutput = serviceHelper.createErrorMessage(message, name, code); + + expect(createErrorMessageOutput.status).to.equal('error'); + expect(createErrorMessageOutput.data.code).to.equal(code); + expect(createErrorMessageOutput.data.name).to.equal(name); + expect(createErrorMessageOutput.data.message).to.equal(message); + }); + + it('should return a proper error message when called with empty message', () => { + const code = 503; + const name = 'Error happened!!'; + const message = ''; + const expectedMessage = 'Unknown error'; + + const createErrorMessageOutput = serviceHelper.createErrorMessage(message, name, code); + + expect(createErrorMessageOutput.status).to.equal('error'); + expect(createErrorMessageOutput.data.code).to.equal(code); + expect(createErrorMessageOutput.data.name).to.equal(name); + expect(createErrorMessageOutput.data.message).to.equal(expectedMessage); + }); + }); + + describe('errUnauthorizedMessage tests', () => { + it('should return a proper unauthorized message when called', () => { + const code = 401; + const name = 'Unauthorized'; + const message = 'Unauthorized. Access denied.'; + + const errUnauthorizedMessageOutput = serviceHelper.errUnauthorizedMessage(message, name, code); + + expect(errUnauthorizedMessageOutput.status).to.equal('error'); + expect(errUnauthorizedMessageOutput.data.code).to.equal(code); + expect(errUnauthorizedMessageOutput.data.name).to.equal(name); + expect(errUnauthorizedMessageOutput.data.message).to.equal(message); + }); + }); + + +}); + diff --git a/tests/unit/serviceHelperTest.spec.js b/tests/unit/serviceHelperTest.spec.js deleted file mode 100644 index fb475528c..000000000 --- a/tests/unit/serviceHelperTest.spec.js +++ /dev/null @@ -1,165 +0,0 @@ -process.env.NODE_CONFIG_DIR = `${process.cwd()}/ZelBack/config/`; -const chai = require('chai'); -const expect = chai.expect; -const serviceHelper = require("../../ZelBack/src/services/serviceHelper"); -describe('serviceHelper tests', () => { - describe('ensureBoolean function tests', () => { - const falseBools = ['false', false, 0, '0']; - const trueBools = ['true', true, 1, '1']; - const restOfTruthyValues = [3, 3n, 'test', [1, 2], { name: 'testobject' }]; - const restOfFalsyValues = [0n, null, undefined, NaN, '']; - - for (let falseBool of falseBools) { - it(`parameter ${typeof falseBool === 'string' ? `"${falseBool}"` : falseBool} should return false`, () => { - expect(serviceHelper.ensureBoolean(falseBool)).to.equal(false); - }); - } - for (let trueBool of trueBools) { - it(`parameter ${typeof trueBool === 'string' ? `"${trueBool}"` : trueBool} should return false`, () => { - expect(serviceHelper.ensureBoolean(trueBool)).to.equal(true); - }); - } - for (let truthyValue of restOfTruthyValues) { - it(`parameter ${typeof truthyValue === 'string' ? `"${truthyValue}"` : truthyValue} should return undefined`, () => { - expect(serviceHelper.ensureBoolean(truthyValue)).to.be.undefined; - }); - } - for (let falsyValue of restOfFalsyValues) { - it(`parameter ${typeof falsyValue === 'string' ? `"${falsyValue}"` : falsyValue} should return undefined`, () => { - expect(serviceHelper.ensureBoolean(falsyValue)).to.be.undefined; - }); - } - it('empty parameter should return undefined', () => { - expect(serviceHelper.ensureBoolean()).to.be.undefined; - }); - }); - - describe('ensureNumber function tests', () => { - it('parameter 1 should return 1', () => { - const ensureNumberOutput = serviceHelper.ensureNumber(1); - const expected = 1; - - expect(ensureNumberOutput).to.equal(expected) - expect(ensureNumberOutput).to.be.a('number') - }); - it('parameter "1" should return 1', () => { - const ensureNumberOutput = serviceHelper.ensureNumber("1"); - const expected = 1; - - expect(ensureNumberOutput).to.equal(expected) - expect(ensureNumberOutput).to.be.a('number') - }); - it('parameter "2.5" should return 2.5', () => { - const ensureNumberOutput = serviceHelper.ensureNumber("2.5"); - const expected = 2.5; - - expect(ensureNumberOutput).to.equal(expected) - expect(ensureNumberOutput).to.be.a('number') - }); - it('parameter 2.5 should return 2.5', () => { - const ensureNumberOutput = serviceHelper.ensureNumber(2.5); - const expected = 2.5; - - expect(ensureNumberOutput).to.equal(expected) - expect(ensureNumberOutput).to.be.a('number') - }); - it('parameter "test" should return NaN', () => { - const ensureNumberOutput = serviceHelper.ensureNumber("test"); - - expect(ensureNumberOutput).to.be.NaN - }); - it('parameter {name: 1} should return NaN', () => { - const ensureNumberOutput = serviceHelper.ensureNumber({ name: 1 }); - - expect(ensureNumberOutput).to.be.NaN - }); - }); - - describe('ensureObject tests', () => { - it('parameter of type object should return the same object', () => { - const testObject = { - id: 1, - username: 'Testing user' - } - - const ensureObjectOutput = serviceHelper.ensureObject(testObject); - - expect(ensureObjectOutput).to.be.an('object'); - expect(ensureObjectOutput).to.equal(testObject); - }); - - it('empty parameter should return an empty object', () => { - const ensureObjectOutput = serviceHelper.ensureObject(); - - expect(ensureObjectOutput).to.be.an('object').that.is.empty; - }); - - it('parameter of type json string should return an object', () => { - const stringObject = '{"id": 1,"username": "Testing user"}'; - const expected = { - id: 1, - username: 'Testing user' - } - - const ensureObjectOutput = serviceHelper.ensureObject(stringObject); - - expect(ensureObjectOutput).to.be.an('object'); - expect(ensureObjectOutput).to.eql(expected); - }); - - it('parameter of type query string should return an object', () => { - const queryString = 'username=Tester&id=1'; - const expected = { - id: '1', - username: 'Tester' - } - - const ensureObjectOutput = serviceHelper.ensureObject(queryString); - - expect(ensureObjectOutput).to.be.an('object'); - expect(ensureObjectOutput).to.eql(expected); - }); - - it('parameter of type string should return an object', () => { - const testString = 'test'; - const expected = { - test: "", - } - - const ensureObjectOutput = serviceHelper.ensureObject(testString); - - expect(ensureObjectOutput).to.be.an('object'); - expect(ensureObjectOutput).to.eql(expected); - }); - - it('parameter of type array should return an array', () => { - const testArr = ['1', 'testing', 3]; - - const ensureObjectOutput = serviceHelper.ensureObject(testArr); - - expect(ensureObjectOutput).to.be.an('array'); - expect(ensureObjectOutput).to.eql(testArr); - }); - - const otherTypes = [1, true] - for (let param of otherTypes) { - it(`parameter of type ${typeof param} should return undefined`, () => { - expect(serviceHelper.ensureObject(param)).to.be.an('object').that.is.empty; - }); - } - }); - - describe('ensureString tests', () => { - it('parameter of type string should return a string', () => { - const testString = 'testing string'; - - const ensureStringOutput = serviceHelper.ensureString(testString); - - expect(ensureStringOutput).to.be.a('string'); - expect(ensureStringOutput).to.eql(testString); - }); - - }); - -}); - From eab5cadf589856a0bae6b947df7f47c0679cc5fc Mon Sep 17 00:00:00 2001 From: JacekAdamczyk Date: Tue, 15 Feb 2022 10:37:30 +0100 Subject: [PATCH 07/41] add more messages tests --- tests/unit/serviceHelper.test.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/unit/serviceHelper.test.js b/tests/unit/serviceHelper.test.js index 1eb3bd4f8..62c648f10 100644 --- a/tests/unit/serviceHelper.test.js +++ b/tests/unit/serviceHelper.test.js @@ -315,6 +315,14 @@ describe('serviceHelper tests', () => { }); }); - + describe.only('connectMongoDb', () => { + before(mochaAsync(async () => { + await serviceHelper.initiateDB(); + })) + it("should ensure that MongoDB is connected", mochaAsync(async () => { + openDBConnection = await serviceHelper.connectMongoDb(); + expect(typeof (openDBConnection)).to.be.equal('object') + })); +}) }); From c7bdfb2288730c84844f47b10c57cb8317c39bff Mon Sep 17 00:00:00 2001 From: JacekAdamczyk Date: Wed, 16 Feb 2022 11:50:23 +0100 Subject: [PATCH 08/41] addAppOwnerTests --- package.json | 2 +- tests/unit/serviceHelper.test.js | 79 ++++++++++++++++++++++++++++---- 2 files changed, 70 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index f0a85ef1b..4191721ad 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "test:e2e": "vue-cli-service test:e2e", "test:unit": "vue-cli-service test:unit", "test:zelback": "mocha tests/ZelBack", - "test:zelback:unit": "mocha tests/unit/*.test.js", + "test:zelback:unit": "mocha tests/unit/*.test.js --exit", "homedev": "vue-cli-service serve --port 16126", "homeprod": "nodemon homeServer.js", "homebuild": "vue-cli-service build", diff --git a/tests/unit/serviceHelper.test.js b/tests/unit/serviceHelper.test.js index 62c648f10..56b2a6454 100644 --- a/tests/unit/serviceHelper.test.js +++ b/tests/unit/serviceHelper.test.js @@ -1,7 +1,10 @@ -process.env.NODE_CONFIG_DIR = `${process.cwd()}/ZelBack/config/`; +process.env.NODE_CONFIG_DIR = `${process.cwd()}/tests/unit/testconfig`; const chai = require('chai'); +const config = require('config'); +const { ObjectId, MongoClient } = require('mongodb'); const expect = chai.expect; const serviceHelper = require("../../ZelBack/src/services/serviceHelper"); + describe('serviceHelper tests', () => { describe('ensureBoolean function tests', () => { const falseBools = ['false', false, 0, '0']; @@ -315,14 +318,70 @@ describe('serviceHelper tests', () => { }); }); - describe.only('connectMongoDb', () => { - before(mochaAsync(async () => { - await serviceHelper.initiateDB(); - })) - it("should ensure that MongoDB is connected", mochaAsync(async () => { - openDBConnection = await serviceHelper.connectMongoDb(); - expect(typeof (openDBConnection)).to.be.equal('object') - })); -}) + describe('getApplicationOwner tests', () => { + beforeEach(async () => { + await serviceHelper.initiateDB(); + const db = serviceHelper.databaseConnection(); + const database = db.db(config.database.appsglobal.database) + const collection = config.database.appsglobal.collections.appsInformation + const insertApp = { + "_id": ObjectId("6147045cd774409b374d253d"), + "name": "PolkadotNode", + "commands": [], + "containerData": "/chaindata", + "containerPorts": [ + "30333", + "9933", + "9944" + ], + "cpu": 0.8, + "description": "Polkadot is a heterogeneous multi-chain interchange.", + "domains": [ + "polkadot.runonflux.io", + "polkadot.runonflux.io", + "polkadot.runonflux.io" + ], + "enviromentParameters": [], + "hash": "6f03b288240df90eb0d5a77c17c8fbea091619926ae66062da639b798fcf4ee5", + "hdd": 20, + "height": 988063, + "owner": "196GJWyLxzAw3MirTT7Bqs2iGpUQio29GH", + "ports": [ + "31116", + "31115", + "31114" + ], + "ram": 1800, + "repotag": "runonflux/polkadot-docker:latest", + "tiered": false, + "version": 2 + } + + await database.collection(collection).drop(); + await serviceHelper.insertOneToDatabase(database, collection, insertApp); + }); + + it("should return application owner if app exists in database", async () => { + const appOwner = '196GJWyLxzAw3MirTT7Bqs2iGpUQio29GH'; + const getOwnerResult = await serviceHelper.getApplicationOwner('PolkadotNode'); + + expect(getOwnerResult).to.equal(appOwner); + }); + + it("should return application owner if app is in available apps, but not in db", async () => { + const appOwner = '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC'; + const getOwnerResult = await serviceHelper.getApplicationOwner('FoldingAtHomeB'); + + expect(getOwnerResult).to.equal(appOwner); + }); + + it("should return null if the app does not exist", async () => { + const getOwnerResult = await serviceHelper.getApplicationOwner('testing'); + + expect(getOwnerResult).to.be.null; + }); + }); + + }); From 43c71bd994eae3a8ebf3cc6a0eeff8c1d51eb3ee Mon Sep 17 00:00:00 2001 From: JacekAdamczyk Date: Wed, 16 Feb 2022 17:08:43 +0100 Subject: [PATCH 09/41] add initial admin verification tests --- package.json | 1 + tests/unit/serviceHelper.test.js | 64 ++++++++++++++++++++++++++++---- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 4191721ad..2071aa918 100644 --- a/package.json +++ b/package.json @@ -91,6 +91,7 @@ "node-df": "~0.1.4", "nodemon": "~2.0.15", "path": "~0.12.7", + "proxyquire": "^2.1.3", "qs": "~6.10.2", "store": "~2.0.12", "stream": "~0.0.2", diff --git a/tests/unit/serviceHelper.test.js b/tests/unit/serviceHelper.test.js index 56b2a6454..a5cc080a9 100644 --- a/tests/unit/serviceHelper.test.js +++ b/tests/unit/serviceHelper.test.js @@ -1,9 +1,11 @@ -process.env.NODE_CONFIG_DIR = `${process.cwd()}/tests/unit/testconfig`; +process.env.NODE_CONFIG_DIR = `${process.cwd()}/tests/unit/globalconfig`; const chai = require('chai'); const config = require('config'); -const { ObjectId, MongoClient } = require('mongodb'); +const { ObjectId } = require('mongodb'); +var proxyquire = require('proxyquire'); const expect = chai.expect; -const serviceHelper = require("../../ZelBack/src/services/serviceHelper"); + +let serviceHelper = require("../../ZelBack/src/services/serviceHelper"); describe('serviceHelper tests', () => { describe('ensureBoolean function tests', () => { @@ -322,8 +324,8 @@ describe('serviceHelper tests', () => { beforeEach(async () => { await serviceHelper.initiateDB(); const db = serviceHelper.databaseConnection(); - const database = db.db(config.database.appsglobal.database) - const collection = config.database.appsglobal.collections.appsInformation + const database = db.db(config.database.appsglobal.database); + const collection = config.database.appsglobal.collections.appsInformation; const insertApp = { "_id": ObjectId("6147045cd774409b374d253d"), "name": "PolkadotNode", @@ -357,7 +359,11 @@ describe('serviceHelper tests', () => { "version": 2 } - await database.collection(collection).drop(); + try{ + await database.collection(collection).drop(); + } catch (err) { + console.log('Collection not found.'); + } await serviceHelper.insertOneToDatabase(database, collection, insertApp); }); @@ -382,6 +388,50 @@ describe('serviceHelper tests', () => { }); }); - + describe('verifyAdminSession tests', () => { + beforeEach(async () => { + const adminConfig = { + initial: { + ipaddress: '83.51.212.243', + zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + testnet: true + } + } + serviceHelper = proxyquire('../../ZelBack/src/services/serviceHelper', + { '../../../config/userconfig': adminConfig }); + + await serviceHelper.initiateDB(); + const db = serviceHelper.databaseConnection(); + const database = db.db(config.database.local.database); + const collection = config.database.local.collections.loggedUsers; + const insertUser = { + "_id": ObjectId("60cad0767247ac0a779fb3f0"), + "zelid": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", + "loginPhrase": "16125160820394ddsh5skgwv0ipodku92y0jbwvpyj17bh68lzrjlxq9", + "signature": "IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=" + } + + try{ + await database.collection(collection).drop(); + } catch (err) { + console.log('Collection not found.'); + } + + await serviceHelper.insertOneToDatabase(database, collection, insertUser); + }); + + + it("should return true when requested by admin", async () => { + const headers = { + zelidauth: { + zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' + } + } + + const verifyResponse = await serviceHelper.verifyAdminSession(headers); + console.log(verifyResponse); + }); + }) }); From 938fb4625c8f79a98a37a41f82068ae4be74c6a2 Mon Sep 17 00:00:00 2001 From: JacekAdamczyk Date: Wed, 16 Feb 2022 17:22:39 +0100 Subject: [PATCH 10/41] add more verifyAdmin tests --- tests/unit/globalconfig/default.js | 151 +++++++++++++++++++++++++++++ tests/unit/serviceHelper.test.js | 48 ++++++++- 2 files changed, 196 insertions(+), 3 deletions(-) create mode 100644 tests/unit/globalconfig/default.js diff --git a/tests/unit/globalconfig/default.js b/tests/unit/globalconfig/default.js new file mode 100644 index 000000000..54384558a --- /dev/null +++ b/tests/unit/globalconfig/default.js @@ -0,0 +1,151 @@ +module.exports = { + server: { + homeport: 16126, + apiport: 16127, + apiporthttps: 16128, + }, + database: { + url: '127.0.0.1', + port: 27017, + local: { + database: 'zelfluxlocaltest', + collections: { + loggedUsers: 'loggedusers', + activeLoginPhrases: 'activeloginphrases', + activeSignatures: 'activesignatures', + }, + }, + daemon: { + database: 'zelcashdatatest', + collections: { + // addreesIndex contains a) balance, b) list of all transacitons, c) list of utxos + scannedHeight: 'scannedheight', + utxoIndex: 'utxoindex', + addressTransactionIndex: 'addresstransactionindex', + fluxTransactions: 'zelnodetransactions', + appsHashes: 'zelappshashes', + coinbaseFusionIndex: 'coinbasefusionindex', + }, + }, + appslocal: { + database: 'localzelappstest', + collections: { + appsInformation: 'zelappsinformation', + }, + }, + appsglobal: { + database: 'globalzelappstest', + collections: { + appsMessages: 'zelappsmessages', // storage for all flux apps messages done on flux network + appsInformation: 'zelappsinformation', // stores actual state of flux app configuration info - initial state and its overwrites with update messages + appsTemporaryMessages: 'zelappstemporarymessages', // storages for all flux apps messages that are not yet confirmed on the flux network + appsLocations: 'zelappslocation', // stores location of flux apps as documents containing name, hash, ip, obtainedAt + }, + }, + fluxshare: { + database: 'zelsharetest', + collections: { + shared: 'shared', + }, + }, + }, + benchmark: { + port: 16225, + rpcport: 16224, + porttestnet: 26225, + rpcporttestnet: 26224, + }, + daemon: { + chainValidHeight: 770000, + port: 16125, + rpcport: 16124, + porttestnet: 26125, + rpcporttestnet: 26124, + }, + fluxTeamZelId: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', + fluxapps: { + // in flux main chain per month (blocksLasting) + price: [{ // any price fork can be done by adjusting object similarily. + height: 0, // height from which price spec is valid + cpu: 3, // per 0.1 cpu core, + ram: 1, // per 100mb, + hdd: 0.5, // per 1gb, + minPrice: 1, // minimum price that has to be paid for registration or update. Flux listens only to message above or equal this price + }, + { + height: 983000, // height from which price spec is valid. Counts from when app was registerd on blockchain! + cpu: 0.3, // per 0.1 cpu core, + ram: 0.1, // per 100mb, + hdd: 0.05, // per 1gb, + minPrice: 0.1, // minimum price that has to be paid for registration or update. Flux listens only to message above or equal this price + }, + { + height: 1004000, // height from which price spec is valid. Counts from when app was registerd on blockchain! 1004000 + cpu: 0.06, // per 0.1 cpu core, + ram: 0.02, // per 100mb, + hdd: 0.01, // per 1gb, + minPrice: 0.01, // minimum price that has to be paid for registration or update. Flux listens only to message above or equal this price + }], + appSpecsEnforcementHeights: { + 1: 0, // blockheight v1 is deprecated. Not possible to use api to update to its specs + 2: 0, // blockheight + 3: 983000, // blockheight. Since this blockheight specification of type 3 is active. User can still submit v1 or v2. UI allows only v2, v3 + 4: 1004000, // v4 available + }, + address: 't1LUs6quf7TB2zVZmexqPQdnqmrFMGZGjV6', + epochstart: 694000, + publicepochstart: 705000, + portMin: 31000, // ports 30000 - 30999 are reserved for local applications + portMax: 39999, + maxImageSize: 500000000, // 500mb possibly increase later + minimumInstances: 3, + maximumInstances: 100, + maximumAdditionalInstances: 1, // max instances above subscribed amount. In case of min instances, this is minimumInstances + maximumAdditionalInstances + minOutgoing: 5, + minIncoming: 2, + installation: { + probability: 100, // 1% + delay: 120, // in seconds + }, + removal: { + probability: 25, // 4% + delay: 300, + }, + redeploy: { + probability: 2, // 50% + delay: 30, + composedDelay: 5, + }, + blocksLasting: 22000, // registered app will live for 22000 of blocks 44000 minutes ~= 1 month + expireFluxAppsPeriod: 100, // every 100 blocks we run a check that deletes apps specifications and stops/removes the application from existence if it has been lastly updated more than 22k blocks ago + updateFluxAppsPeriod: 9, // every 9 blocks we check for reinstalling of old application versions + removeFluxAppsPeriod: 11, // every 11 blocks we check for more than maximum number of instances of an application + }, + lockedSystemResources: { + cpu: 10, // 1 cpu core + ram: 2000, // 2000mb + hdd: 30, // 30gb // this value is likely to rise + }, + fluxSpecifics: { + cpu: { + basic: 20, // 10 available for apps + super: 40, // 30 available for apps + bamf: 80, // 70 available for apps + }, + ram: { + basic: 3000, // 1000 available for apps + super: 7000, // 5000 available for apps + bamf: 30000, // available 28000 for apps + }, + hdd: { + basic: 50, // 20 for apps + super: 150, // 120 for apps + bamf: 600, // 570 for apps + }, + collateral: { + basic: 10000, + super: 25000, + bamf: 100000, + }, + }, +}; diff --git a/tests/unit/serviceHelper.test.js b/tests/unit/serviceHelper.test.js index a5cc080a9..73b262359 100644 --- a/tests/unit/serviceHelper.test.js +++ b/tests/unit/serviceHelper.test.js @@ -420,7 +420,6 @@ describe('serviceHelper tests', () => { await serviceHelper.insertOneToDatabase(database, collection, insertUser); }); - it("should return true when requested by admin", async () => { const headers = { zelidauth: { @@ -429,8 +428,51 @@ describe('serviceHelper tests', () => { } } - const verifyResponse = await serviceHelper.verifyAdminSession(headers); - console.log(verifyResponse); + const isAdmin = await serviceHelper.verifyAdminSession(headers); + expect(isAdmin).to.be.true; + }); + + it("should return false if signature is invalid", async () => { + const headers = { + zelidauth: { + zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + signature: 'IH9d68fk/dYQtzMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' + } + } + + const isAdmin = await serviceHelper.verifyAdminSession(headers); + expect(isAdmin).to.be.false; + }); + + it("should return false if zelID is invalid", async () => { + const headers = { + zelidauth: { + zelid: '2CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' + } + } + + const isAdmin = await serviceHelper.verifyAdminSession(headers); + expect(isAdmin).to.be.false; + }); + + it("should return false if header values are empty", async () => { + const headers = { + zelidauth: { + zelid: '', + signature: '' + } + } + + const isAdmin = await serviceHelper.verifyAdminSession(headers); + expect(isAdmin).to.be.false; + }); + + it("should return false if header is empty", async () => { + const headers = {} + + const isAdmin = await serviceHelper.verifyAdminSession(headers); + expect(isAdmin).to.be.false; }); }) }); From bb008d6125f21569a3cd7f01b77ec20dc5dc9572 Mon Sep 17 00:00:00 2001 From: JacekAdamczyk Date: Thu, 17 Feb 2022 07:43:49 +0100 Subject: [PATCH 11/41] move env variable to command and code cleanup --- package.json | 2 +- tests/unit/serviceHelper.test.js | 256 ++++++++++++++++++------------- 2 files changed, 151 insertions(+), 107 deletions(-) diff --git a/package.json b/package.json index 2071aa918..ec824c0b0 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "test:e2e": "vue-cli-service test:e2e", "test:unit": "vue-cli-service test:unit", "test:zelback": "mocha tests/ZelBack", - "test:zelback:unit": "mocha tests/unit/*.test.js --exit", + "test:zelback:unit": "env NODE_CONFIG_DIR=$PWD/tests/unit/globalconfig mocha tests/unit/*.test.js --exit", "homedev": "vue-cli-service serve --port 16126", "homeprod": "nodemon homeServer.js", "homebuild": "vue-cli-service build", diff --git a/tests/unit/serviceHelper.test.js b/tests/unit/serviceHelper.test.js index 73b262359..f38ffbb22 100644 --- a/tests/unit/serviceHelper.test.js +++ b/tests/unit/serviceHelper.test.js @@ -1,4 +1,3 @@ -process.env.NODE_CONFIG_DIR = `${process.cwd()}/tests/unit/globalconfig`; const chai = require('chai'); const config = require('config'); const { ObjectId } = require('mongodb'); @@ -15,65 +14,51 @@ describe('serviceHelper tests', () => { const restOfFalsyValues = [0n, null, undefined, NaN, '']; for (let falseBool of falseBools) { - it(`parameter ${typeof falseBool === 'string' ? `"${falseBool}"` : falseBool} should return false`, () => { + it(`parameter ${falseBool} of type ${typeof falseBool} should return false`, () => { expect(serviceHelper.ensureBoolean(falseBool)).to.equal(false); }); } + for (let trueBool of trueBools) { - it(`parameter ${typeof trueBool === 'string' ? `"${trueBool}"` : trueBool} should return false`, () => { + it(`parameter ${trueBool} of type ${typeof trueBool} should return false`, () => { expect(serviceHelper.ensureBoolean(trueBool)).to.equal(true); }); } + for (let truthyValue of restOfTruthyValues) { - it(`parameter ${typeof truthyValue === 'string' ? `"${truthyValue}"` : truthyValue} should return undefined`, () => { + it(`parameter ${truthyValue} of type ${typeof truthyValue} should return undefined`, () => { expect(serviceHelper.ensureBoolean(truthyValue)).to.be.undefined; }); } + for (let falsyValue of restOfFalsyValues) { - it(`parameter ${typeof falsyValue === 'string' ? `"${falsyValue}"` : falsyValue} should return undefined`, () => { + it(`parameter ${falsyValue} of type ${typeof falsyValue} should return undefined`, () => { expect(serviceHelper.ensureBoolean(falsyValue)).to.be.undefined; }); } + it('empty parameter should return undefined', () => { expect(serviceHelper.ensureBoolean()).to.be.undefined; }); }); describe('ensureNumber function tests', () => { - it('parameter 1 should return 1', () => { - const ensureNumberOutput = serviceHelper.ensureNumber(1); - const expected = 1; + const numbersList = [1, '1', 2.5, '2.5'] - expect(ensureNumberOutput).to.equal(expected) - expect(ensureNumberOutput).to.be.a('number') - }); - it('parameter "1" should return 1', () => { - const ensureNumberOutput = serviceHelper.ensureNumber("1"); - const expected = 1; + for (let number of numbersList) { + it(`parameter ${number} should return number value`, () => { + const ensureNumberOutput = serviceHelper.ensureNumber(1); - expect(ensureNumberOutput).to.equal(expected) - expect(ensureNumberOutput).to.be.a('number') - }); - it('parameter "2.5" should return 2.5', () => { - const ensureNumberOutput = serviceHelper.ensureNumber("2.5"); - const expected = 2.5; - - expect(ensureNumberOutput).to.equal(expected) - expect(ensureNumberOutput).to.be.a('number') - }); - it('parameter 2.5 should return 2.5', () => { - const ensureNumberOutput = serviceHelper.ensureNumber(2.5); - const expected = 2.5; + expect(ensureNumberOutput).to.be.a('number') + }); + } - expect(ensureNumberOutput).to.equal(expected) - expect(ensureNumberOutput).to.be.a('number') - }); - it('parameter "test" should return NaN', () => { + it('parameter "test" of type string should return NaN', () => { const ensureNumberOutput = serviceHelper.ensureNumber("test"); expect(ensureNumberOutput).to.be.NaN }); - it('parameter {name: 1} should return NaN', () => { + it('parameter {name: 1} of type object should return NaN', () => { const ensureNumberOutput = serviceHelper.ensureNumber({ name: 1 }); expect(ensureNumberOutput).to.be.NaN @@ -100,7 +85,7 @@ describe('serviceHelper tests', () => { }); it('parameter of type json string should return an object', () => { - const stringObject = '{"id": 1,"username": "Testing user"}'; + stringObject = JSON.stringify({ "id": 1, "username": "Testing user" }) const expected = { id: 1, username: 'Testing user' @@ -198,10 +183,10 @@ describe('serviceHelper tests', () => { it('should return a proper data message when called correctly', () => { const testData = { id: 55, message: 'this is my test message' }; - const createDataMessageOutput = serviceHelper.createDataMessage(testData); + const { status, data } = serviceHelper.createDataMessage(testData); - expect(createDataMessageOutput.status).to.equal('success'); - expect(createDataMessageOutput.data).to.equal(testData); + expect(status).to.equal('success'); + expect(data).to.equal(testData); }); }); @@ -211,12 +196,12 @@ describe('serviceHelper tests', () => { const name = 'Successful transfer'; const message = 'Your funds were transfered properly!'; - const createSuccessMessageOutput = serviceHelper.createSuccessMessage(message, name, code); + const { status, data } = serviceHelper.createSuccessMessage(message, name, code); - expect(createSuccessMessageOutput.status).to.equal('success'); - expect(createSuccessMessageOutput.data.code).to.equal(code); - expect(createSuccessMessageOutput.data.name).to.equal(name); - expect(createSuccessMessageOutput.data.message).to.equal(message); + expect(status).to.equal('success'); + expect(data.code).to.equal(code); + expect(data.name).to.equal(name); + expect(data.message).to.equal(message); }); }); @@ -226,12 +211,12 @@ describe('serviceHelper tests', () => { const name = 'Successful transfer'; const message = 'Your funds were transfered properly!'; - const createSuccessMessageOutput = serviceHelper.createSuccessMessage(message, name, code); + const { status, data } = serviceHelper.createSuccessMessage(message, name, code); - expect(createSuccessMessageOutput.status).to.equal('success'); - expect(createSuccessMessageOutput.data.code).to.equal(code); - expect(createSuccessMessageOutput.data.name).to.equal(name); - expect(createSuccessMessageOutput.data.message).to.equal(message); + expect(status).to.equal('success'); + expect(data.code).to.equal(code); + expect(data.name).to.equal(name); + expect(data.message).to.equal(message); }); it('should return a proper success message when called with empty message', () => { @@ -239,12 +224,12 @@ describe('serviceHelper tests', () => { const name = 'Successful transfer'; const message = ''; - const createSuccessMessageOutput = serviceHelper.createSuccessMessage(message, name, code); + const { status, data } = serviceHelper.createSuccessMessage(message, name, code); - expect(createSuccessMessageOutput.status).to.equal('success'); - expect(createSuccessMessageOutput.data.code).to.equal(code); - expect(createSuccessMessageOutput.data.name).to.equal(name); - expect(createSuccessMessageOutput.data.message).to.equal(message); + expect(status).to.equal('success'); + expect(data.code).to.equal(code); + expect(data.name).to.equal(name); + expect(data.message).to.equal(message); }); }); @@ -254,12 +239,12 @@ describe('serviceHelper tests', () => { const name = 'Warning!'; const message = 'There was a slight issue!'; - const createWarningMessageOutput = serviceHelper.createWarningMessage(message, name, code); + const { status, data } = serviceHelper.createWarningMessage(message, name, code); - expect(createWarningMessageOutput.status).to.equal('warning'); - expect(createWarningMessageOutput.data.code).to.equal(code); - expect(createWarningMessageOutput.data.name).to.equal(name); - expect(createWarningMessageOutput.data.message).to.equal(message); + expect(status).to.equal('warning'); + expect(data.code).to.equal(code); + expect(data.name).to.equal(name); + expect(data.message).to.equal(message); }); it('should return a proper warning message when called with empty message', () => { @@ -267,12 +252,12 @@ describe('serviceHelper tests', () => { const name = 'Warning!'; const message = ''; - const createSuccessMessageOutput = serviceHelper.createWarningMessage(message, name, code); + const { status, data } = serviceHelper.createWarningMessage(message, name, code); - expect(createSuccessMessageOutput.status).to.equal('warning'); - expect(createSuccessMessageOutput.data.code).to.equal(code); - expect(createSuccessMessageOutput.data.name).to.equal(name); - expect(createSuccessMessageOutput.data.message).to.equal(message); + expect(status).to.equal('warning'); + expect(data.code).to.equal(code); + expect(data.name).to.equal(name); + expect(data.message).to.equal(message); }); }); @@ -282,12 +267,12 @@ describe('serviceHelper tests', () => { const name = 'Error happened!!'; const message = 'There was a big error!'; - const createErrorMessageOutput = serviceHelper.createErrorMessage(message, name, code); + const { status, data } = serviceHelper.createErrorMessage(message, name, code); - expect(createErrorMessageOutput.status).to.equal('error'); - expect(createErrorMessageOutput.data.code).to.equal(code); - expect(createErrorMessageOutput.data.name).to.equal(name); - expect(createErrorMessageOutput.data.message).to.equal(message); + expect(status).to.equal('error'); + expect(data.code).to.equal(code); + expect(data.name).to.equal(name); + expect(data.message).to.equal(message); }); it('should return a proper error message when called with empty message', () => { @@ -296,12 +281,12 @@ describe('serviceHelper tests', () => { const message = ''; const expectedMessage = 'Unknown error'; - const createErrorMessageOutput = serviceHelper.createErrorMessage(message, name, code); + const { status, data } = serviceHelper.createErrorMessage(message, name, code); - expect(createErrorMessageOutput.status).to.equal('error'); - expect(createErrorMessageOutput.data.code).to.equal(code); - expect(createErrorMessageOutput.data.name).to.equal(name); - expect(createErrorMessageOutput.data.message).to.equal(expectedMessage); + expect(status).to.equal('error'); + expect(data.code).to.equal(code); + expect(data.name).to.equal(name); + expect(data.message).to.equal(expectedMessage); }); }); @@ -311,12 +296,12 @@ describe('serviceHelper tests', () => { const name = 'Unauthorized'; const message = 'Unauthorized. Access denied.'; - const errUnauthorizedMessageOutput = serviceHelper.errUnauthorizedMessage(message, name, code); + const { status, data } = serviceHelper.errUnauthorizedMessage(message, name, code); - expect(errUnauthorizedMessageOutput.status).to.equal('error'); - expect(errUnauthorizedMessageOutput.data.code).to.equal(code); - expect(errUnauthorizedMessageOutput.data.name).to.equal(name); - expect(errUnauthorizedMessageOutput.data.message).to.equal(message); + expect(status).to.equal('error'); + expect(data.code).to.equal(code); + expect(data.name).to.equal(name); + expect(data.message).to.equal(message); }); }); @@ -329,37 +314,11 @@ describe('serviceHelper tests', () => { const insertApp = { "_id": ObjectId("6147045cd774409b374d253d"), "name": "PolkadotNode", - "commands": [], - "containerData": "/chaindata", - "containerPorts": [ - "30333", - "9933", - "9944" - ], - "cpu": 0.8, "description": "Polkadot is a heterogeneous multi-chain interchange.", - "domains": [ - "polkadot.runonflux.io", - "polkadot.runonflux.io", - "polkadot.runonflux.io" - ], - "enviromentParameters": [], - "hash": "6f03b288240df90eb0d5a77c17c8fbea091619926ae66062da639b798fcf4ee5", - "hdd": 20, - "height": 988063, "owner": "196GJWyLxzAw3MirTT7Bqs2iGpUQio29GH", - "ports": [ - "31116", - "31115", - "31114" - ], - "ram": 1800, - "repotag": "runonflux/polkadot-docker:latest", - "tiered": false, - "version": 2 } - try{ + try { await database.collection(collection).drop(); } catch (err) { console.log('Collection not found.'); @@ -411,7 +370,7 @@ describe('serviceHelper tests', () => { "signature": "IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=" } - try{ + try { await database.collection(collection).drop(); } catch (err) { console.log('Collection not found.'); @@ -429,6 +388,7 @@ describe('serviceHelper tests', () => { } const isAdmin = await serviceHelper.verifyAdminSession(headers); + expect(isAdmin).to.be.true; }); @@ -441,6 +401,7 @@ describe('serviceHelper tests', () => { } const isAdmin = await serviceHelper.verifyAdminSession(headers); + expect(isAdmin).to.be.false; }); @@ -453,9 +414,10 @@ describe('serviceHelper tests', () => { } const isAdmin = await serviceHelper.verifyAdminSession(headers); + expect(isAdmin).to.be.false; }); - + it("should return false if header values are empty", async () => { const headers = { zelidauth: { @@ -465,6 +427,7 @@ describe('serviceHelper tests', () => { } const isAdmin = await serviceHelper.verifyAdminSession(headers); + expect(isAdmin).to.be.false; }); @@ -472,8 +435,89 @@ describe('serviceHelper tests', () => { const headers = {} const isAdmin = await serviceHelper.verifyAdminSession(headers); + expect(isAdmin).to.be.false; }); - }) + }); + + describe('verifyUserSession tests', () => { + beforeEach(async () => { + await serviceHelper.initiateDB(); + const db = serviceHelper.databaseConnection(); + const database = db.db(config.database.local.database); + const collection = config.database.local.collections.loggedUsers; + const insertUser = { + "_id": ObjectId("601f403878cbf33af2b07e63"), + "zelid": "1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t", + "loginPhrase": "16126607802409ki3t43zmwinlys5p0dxaokf420w59gvrio2bij61dzs", + "signature": "IMDMG1GuDasjPMkrGaRQhkLpFO0saBV+v+N6h3wP6/QlF3J9ymLAPZy7DCBd/RnOSzUxmTHruenVeR7LghzRnHA=" + } + + try { + await database.collection(collection).drop(); + } catch (err) { + console.log('Collection not found.'); + } + + await serviceHelper.insertOneToDatabase(database, collection, insertUser); + }); + + it("should return true when requested by logged user", async () => { + const headers = { + zelidauth: { + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', + signature: 'IMDMG1GuDasjPMkrGaRQhkLpFO0saBV+v+N6h3wP6/QlF3J9ymLAPZy7DCBd/RnOSzUxmTHruenVeR7LghzRnHA=' + } + } + + const isLoggedUser = await serviceHelper.verifyUserSession(headers); + + expect(isLoggedUser).to.be.true; + }); + + it("should return false if called with a wrong zelid", async () => { + const headers = { + zelidauth: { + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBu9t', + signature: 'IMDMG1GuDasjPMkrGaRQhkLpFO0saBV+v+N6h3wP6/QlF3J9ymLAPZy7DCBd/RnOSzUxmTHruenVeR7LghzRnHA=' + } + } + + const isLoggedUser = await serviceHelper.verifyUserSession(headers); + + expect(isLoggedUser).to.be.false; + }); + + it("should return false if called with a wrong signature", async () => { + const headers = { + zelidauth: { + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', + signature: 'IMDMG1GuDasjPMkrGaRQhkLpFO0saBZ+v+N6h3wP6/QlF3J9ymLAPZy7DCBd/RnOSzUxmTHruenVeR7LghzRnHA=' + } + } + + const isLoggedUser = await serviceHelper.verifyUserSession(headers); + + expect(isLoggedUser).to.be.false; + }); + it("should return false if called with no header", async () => { + const isLoggedUser = await serviceHelper.verifyUserSession(); + + expect(isLoggedUser).to.be.false; + }); + + it("should return false if called with empty data", async () => { + const headers = { + zelidauth: { + zelid: '', + signature: '' + } + } + + const isLoggedUser = await serviceHelper.verifyUserSession(headers); + + expect(isLoggedUser).to.be.false; + }); + }); }); From 0e79de09dd6f9f401c231ec0a285942422fbd0c0 Mon Sep 17 00:00:00 2001 From: JacekAdamczyk Date: Thu, 17 Feb 2022 16:44:03 +0100 Subject: [PATCH 12/41] verifyAdmin and verifyAdminAndFluxTeamSession tests --- tests/unit/globalconfig/default.js | 2 +- tests/unit/serviceHelper.test.js | 312 +++++++++++++++++++++++++++-- 2 files changed, 299 insertions(+), 15 deletions(-) diff --git a/tests/unit/globalconfig/default.js b/tests/unit/globalconfig/default.js index 54384558a..43b160e29 100644 --- a/tests/unit/globalconfig/default.js +++ b/tests/unit/globalconfig/default.js @@ -62,7 +62,7 @@ module.exports = { porttestnet: 26125, rpcporttestnet: 26124, }, - fluxTeamZelId: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', + fluxTeamZelId: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', fluxapps: { // in flux main chain per month (blocksLasting) price: [{ // any price fork can be done by adjusting object similarily. diff --git a/tests/unit/serviceHelper.test.js b/tests/unit/serviceHelper.test.js index f38ffbb22..560d1b035 100644 --- a/tests/unit/serviceHelper.test.js +++ b/tests/unit/serviceHelper.test.js @@ -6,6 +6,17 @@ const expect = chai.expect; let serviceHelper = require("../../ZelBack/src/services/serviceHelper"); +const adminConfig = { + initial: { + ipaddress: '83.51.212.243', + zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + testnet: true + } +} +serviceHelper = proxyquire('../../ZelBack/src/services/serviceHelper', + { '../../../config/userconfig': adminConfig }); + + describe('serviceHelper tests', () => { describe('ensureBoolean function tests', () => { const falseBools = ['false', false, 0, '0']; @@ -349,26 +360,21 @@ describe('serviceHelper tests', () => { describe('verifyAdminSession tests', () => { beforeEach(async () => { - const adminConfig = { - initial: { - ipaddress: '83.51.212.243', - zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', - testnet: true - } - } - serviceHelper = proxyquire('../../ZelBack/src/services/serviceHelper', - { '../../../config/userconfig': adminConfig }); - await serviceHelper.initiateDB(); const db = serviceHelper.databaseConnection(); const database = db.db(config.database.local.database); const collection = config.database.local.collections.loggedUsers; - const insertUser = { + const insertUsers = [{ "_id": ObjectId("60cad0767247ac0a779fb3f0"), - "zelid": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", + "zelid": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", // admin "loginPhrase": "16125160820394ddsh5skgwv0ipodku92y0jbwvpyj17bh68lzrjlxq9", "signature": "IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=" - } + }, { + "_id": ObjectId("6108fbb9f04dfe1ef624b819"), + "zelid": "1hjy4bCYBJr4mny4zCE85J94RXa8W6q37", // regular user + "loginPhrase": "162797868130153vt9r89dzjjjfg6kf34ntf1d8aa5zqlk04j3zy8z40ni", + "signature": "H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=" + }]; try { await database.collection(collection).drop(); @@ -376,7 +382,9 @@ describe('serviceHelper tests', () => { console.log('Collection not found.'); } - await serviceHelper.insertOneToDatabase(database, collection, insertUser); + for (let insertUser of insertUsers) { + await serviceHelper.insertOneToDatabase(database, collection, insertUser); + } }); it("should return true when requested by admin", async () => { @@ -392,6 +400,19 @@ describe('serviceHelper tests', () => { expect(isAdmin).to.be.true; }); + it("should return false when requested by regular user", async () => { + const headers = { + zelidauth: { + zelid: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', + signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=' + } + } + + const isAdmin = await serviceHelper.verifyAdminSession(headers); + + expect(isAdmin).to.be.false; + }); + it("should return false if signature is invalid", async () => { const headers = { zelidauth: { @@ -519,5 +540,268 @@ describe('serviceHelper tests', () => { expect(isLoggedUser).to.be.false; }); }); + + describe('verifyFluxTeamSession tests', () => { + beforeEach(async () => { + await serviceHelper.initiateDB(); + const db = serviceHelper.databaseConnection(); + const database = db.db(config.database.local.database); + const collection = config.database.local.collections.loggedUsers; + const insertUsers = [{ + "_id": ObjectId("60cad0767247ac0a779fb3f0"), + "zelid": "1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM", // flux team + "loginPhrase": "1623904359736pja76q7y68deb4264olbml6o8gyhot2yvj5oevgv9k2", + "signature": "H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=" + }, { + "_id": ObjectId("6108fbb9f04dfe1ef624b819"), + "zelid": "1hjy4bCYBJr4mny4zCE85J94RXa8W6q37", // regular user + "loginPhrase": "162797868130153vt9r89dzjjjfg6kf34ntf1d8aa5zqlk04j3zy8z40ni", + "signature": "H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=" + }]; + try { + await database.collection(collection).drop(); + } catch (err) { + console.log('Collection not found.'); + } + + for (let insertUser of insertUsers) { + await serviceHelper.insertOneToDatabase(database, collection, insertUser); + } + }); + + it("should return true when requested by the flux team", async () => { + const headers = { + zelidauth: { + zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', + signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' + } + }; + + const isFluxTeamSession = await serviceHelper.verifyFluxTeamSession(headers); + + expect(isFluxTeamSession).to.be.true; + }); + + it("should return false when zelid is not the flux team", async () => { + const headers = { + zelidauth: { + zelid: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', + signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=' + } + }; + + const isFluxTeamSession = await serviceHelper.verifyFluxTeamSession(headers); + + expect(isFluxTeamSession).to.be.false; + }); + + + it("should return false when signature is invalid", async () => { + const headers = { + zelidauth: { + zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', + signature: 'N4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' + } + }; + + const isFluxTeamSession = await serviceHelper.verifyFluxTeamSession(headers); + + expect(isFluxTeamSession).to.be.false; + }); + + it("should return false when zelid is invalid", async () => { + const headers = { + zelidauth: { + zelid: '1NH9BP1z5Rp3HSf5ef6NpUbE8JcyLRruAM', + signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' + } + }; + + const isFluxTeamSession = await serviceHelper.verifyFluxTeamSession(headers); + + expect(isFluxTeamSession).to.be.false; + }); + + it("should return false when data is empty", async () => { + const headers = { + zelidauth: { + zelid: '', + signature: '' + } + }; + + const isFluxTeamSession = await serviceHelper.verifyFluxTeamSession(headers); + + expect(isFluxTeamSession).to.be.false; + }); + + it("should return false when data are true bools", async () => { + const headers = { + zelidauth: { + zelid: true, + signature: true + } + }; + + const isFluxTeamSession = await serviceHelper.verifyFluxTeamSession(headers); + + expect(isFluxTeamSession).to.be.false; + }); + + it("should return false when header is empty", async () => { + const headers = {}; + + const isFluxTeamSession = await serviceHelper.verifyFluxTeamSession(headers); + + expect(isFluxTeamSession).to.be.false; + }); + + it("should return false when no header is passed", async () => { + const isFluxTeamSession = await serviceHelper.verifyFluxTeamSession(); + + expect(isFluxTeamSession).to.be.false; + }); + }); + + describe('verifyAdminAndFluxTeamSession tests', () => { + beforeEach(async () => { + await serviceHelper.initiateDB(); + const db = serviceHelper.databaseConnection(); + const database = db.db(config.database.local.database); + const collection = config.database.local.collections.loggedUsers; + const insertUsers = [{ + "_id": ObjectId("61967125f3178f082a296100"), + "zelid": "1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM", // Flux team + "loginPhrase": "1623904359736pja76q7y68deb4264olbml6o8gyhot2yvj5oevgv9k2", + "signature": "H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=" + }, { + "_id": ObjectId("6108fbb9f04dfe1ef624b819"), + "zelid": "1hjy4bCYBJr4mny4zCE85J94RXa8W6q37", // regular user + "loginPhrase": "162797868130153vt9r89dzjjjfg6kf34ntf1d8aa5zqlk04j3zy8z40ni", + "signature": "H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=" + }, { + "_id": ObjectId("60cad0767247ac0a779fb3f0"), + "zelid": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", // admin + "loginPhrase": "16125160820394ddsh5skgwv0ipodku92y0jbwvpyj17bh68lzrjlxq9", + "signature": "IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=" + } + ]; + try { + await database.collection(collection).drop(); + } catch (err) { + console.log('Collection not found.'); + } + + for (let insertUser of insertUsers) { + await serviceHelper.insertOneToDatabase(database, collection, insertUser); + } + }); + + it("should return true when requested by the flux team", async () => { + const headers = { + zelidauth: { + zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', + signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' + } + }; + + const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(headers); + + expect(isAdminOrFluxTeam).to.be.true; + }); + + it("should return true when requested by the admin", async () => { + const headers = { + zelidauth: { + zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' + } + }; + + const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(headers); + + expect(isAdminOrFluxTeam).to.be.true; + }); + + it("should return false when zelid is not the flux team", async () => { + const headers = { + zelidauth: { + zelid: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', + signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=' + } + }; + + const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(headers); + + expect(isAdminOrFluxTeam).to.be.false; + }); + + + it("should return false when signature is invalid", async () => { + const headers = { + zelidauth: { + zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', + signature: 'N4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' + } + }; + + const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(headers); + + expect(isAdminOrFluxTeam).to.be.false; + }); + + it("should return false when zelid is invalid", async () => { + const headers = { + zelidauth: { + zelid: '1NH9BP1z5Rp3HSf5ef6NpUbE8JcyLRruAM', + signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' + } + }; + + const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(headers); + + expect(isAdminOrFluxTeam).to.be.false; + }); + + it("should return false when data is empty", async () => { + const headers = { + zelidauth: { + zelid: '', + signature: '' + } + }; + + const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(headers); + + expect(isAdminOrFluxTeam).to.be.false; + }); + + it("should return false when data are true bools", async () => { + const headers = { + zelidauth: { + zelid: true, + signature: true + } + }; + + const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(headers); + + expect(isAdminOrFluxTeam).to.be.false; + }); + + it("should return false when header is empty", async () => { + const headers = {}; + + const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(headers); + + expect(isAdminOrFluxTeam).to.be.false; + }); + + it("should return false when no header is passed", async () => { + const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(); + + expect(isAdminOrFluxTeam).to.be.false; + }); + }); }); From 7aad1ec67d98a5442ad4ed7ce06d8aa2a2c0db6b Mon Sep 17 00:00:00 2001 From: JacekAdamczyk Date: Fri, 18 Feb 2022 18:14:31 +0100 Subject: [PATCH 13/41] add more session tests --- ZelBack/src/services/serviceHelper.js | 5 - package.json | 1 + tests/unit/serviceHelper.test.js | 277 +++++++++++++++++++++++++- 3 files changed, 275 insertions(+), 8 deletions(-) diff --git a/ZelBack/src/services/serviceHelper.js b/ZelBack/src/services/serviceHelper.js index c5c141359..e7c99aea2 100644 --- a/ZelBack/src/services/serviceHelper.js +++ b/ZelBack/src/services/serviceHelper.js @@ -224,11 +224,7 @@ async function getApplicationOwner(appName) { async function verifyAdminSession(headers) { if (headers && headers.zelidauth) { const auth = ensureObject(headers.zelidauth); - console.log(auth); if (auth.zelid && auth.signature) { - console.log(auth.zelid); - console.log(auth.signature); - console.log(userconfig.initial.zelid); if (auth.zelid === userconfig.initial.zelid) { const db = databaseConnection(); const database = db.db(config.database.local.database); @@ -267,7 +263,6 @@ async function verifyAdminSession(headers) { async function verifyUserSession(headers) { if (headers && headers.zelidauth) { const auth = ensureObject(headers.zelidauth); - console.log(auth); if (auth.zelid && auth.signature) { const db = databaseConnection(); const database = db.db(config.database.local.database); diff --git a/package.json b/package.json index ec824c0b0..6904a1f97 100644 --- a/package.json +++ b/package.json @@ -130,6 +130,7 @@ "retry-axios": "^2.6.0", "sass": "^1.43.4", "sass-loader": "^10.1.1", + "sinon": "^13.0.1", "supertest": "^6.1.6", "uuid": "^8.3.2", "vee-validate": "^3.4.13", diff --git a/tests/unit/serviceHelper.test.js b/tests/unit/serviceHelper.test.js index 560d1b035..7816c84c0 100644 --- a/tests/unit/serviceHelper.test.js +++ b/tests/unit/serviceHelper.test.js @@ -3,6 +3,7 @@ const config = require('config'); const { ObjectId } = require('mongodb'); var proxyquire = require('proxyquire'); const expect = chai.expect; +const sinon = require('sinon'); let serviceHelper = require("../../ZelBack/src/services/serviceHelper"); @@ -684,8 +685,7 @@ describe('serviceHelper tests', () => { "zelid": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", // admin "loginPhrase": "16125160820394ddsh5skgwv0ipodku92y0jbwvpyj17bh68lzrjlxq9", "signature": "IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=" - } - ]; + }]; try { await database.collection(collection).drop(); } catch (err) { @@ -803,5 +803,276 @@ describe('serviceHelper tests', () => { expect(isAdminOrFluxTeam).to.be.false; }); }); -}); + describe('verifyAppOwnerSession tests', () => { + beforeEach(async () => { + await serviceHelper.initiateDB(); + const db = serviceHelper.databaseConnection(); + const databaseLocal = db.db(config.database.local.database); + const collectionLoggedUsers = config.database.local.collections.loggedUsers; + const insertUsers = [{ + "_id": ObjectId("6108fbb9f04dfe1ef624b819"), + "zelid": "1hjy4bCYBJr4mny4zCE85J94RXa8W6q37", // regular user + "loginPhrase": "162797868130153vt9r89dzjjjfg6kf34ntf1d8aa5zqlk04j3zy8z40ni", + "signature": "H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=" + }, { + "_id": ObjectId("60cad0767247ac0a779fb3f0"), + "zelid": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", // admin + "loginPhrase": "16125160820394ddsh5skgwv0ipodku92y0jbwvpyj17bh68lzrjlxq9", + "signature": "IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=" + }, { + "_id": ObjectId("620bbc40c04b4966674013a8"), + "zelid": "1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t", // app owner + "loginPhrase": "1644935889016mtmbo4uah32tvvwrmzg4j8qzv04ba8g8n56cevn6b", + "signature": "H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=" + } + ]; + try { + await databaseLocal.collection(collectionLoggedUsers).drop(); + } catch (err) { + console.log('Collection not found.'); + } + + for (let insertUser of insertUsers) { + await serviceHelper.insertOneToDatabase(databaseLocal, collectionLoggedUsers, insertUser); + } + + + const databaseGlobal = db.db(config.database.appsglobal.database); + const collectionApps = config.database.appsglobal.collections.appsInformation; + const insertApp = { + "_id": ObjectId("6147045cd774409b374d253d"), + "name": "PolkadotNode", + "description": "Polkadot is a heterogeneous multi-chain interchange.", + "owner": "1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t", + } + + try { + await databaseGlobal.collection(collectionApps).drop(); + } catch (err) { + console.log('Collection not found.'); + } + await serviceHelper.insertOneToDatabase(databaseGlobal, collectionApps, insertApp); + + }); + + it("should return true when requested by the app owner", async () => { + const headers = { + zelidauth: { + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', + signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=' + } + }; + const appName = 'PolkadotNode'; + const isOwnerSession = await serviceHelper.verifyAppOwnerSession(headers, appName); + + expect(isOwnerSession).to.be.true; + }); + + it("should return false when requested by the admin", async () => { + const headers = { + zelidauth: { + zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' + } + }; + const appName = 'PolkadotNode'; + const isOwnerSession = await serviceHelper.verifyAppOwnerSession(headers, appName); + + expect(isOwnerSession).to.be.false; + }); + + it("should return false when requested by the owner with a wrong signature", async () => { + const headers = { + zelidauth: { + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' + } + }; + const appName = 'PolkadotNode'; + const isOwnerSession = await serviceHelper.verifyAppOwnerSession(headers, appName); + + expect(isOwnerSession).to.be.false; + }); + + it("should return false when requested with empty header data", async () => { + const headers = { + zelidauth: { + zelid: '', + signature: '' + } + }; + const appName = 'PolkadotNode'; + const isOwnerSession = await serviceHelper.verifyAppOwnerSession(headers, appName); + + expect(isOwnerSession).to.be.false; + }); + + it("should return false when requested with empty header ", async () => { + const headers = {}; + + const appName = 'PolkadotNode'; + const isOwnerSession = await serviceHelper.verifyAppOwnerSession(headers, appName); + + expect(isOwnerSession).to.be.false; + }); + + it("should return true when requested with an empty app name", async () => { + const headers = { + zelidauth: { + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', + signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=' + } + }; + const appName = ''; + const isOwnerSession = await serviceHelper.verifyAppOwnerSession(headers, appName); + + expect(isOwnerSession).to.be.false; + }); + }); + + describe('verifyAppOwnerSessionOrHigher tests', () => { + beforeEach(async () => { + await serviceHelper.initiateDB(); + const db = serviceHelper.databaseConnection(); + const databaseLocal = db.db(config.database.local.database); + const collectionLoggedUsers = config.database.local.collections.loggedUsers; + const insertUsers = [{ + "_id": ObjectId("6108fbb9f04dfe1ef624b819"), + "zelid": "1hjy4bCYBJr4mny4zCE85J94RXa8W6q37", // regular user + "loginPhrase": "162797868130153vt9r89dzjjjfg6kf34ntf1d8aa5zqlk04j3zy8z40ni", + "signature": "H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=" + }, { + "_id": ObjectId("60cad0767247ac0a779fb3f0"), + "zelid": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", // admin + "loginPhrase": "16125160820394ddsh5skgwv0ipodku92y0jbwvpyj17bh68lzrjlxq9", + "signature": "IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=" + }, { + "_id": ObjectId("620bbc40c04b4966674013a8"), + "zelid": "1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t", // app owner + "loginPhrase": "1644935889016mtmbo4uah32tvvwrmzg4j8qzv04ba8g8n56cevn6b", + "signature": "H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=" + }, { + "_id": ObjectId("61967125f3178f082a296100"), + "zelid": "1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM", // Flux team + "loginPhrase": "1623904359736pja76q7y68deb4264olbml6o8gyhot2yvj5oevgv9k2", + "signature": "H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=" + } + ]; + try { + await databaseLocal.collection(collectionLoggedUsers).drop(); + } catch (err) { + console.log('Collection not found.'); + } + + for (let insertUser of insertUsers) { + await serviceHelper.insertOneToDatabase(databaseLocal, collectionLoggedUsers, insertUser); + } + + + const databaseGlobal = db.db(config.database.appsglobal.database); + const collectionApps = config.database.appsglobal.collections.appsInformation; + const insertApp = { + "_id": ObjectId("6147045cd774409b374d253d"), + "name": "PolkadotNode", + "description": "Polkadot is a heterogeneous multi-chain interchange.", + "owner": "1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t", + } + + try { + await databaseGlobal.collection(collectionApps).drop(); + } catch (err) { + console.log('Collection not found.'); + } + await serviceHelper.insertOneToDatabase(databaseGlobal, collectionApps, insertApp); + + }); + + it("should return true when requested by the app owner", async () => { + const headers = { + zelidauth: { + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', + signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=' + } + }; + const appName = 'PolkadotNode'; + const isOwnerOrHigherSession = await serviceHelper.verifyAppOwnerOrHigherSession(headers, appName); + + expect(isOwnerOrHigherSession).to.be.true; + }); + + it("should return true when requested by the admin", async () => { + const headers = { + zelidauth: { + zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' + } + }; + const appName = 'PolkadotNode'; + const isOwnerOrHigherSession = await serviceHelper.verifyAppOwnerOrHigherSession(headers, appName); + + expect(isOwnerOrHigherSession).to.be.true; + }); + + it("should return true when requested by the flux team", async () => { + const headers = { + zelidauth: { + zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', + signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' + } + }; + const appName = 'PolkadotNode'; + const isOwnerOrHigherSession = await serviceHelper.verifyAppOwnerOrHigherSession(headers, appName); + + expect(isOwnerOrHigherSession).to.be.true; + }); + + it("should return false when requested by the owner with a wrong signature", async () => { + const headers = { + zelidauth: { + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' + } + }; + const appName = 'PolkadotNode'; + const isOwnerOrHigherSession = await serviceHelper.verifyAppOwnerOrHigherSession(headers, appName); + + expect(isOwnerOrHigherSession).to.be.false; + }); + + it("should return false when requested with empty header data", async () => { + const headers = { + zelidauth: { + zelid: '', + signature: '' + } + }; + const appName = 'PolkadotNode'; + const isOwnerOrHigherSession = await serviceHelper.verifyAppOwnerOrHigherSession(headers, appName); + + expect(isOwnerOrHigherSession).to.be.false; + }); + + it("should return false when requested with empty header ", async () => { + const headers = {}; + + const appName = 'PolkadotNode'; + const isOwnerOrHigherSession = await serviceHelper.verifyAppOwnerOrHigherSession(headers, appName); + + expect(isOwnerOrHigherSession).to.be.false; + }); + + it("should return true when requested with an empty app name", async () => { + const headers = { + zelidauth: { + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', + signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=' + } + }; + const appName = ''; + const isOwnerOrHigherSession = await serviceHelper.verifyAppOwnerOrHigherSession(headers, appName); + + expect(isOwnerOrHigherSession).to.be.false; + }); + }); +}); From ceb6f4c987157b0f32fbc94b4fb65c7eed64c432 Mon Sep 17 00:00:00 2001 From: JacekAdamczyk Date: Mon, 21 Feb 2022 12:23:02 +0100 Subject: [PATCH 14/41] refactoring Verification - WIP --- tests/unit/serviceHelper.test.js | 613 ------------------------------- 1 file changed, 613 deletions(-) diff --git a/tests/unit/serviceHelper.test.js b/tests/unit/serviceHelper.test.js index 7816c84c0..8efdad2b7 100644 --- a/tests/unit/serviceHelper.test.js +++ b/tests/unit/serviceHelper.test.js @@ -462,617 +462,4 @@ describe('serviceHelper tests', () => { }); }); - describe('verifyUserSession tests', () => { - beforeEach(async () => { - await serviceHelper.initiateDB(); - const db = serviceHelper.databaseConnection(); - const database = db.db(config.database.local.database); - const collection = config.database.local.collections.loggedUsers; - const insertUser = { - "_id": ObjectId("601f403878cbf33af2b07e63"), - "zelid": "1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t", - "loginPhrase": "16126607802409ki3t43zmwinlys5p0dxaokf420w59gvrio2bij61dzs", - "signature": "IMDMG1GuDasjPMkrGaRQhkLpFO0saBV+v+N6h3wP6/QlF3J9ymLAPZy7DCBd/RnOSzUxmTHruenVeR7LghzRnHA=" - } - - try { - await database.collection(collection).drop(); - } catch (err) { - console.log('Collection not found.'); - } - - await serviceHelper.insertOneToDatabase(database, collection, insertUser); - }); - - it("should return true when requested by logged user", async () => { - const headers = { - zelidauth: { - zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', - signature: 'IMDMG1GuDasjPMkrGaRQhkLpFO0saBV+v+N6h3wP6/QlF3J9ymLAPZy7DCBd/RnOSzUxmTHruenVeR7LghzRnHA=' - } - } - - const isLoggedUser = await serviceHelper.verifyUserSession(headers); - - expect(isLoggedUser).to.be.true; - }); - - it("should return false if called with a wrong zelid", async () => { - const headers = { - zelidauth: { - zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBu9t', - signature: 'IMDMG1GuDasjPMkrGaRQhkLpFO0saBV+v+N6h3wP6/QlF3J9ymLAPZy7DCBd/RnOSzUxmTHruenVeR7LghzRnHA=' - } - } - - const isLoggedUser = await serviceHelper.verifyUserSession(headers); - - expect(isLoggedUser).to.be.false; - }); - - it("should return false if called with a wrong signature", async () => { - const headers = { - zelidauth: { - zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', - signature: 'IMDMG1GuDasjPMkrGaRQhkLpFO0saBZ+v+N6h3wP6/QlF3J9ymLAPZy7DCBd/RnOSzUxmTHruenVeR7LghzRnHA=' - } - } - - const isLoggedUser = await serviceHelper.verifyUserSession(headers); - - expect(isLoggedUser).to.be.false; - }); - it("should return false if called with no header", async () => { - const isLoggedUser = await serviceHelper.verifyUserSession(); - - expect(isLoggedUser).to.be.false; - }); - - it("should return false if called with empty data", async () => { - const headers = { - zelidauth: { - zelid: '', - signature: '' - } - } - - const isLoggedUser = await serviceHelper.verifyUserSession(headers); - - expect(isLoggedUser).to.be.false; - }); - }); - - describe('verifyFluxTeamSession tests', () => { - beforeEach(async () => { - await serviceHelper.initiateDB(); - const db = serviceHelper.databaseConnection(); - const database = db.db(config.database.local.database); - const collection = config.database.local.collections.loggedUsers; - const insertUsers = [{ - "_id": ObjectId("60cad0767247ac0a779fb3f0"), - "zelid": "1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM", // flux team - "loginPhrase": "1623904359736pja76q7y68deb4264olbml6o8gyhot2yvj5oevgv9k2", - "signature": "H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=" - }, { - "_id": ObjectId("6108fbb9f04dfe1ef624b819"), - "zelid": "1hjy4bCYBJr4mny4zCE85J94RXa8W6q37", // regular user - "loginPhrase": "162797868130153vt9r89dzjjjfg6kf34ntf1d8aa5zqlk04j3zy8z40ni", - "signature": "H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=" - }]; - try { - await database.collection(collection).drop(); - } catch (err) { - console.log('Collection not found.'); - } - - for (let insertUser of insertUsers) { - await serviceHelper.insertOneToDatabase(database, collection, insertUser); - } - }); - - it("should return true when requested by the flux team", async () => { - const headers = { - zelidauth: { - zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', - signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' - } - }; - - const isFluxTeamSession = await serviceHelper.verifyFluxTeamSession(headers); - - expect(isFluxTeamSession).to.be.true; - }); - - it("should return false when zelid is not the flux team", async () => { - const headers = { - zelidauth: { - zelid: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', - signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=' - } - }; - - const isFluxTeamSession = await serviceHelper.verifyFluxTeamSession(headers); - - expect(isFluxTeamSession).to.be.false; - }); - - - it("should return false when signature is invalid", async () => { - const headers = { - zelidauth: { - zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', - signature: 'N4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' - } - }; - - const isFluxTeamSession = await serviceHelper.verifyFluxTeamSession(headers); - - expect(isFluxTeamSession).to.be.false; - }); - - it("should return false when zelid is invalid", async () => { - const headers = { - zelidauth: { - zelid: '1NH9BP1z5Rp3HSf5ef6NpUbE8JcyLRruAM', - signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' - } - }; - - const isFluxTeamSession = await serviceHelper.verifyFluxTeamSession(headers); - - expect(isFluxTeamSession).to.be.false; - }); - - it("should return false when data is empty", async () => { - const headers = { - zelidauth: { - zelid: '', - signature: '' - } - }; - - const isFluxTeamSession = await serviceHelper.verifyFluxTeamSession(headers); - - expect(isFluxTeamSession).to.be.false; - }); - - it("should return false when data are true bools", async () => { - const headers = { - zelidauth: { - zelid: true, - signature: true - } - }; - - const isFluxTeamSession = await serviceHelper.verifyFluxTeamSession(headers); - - expect(isFluxTeamSession).to.be.false; - }); - - it("should return false when header is empty", async () => { - const headers = {}; - - const isFluxTeamSession = await serviceHelper.verifyFluxTeamSession(headers); - - expect(isFluxTeamSession).to.be.false; - }); - - it("should return false when no header is passed", async () => { - const isFluxTeamSession = await serviceHelper.verifyFluxTeamSession(); - - expect(isFluxTeamSession).to.be.false; - }); - }); - - describe('verifyAdminAndFluxTeamSession tests', () => { - beforeEach(async () => { - await serviceHelper.initiateDB(); - const db = serviceHelper.databaseConnection(); - const database = db.db(config.database.local.database); - const collection = config.database.local.collections.loggedUsers; - const insertUsers = [{ - "_id": ObjectId("61967125f3178f082a296100"), - "zelid": "1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM", // Flux team - "loginPhrase": "1623904359736pja76q7y68deb4264olbml6o8gyhot2yvj5oevgv9k2", - "signature": "H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=" - }, { - "_id": ObjectId("6108fbb9f04dfe1ef624b819"), - "zelid": "1hjy4bCYBJr4mny4zCE85J94RXa8W6q37", // regular user - "loginPhrase": "162797868130153vt9r89dzjjjfg6kf34ntf1d8aa5zqlk04j3zy8z40ni", - "signature": "H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=" - }, { - "_id": ObjectId("60cad0767247ac0a779fb3f0"), - "zelid": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", // admin - "loginPhrase": "16125160820394ddsh5skgwv0ipodku92y0jbwvpyj17bh68lzrjlxq9", - "signature": "IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=" - }]; - try { - await database.collection(collection).drop(); - } catch (err) { - console.log('Collection not found.'); - } - - for (let insertUser of insertUsers) { - await serviceHelper.insertOneToDatabase(database, collection, insertUser); - } - }); - - it("should return true when requested by the flux team", async () => { - const headers = { - zelidauth: { - zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', - signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' - } - }; - - const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(headers); - - expect(isAdminOrFluxTeam).to.be.true; - }); - - it("should return true when requested by the admin", async () => { - const headers = { - zelidauth: { - zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', - signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' - } - }; - - const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(headers); - - expect(isAdminOrFluxTeam).to.be.true; - }); - - it("should return false when zelid is not the flux team", async () => { - const headers = { - zelidauth: { - zelid: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', - signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=' - } - }; - - const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(headers); - - expect(isAdminOrFluxTeam).to.be.false; - }); - - - it("should return false when signature is invalid", async () => { - const headers = { - zelidauth: { - zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', - signature: 'N4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' - } - }; - - const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(headers); - - expect(isAdminOrFluxTeam).to.be.false; - }); - - it("should return false when zelid is invalid", async () => { - const headers = { - zelidauth: { - zelid: '1NH9BP1z5Rp3HSf5ef6NpUbE8JcyLRruAM', - signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' - } - }; - - const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(headers); - - expect(isAdminOrFluxTeam).to.be.false; - }); - - it("should return false when data is empty", async () => { - const headers = { - zelidauth: { - zelid: '', - signature: '' - } - }; - - const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(headers); - - expect(isAdminOrFluxTeam).to.be.false; - }); - - it("should return false when data are true bools", async () => { - const headers = { - zelidauth: { - zelid: true, - signature: true - } - }; - - const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(headers); - - expect(isAdminOrFluxTeam).to.be.false; - }); - - it("should return false when header is empty", async () => { - const headers = {}; - - const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(headers); - - expect(isAdminOrFluxTeam).to.be.false; - }); - - it("should return false when no header is passed", async () => { - const isAdminOrFluxTeam = await serviceHelper.verifyAdminAndFluxTeamSession(); - - expect(isAdminOrFluxTeam).to.be.false; - }); - }); - - describe('verifyAppOwnerSession tests', () => { - beforeEach(async () => { - await serviceHelper.initiateDB(); - const db = serviceHelper.databaseConnection(); - const databaseLocal = db.db(config.database.local.database); - const collectionLoggedUsers = config.database.local.collections.loggedUsers; - const insertUsers = [{ - "_id": ObjectId("6108fbb9f04dfe1ef624b819"), - "zelid": "1hjy4bCYBJr4mny4zCE85J94RXa8W6q37", // regular user - "loginPhrase": "162797868130153vt9r89dzjjjfg6kf34ntf1d8aa5zqlk04j3zy8z40ni", - "signature": "H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=" - }, { - "_id": ObjectId("60cad0767247ac0a779fb3f0"), - "zelid": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", // admin - "loginPhrase": "16125160820394ddsh5skgwv0ipodku92y0jbwvpyj17bh68lzrjlxq9", - "signature": "IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=" - }, { - "_id": ObjectId("620bbc40c04b4966674013a8"), - "zelid": "1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t", // app owner - "loginPhrase": "1644935889016mtmbo4uah32tvvwrmzg4j8qzv04ba8g8n56cevn6b", - "signature": "H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=" - } - ]; - try { - await databaseLocal.collection(collectionLoggedUsers).drop(); - } catch (err) { - console.log('Collection not found.'); - } - - for (let insertUser of insertUsers) { - await serviceHelper.insertOneToDatabase(databaseLocal, collectionLoggedUsers, insertUser); - } - - - const databaseGlobal = db.db(config.database.appsglobal.database); - const collectionApps = config.database.appsglobal.collections.appsInformation; - const insertApp = { - "_id": ObjectId("6147045cd774409b374d253d"), - "name": "PolkadotNode", - "description": "Polkadot is a heterogeneous multi-chain interchange.", - "owner": "1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t", - } - - try { - await databaseGlobal.collection(collectionApps).drop(); - } catch (err) { - console.log('Collection not found.'); - } - await serviceHelper.insertOneToDatabase(databaseGlobal, collectionApps, insertApp); - - }); - - it("should return true when requested by the app owner", async () => { - const headers = { - zelidauth: { - zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', - signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=' - } - }; - const appName = 'PolkadotNode'; - const isOwnerSession = await serviceHelper.verifyAppOwnerSession(headers, appName); - - expect(isOwnerSession).to.be.true; - }); - - it("should return false when requested by the admin", async () => { - const headers = { - zelidauth: { - zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', - signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' - } - }; - const appName = 'PolkadotNode'; - const isOwnerSession = await serviceHelper.verifyAppOwnerSession(headers, appName); - - expect(isOwnerSession).to.be.false; - }); - - it("should return false when requested by the owner with a wrong signature", async () => { - const headers = { - zelidauth: { - zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', - signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' - } - }; - const appName = 'PolkadotNode'; - const isOwnerSession = await serviceHelper.verifyAppOwnerSession(headers, appName); - - expect(isOwnerSession).to.be.false; - }); - - it("should return false when requested with empty header data", async () => { - const headers = { - zelidauth: { - zelid: '', - signature: '' - } - }; - const appName = 'PolkadotNode'; - const isOwnerSession = await serviceHelper.verifyAppOwnerSession(headers, appName); - - expect(isOwnerSession).to.be.false; - }); - - it("should return false when requested with empty header ", async () => { - const headers = {}; - - const appName = 'PolkadotNode'; - const isOwnerSession = await serviceHelper.verifyAppOwnerSession(headers, appName); - - expect(isOwnerSession).to.be.false; - }); - - it("should return true when requested with an empty app name", async () => { - const headers = { - zelidauth: { - zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', - signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=' - } - }; - const appName = ''; - const isOwnerSession = await serviceHelper.verifyAppOwnerSession(headers, appName); - - expect(isOwnerSession).to.be.false; - }); - }); - - describe('verifyAppOwnerSessionOrHigher tests', () => { - beforeEach(async () => { - await serviceHelper.initiateDB(); - const db = serviceHelper.databaseConnection(); - const databaseLocal = db.db(config.database.local.database); - const collectionLoggedUsers = config.database.local.collections.loggedUsers; - const insertUsers = [{ - "_id": ObjectId("6108fbb9f04dfe1ef624b819"), - "zelid": "1hjy4bCYBJr4mny4zCE85J94RXa8W6q37", // regular user - "loginPhrase": "162797868130153vt9r89dzjjjfg6kf34ntf1d8aa5zqlk04j3zy8z40ni", - "signature": "H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=" - }, { - "_id": ObjectId("60cad0767247ac0a779fb3f0"), - "zelid": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", // admin - "loginPhrase": "16125160820394ddsh5skgwv0ipodku92y0jbwvpyj17bh68lzrjlxq9", - "signature": "IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=" - }, { - "_id": ObjectId("620bbc40c04b4966674013a8"), - "zelid": "1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t", // app owner - "loginPhrase": "1644935889016mtmbo4uah32tvvwrmzg4j8qzv04ba8g8n56cevn6b", - "signature": "H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=" - }, { - "_id": ObjectId("61967125f3178f082a296100"), - "zelid": "1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM", // Flux team - "loginPhrase": "1623904359736pja76q7y68deb4264olbml6o8gyhot2yvj5oevgv9k2", - "signature": "H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=" - } - ]; - try { - await databaseLocal.collection(collectionLoggedUsers).drop(); - } catch (err) { - console.log('Collection not found.'); - } - - for (let insertUser of insertUsers) { - await serviceHelper.insertOneToDatabase(databaseLocal, collectionLoggedUsers, insertUser); - } - - - const databaseGlobal = db.db(config.database.appsglobal.database); - const collectionApps = config.database.appsglobal.collections.appsInformation; - const insertApp = { - "_id": ObjectId("6147045cd774409b374d253d"), - "name": "PolkadotNode", - "description": "Polkadot is a heterogeneous multi-chain interchange.", - "owner": "1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t", - } - - try { - await databaseGlobal.collection(collectionApps).drop(); - } catch (err) { - console.log('Collection not found.'); - } - await serviceHelper.insertOneToDatabase(databaseGlobal, collectionApps, insertApp); - - }); - - it("should return true when requested by the app owner", async () => { - const headers = { - zelidauth: { - zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', - signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=' - } - }; - const appName = 'PolkadotNode'; - const isOwnerOrHigherSession = await serviceHelper.verifyAppOwnerOrHigherSession(headers, appName); - - expect(isOwnerOrHigherSession).to.be.true; - }); - - it("should return true when requested by the admin", async () => { - const headers = { - zelidauth: { - zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', - signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' - } - }; - const appName = 'PolkadotNode'; - const isOwnerOrHigherSession = await serviceHelper.verifyAppOwnerOrHigherSession(headers, appName); - - expect(isOwnerOrHigherSession).to.be.true; - }); - - it("should return true when requested by the flux team", async () => { - const headers = { - zelidauth: { - zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', - signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' - } - }; - const appName = 'PolkadotNode'; - const isOwnerOrHigherSession = await serviceHelper.verifyAppOwnerOrHigherSession(headers, appName); - - expect(isOwnerOrHigherSession).to.be.true; - }); - - it("should return false when requested by the owner with a wrong signature", async () => { - const headers = { - zelidauth: { - zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', - signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' - } - }; - const appName = 'PolkadotNode'; - const isOwnerOrHigherSession = await serviceHelper.verifyAppOwnerOrHigherSession(headers, appName); - - expect(isOwnerOrHigherSession).to.be.false; - }); - - it("should return false when requested with empty header data", async () => { - const headers = { - zelidauth: { - zelid: '', - signature: '' - } - }; - const appName = 'PolkadotNode'; - const isOwnerOrHigherSession = await serviceHelper.verifyAppOwnerOrHigherSession(headers, appName); - - expect(isOwnerOrHigherSession).to.be.false; - }); - - it("should return false when requested with empty header ", async () => { - const headers = {}; - - const appName = 'PolkadotNode'; - const isOwnerOrHigherSession = await serviceHelper.verifyAppOwnerOrHigherSession(headers, appName); - - expect(isOwnerOrHigherSession).to.be.false; - }); - - it("should return true when requested with an empty app name", async () => { - const headers = { - zelidauth: { - zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', - signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=' - } - }; - const appName = ''; - const isOwnerOrHigherSession = await serviceHelper.verifyAppOwnerOrHigherSession(headers, appName); - - expect(isOwnerOrHigherSession).to.be.false; - }); - }); }); From 30309226398418396f3f680b138c4d90add03609 Mon Sep 17 00:00:00 2001 From: JacekAdamczyk Date: Mon, 21 Feb 2022 12:24:07 +0100 Subject: [PATCH 15/41] split helper into modules --- ZelBack/src/services/verificationHelper.js | 42 ++ .../src/services/verificationHelperUtils.js | 224 +++++++ tests/unit/verificationHelper.test.js | 94 +++ tests/unit/verificationHelperUtils.test.js | 587 ++++++++++++++++++ 4 files changed, 947 insertions(+) create mode 100644 ZelBack/src/services/verificationHelper.js create mode 100644 ZelBack/src/services/verificationHelperUtils.js create mode 100644 tests/unit/verificationHelper.test.js create mode 100644 tests/unit/verificationHelperUtils.test.js diff --git a/ZelBack/src/services/verificationHelper.js b/ZelBack/src/services/verificationHelper.js new file mode 100644 index 000000000..7ca620fcf --- /dev/null +++ b/ZelBack/src/services/verificationHelper.js @@ -0,0 +1,42 @@ +const verificationHelperUtils = require('./verificationHelperUtils'); + +/** + * Verifies a specific privilege based on request headers. + * @param {string} privilege - 'admin, 'fluxteam', 'adminandfluxteam', 'appownerabove', 'appowner', 'user' + * @param {object} req + * @param {string} appName + * + * @returns {Promise} authorized + */ + +async function verifyPrivilege(privilege, req, appName) { + let authorized; + switch (privilege) { + case 'admin': + authorized = await verificationHelperUtils.verifyAdminSession(req.headers); + break; + case 'fluxteam': + authorized = await verificationHelperUtils.verifyFluxTeamSession(req.headers); + break; + case 'adminandfluxteam': + authorized = await verificationHelperUtils.verifyAdminAndFluxTeamSession(req.headers); + break; + case 'appownerabove': + authorized = await verificationHelperUtils.verifyAppOwnerOrHigherSession(req.headers, appName); + break; + case 'appowner': + authorized = await verificationHelperUtils.verifyAppOwnerSession(req.headers, appName); + break; + case 'user': + authorized = await verificationHelperUtils.verifyUserSession(req.headers); + break; + default: + authorized = false; + break; + } + return authorized; +} + +module.exports = { + verifyPrivilege, +}; diff --git a/ZelBack/src/services/verificationHelperUtils.js b/ZelBack/src/services/verificationHelperUtils.js new file mode 100644 index 000000000..56e9b0c8d --- /dev/null +++ b/ZelBack/src/services/verificationHelperUtils.js @@ -0,0 +1,224 @@ +const config = require('config'); +const bitcoinMessage = require('bitcoinjs-message'); +const serviceHelper = require('./serviceHelper'); +const userconfig = require('../../../config/userconfig'); + +/** + * @module + * Contains utility functions to be used only by verificationHelper. + * To verify privilage use verifyPrivilege from verificationHelper module. + */ + +/** + * Verifies admin session + * @param {object} headers + * + * @returns {Promise} + */ +async function verifyAdminSession(headers) { + if (!headers || !headers.zelidauth) return false; + const auth = serviceHelper.ensureObject(headers.zelidauth); + if (!auth.zelid || !auth.signature) return false; + if (auth.zelid !== userconfig.initial.zelid) return false; + + const db = serviceHelper.databaseConnection(); + const database = db.db(config.database.local.database); + const collection = config.database.local.collections.loggedUsers; + const query = { $and: [{ signature: auth.signature }, { zelid: auth.zelid }] }; + const projection = {}; + const loggedUser = await serviceHelper.findOneInDatabase(database, collection, query, projection); + if (!loggedUser) return false; + + // check if signature corresponds to message with that zelid + let valid = false; + try { + valid = bitcoinMessage.verify(loggedUser.loginPhrase, auth.zelid, auth.signature); + } catch (error) { + return false; + } + if (valid) { + // now we know this is indeed a logged admin + return true; + } + return false; +} + +/** + * Verifies user session + * @param {object} headers + * + * @returns {Promise} + */ +async function verifyUserSession(headers) { + if (!headers || !headers.zelidauth) return false; + const auth = serviceHelper.ensureObject(headers.zelidauth); + if (!auth.zelid || !auth.signature) return false; + + const db = serviceHelper.databaseConnection(); + const database = db.db(config.database.local.database); + const collection = config.database.local.collections.loggedUsers; + const query = { $and: [{ signature: auth.signature }, { zelid: auth.zelid }] }; + const projection = {}; + const loggedUser = await serviceHelper.findOneInDatabase(database, collection, query, projection); + if (!loggedUser) return false; + + // check if signature corresponds to message with that zelid + let valid = false; + try { + valid = bitcoinMessage.verify(loggedUser.loginPhrase, auth.zelid, auth.signature); + } catch (error) { + return false; + } + // console.log(valid) + if (valid) { + // now we know this is indeed a logged admin + return true; + } + return false; +} + +/** + * Verifies flux team session + * @param {object} headers + * + * @returns {Promise} + */ +async function verifyFluxTeamSession(headers) { + if (!headers || !headers.zelidauth) return false; + const auth = serviceHelper.ensureObject(headers.zelidauth); + if (!auth.zelid || !auth.signature) return false; + if (auth.zelid !== config.fluxTeamZelId) return false; + + const db = serviceHelper.databaseConnection(); + const database = db.db(config.database.local.database); + const collection = config.database.local.collections.loggedUsers; + const query = { $and: [{ signature: auth.signature }, { zelid: auth.zelid }] }; + const projection = {}; + const result = await serviceHelper.findOneInDatabase(database, collection, query, projection); + const loggedUser = result; + if (!loggedUser) return false; + // check if signature corresponds to message with that zelid + let valid = false; + try { + valid = bitcoinMessage.verify(loggedUser.loginPhrase, auth.zelid, auth.signature); + } catch (error) { + return false; + } + if (valid) { + // now we know this is indeed a logged fluxteam + return true; + } + return false; +} + +/** + * Verifies admin or flux team session + * @param {object} headers + * + * @returns {Promise} + */ +async function verifyAdminAndFluxTeamSession(headers) { + if (!headers || !headers.zelidauth) return false; + const auth = serviceHelper.ensureObject(headers.zelidauth); + if (!auth.zelid || !auth.signature) return false; + if (auth.zelid !== config.fluxTeamZelId && auth.zelid !== userconfig.initial.zelid) return false; // admin is considered as fluxTeam + + const db = serviceHelper.databaseConnection(); + const database = db.db(config.database.local.database); + const collection = config.database.local.collections.loggedUsers; + const query = { $and: [{ signature: auth.signature }, { zelid: auth.zelid }] }; + const projection = {}; + const loggedUser = await serviceHelper.findOneInDatabase(database, collection, query, projection); + if (!loggedUser) return false; + + // check if signature corresponds to message with that zelid + let valid = false; + try { + valid = bitcoinMessage.verify(loggedUser.loginPhrase, auth.zelid, auth.signature); + } catch (error) { + return false; + } + if (valid) { + // now we know this is indeed a logged admin or fluxteam + return true; + } + return false; +} + +/** + * Verifies app owner session + * @param {object} headers + * + * @returns {Promise} + */ +async function verifyAppOwnerSession(headers, appName) { + if (!headers || !headers.zelidauth || !appName) return false; + const auth = serviceHelper.ensureObject(headers.zelidauth); + if (!auth.zelid || !auth.signature) return false; + const ownerZelID = await serviceHelper.getApplicationOwner(appName); + if (auth.zelid !== ownerZelID) return false; + + const db = serviceHelper.databaseConnection(); + const database = db.db(config.database.local.database); + const collection = config.database.local.collections.loggedUsers; + const query = { $and: [{ signature: auth.signature }, { zelid: auth.zelid }] }; + const projection = {}; + const loggedUser = await serviceHelper.findOneInDatabase(database, collection, query, projection); + if (!loggedUser) return false; + // check if signature corresponds to message with that zelid + let valid = false; + try { + valid = bitcoinMessage.verify(loggedUser.loginPhrase, auth.zelid, auth.signature); + } catch (error) { + return false; + } + if (valid) { + // now we know this is indeed a logged application owner + return true; + } + return false; +} + +/** + * Verifies app owner (or higher privilege) session + * @param {object} headers + * + * @returns {Promise} + */ +async function verifyAppOwnerOrHigherSession(headers, appName) { + if (!headers || !headers.zelidauth || !appName) return false; + const auth = serviceHelper.ensureObject(headers.zelidauth); + if (!auth.zelid || !auth.signature) return false; + const ownerZelID = await serviceHelper.getApplicationOwner(appName); + if (auth.zelid !== ownerZelID && auth.zelid !== config.fluxTeamZelId && auth.zelid !== userconfig.initial.zelid) return false; + + const db = serviceHelper.databaseConnection(); + const database = db.db(config.database.local.database); + const collection = config.database.local.collections.loggedUsers; + const query = { $and: [{ signature: auth.signature }, { zelid: auth.zelid }] }; + const projection = {}; + const loggedUser = await serviceHelper.findOneInDatabase(database, collection, query, projection); + if (!loggedUser) return false; + + // check if signature corresponds to message with that zelid + let valid = false; + try { + valid = bitcoinMessage.verify(loggedUser.loginPhrase, auth.zelid, auth.signature); + } catch (error) { + return false; + } + if (valid) { + // now we know this is indeed a logged application owner + return true; + } + return false; +} + +module.exports = { + verifyAdminAndFluxTeamSession, + verifyAdminSession, + verifyAppOwnerOrHigherSession, + verifyAppOwnerSession, + verifyFluxTeamSession, + verifyUserSession, +}; diff --git a/tests/unit/verificationHelper.test.js b/tests/unit/verificationHelper.test.js new file mode 100644 index 000000000..e49d8a960 --- /dev/null +++ b/tests/unit/verificationHelper.test.js @@ -0,0 +1,94 @@ +const chai = require('chai'); +const expect = chai.expect; +const sinon = require('sinon'); + +const verificationHelperUtils = require("../../ZelBack/src/services/verificationHelperUtils"); +const { verifyPrivilege } = require("../../ZelBack/src/services/verificationHelper"); + +//placeholders - verification functions are mocked, since they've already been tested in verificationHelperUtils.test +const req = { + headers: { + zelidauth: { + zelid: 'testing1', + signature: 'testing2' + } + } +}; +const appName = 'myTestAppName'; + + +describe('verificationHelper tests', () => { + it('should call verifyAdminSession when flag "admin" is passed', async () => { + const privilege = 'admin'; + const stub = sinon.stub(verificationHelperUtils, 'verifyAdminSession').resolves(true); + const verifyPrivilegeResult = await verifyPrivilege(privilege, req); + + sinon.assert.calledOnceWithExactly(stub, req.headers); + expect(verifyPrivilegeResult).to.be.true; + stub.reset(); + }); + + it('should call verifyFluxTeamSession when flag "fluxteam" is passed', async () => { + const privilege = 'fluxteam'; + const stub = sinon.stub(verificationHelperUtils, 'verifyFluxTeamSession').resolves(true); + const verifyPrivilegeResult = await verifyPrivilege(privilege, req); + + sinon.assert.calledOnceWithExactly(stub, req.headers); + expect(verifyPrivilegeResult).to.be.true; + stub.reset(); + }); + + it('should call verifyAdminAndFluxTeamSession when flag "adminandfluxteam" is passed', async () => { + const privilege = 'adminandfluxteam'; + const stub = sinon.stub(verificationHelperUtils, 'verifyAdminAndFluxTeamSession').resolves(true); + const verifyPrivilegeResult = await verifyPrivilege(privilege, req); + + sinon.assert.calledOnceWithExactly(stub, req.headers); + expect(verifyPrivilegeResult).to.be.true; + stub.reset(); + }); + + it('should call verifyAppOwnerOrHigherSession when flag "appownerabove" is passed', async () => { + const privilege = 'appownerabove'; + const stub = sinon.stub(verificationHelperUtils, 'verifyAppOwnerOrHigherSession').resolves(true); + const verifyPrivilegeResult = await verifyPrivilege(privilege, req, appName); + + sinon.assert.calledOnceWithExactly(stub, req.headers, appName); + expect(verifyPrivilegeResult).to.be.true; + stub.reset(); + }); + + it('should call verifyAppOwnerSession when flag "appowner" is passed', async () => { + const privilege = 'appowner'; + const stub = sinon.stub(verificationHelperUtils, 'verifyAppOwnerSession').resolves(true); + const verifyPrivilegeResult = await verifyPrivilege(privilege, req, appName); + + sinon.assert.calledOnceWithExactly(stub, req.headers, appName); + expect(verifyPrivilegeResult).to.be.true; + stub.reset(); + }); + + it('should call verifyUserSession when flag "user" is passed', async () => { + const privilege = 'user'; + const stub = sinon.stub(verificationHelperUtils, 'verifyUserSession').resolves(true); + const verifyPrivilegeResult = await verifyPrivilege(privilege, req); + + sinon.assert.calledOnceWithExactly(stub, req.headers); + expect(verifyPrivilegeResult).to.be.true; + stub.reset(); + }); + + it('should return false when a wrong flag - "test" is passed', async () => { + const privilege = 'test'; + const verifyPrivilegeResult = await verifyPrivilege(privilege, req); + + expect(verifyPrivilegeResult).to.be.false; + }); + + it('should return false when a wrong flag - true is passed', async () => { + const privilege = true; + const verifyPrivilegeResult = await verifyPrivilege(privilege, req); + + expect(verifyPrivilegeResult).to.be.false; + }); +}); \ No newline at end of file diff --git a/tests/unit/verificationHelperUtils.test.js b/tests/unit/verificationHelperUtils.test.js new file mode 100644 index 000000000..b19572ced --- /dev/null +++ b/tests/unit/verificationHelperUtils.test.js @@ -0,0 +1,587 @@ +const chai = require('chai'); +const config = require('config'); +const { ObjectId } = require('mongodb'); +const proxyquire = require('proxyquire'); +const expect = chai.expect; +let serviceHelper = require("../../ZelBack/src/services/serviceHelper"); + +const adminConfig = { + initial: { + ipaddress: '83.51.212.243', + zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + testnet: true + } +} +const verificationHelperUtils = proxyquire('../../ZelBack/src/services/verificationHelperUtils', + { '../../../config/userconfig': adminConfig }); + +const insertUsers = [{ + "_id": ObjectId("6108fbb9f04dfe1ef624b819"), + "zelid": "1hjy4bCYBJr4mny4zCE85J94RXa8W6q37", // regular user + "loginPhrase": "162797868130153vt9r89dzjjjfg6kf34ntf1d8aa5zqlk04j3zy8z40ni", + "signature": "H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=" +}, { + "_id": ObjectId("60cad0767247ac0a779fb3f0"), + "zelid": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", // admin + "loginPhrase": "16125160820394ddsh5skgwv0ipodku92y0jbwvpyj17bh68lzrjlxq9", + "signature": "IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=" +}, { + "_id": ObjectId("620bbc40c04b4966674013a8"), + "zelid": "1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t", // app owner + "loginPhrase": "1644935889016mtmbo4uah32tvvwrmzg4j8qzv04ba8g8n56cevn6b", + "signature": "H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=" +}, { + "_id": ObjectId("61967125f3178f082a296100"), + "zelid": "1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM", // Flux team + "loginPhrase": "1623904359736pja76q7y68deb4264olbml6o8gyhot2yvj5oevgv9k2", + "signature": "H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=" +} +]; + +const insertApp = { + "_id": ObjectId("6147045cd774409b374d253d"), + "name": "PolkadotNode", + "description": "Polkadot is a heterogeneous multi-chain interchange.", + "owner": "1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t", +} + +describe('verificationHelperUtils tests', () => { + describe('verifyUserSession tests', () => { + beforeEach(async () => { + await serviceHelper.initiateDB(); + const db = serviceHelper.databaseConnection(); + const database = db.db(config.database.local.database); + const collection = config.database.local.collections.loggedUsers; + + try { + await database.collection(collection).drop(); + } catch (err) { + console.log('Collection not found.'); + } + + + await database.collection(collection).insertMany(insertUsers); + }); + + it("should return true when requested by a logged user", async () => { + const headers = { + zelidauth: { + zelid: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', + signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=' + } + } + + const isLoggedUser = await verificationHelperUtils.verifyUserSession(headers); + + expect(isLoggedUser).to.be.true; + }); + + it("should return false if called with a wrong zelid", async () => { + const headers = { + zelidauth: { + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBu9t', + signature: 'IMDMG1GuDasjPMkrGaRQhkLpFO0saBV+v+N6h3wP6/QlF3J9ymLAPZy7DCBd/RnOSzUxmTHruenVeR7LghzRnHA=' + } + } + + const isLoggedUser = await verificationHelperUtils.verifyUserSession(headers); + + expect(isLoggedUser).to.be.false; + }); + + it("should return false if called with a wrong signature", async () => { + const headers = { + zelidauth: { + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', + signature: 'IMDMG1GuDasjPMkrGaRQhkLpFO0saBZ+v+N6h3wP6/QlF3J9ymLAPZy7DCBd/RnOSzUxmTHruenVeR7LghzRnHA=' + } + } + + const isLoggedUser = await verificationHelperUtils.verifyUserSession(headers); + + expect(isLoggedUser).to.be.false; + }); + it("should return false if called with no header", async () => { + const isLoggedUser = await verificationHelperUtils.verifyUserSession(); + + expect(isLoggedUser).to.be.false; + }); + + it("should return false if called with empty data", async () => { + const headers = { + zelidauth: { + zelid: '', + signature: '' + } + } + + const isLoggedUser = await verificationHelperUtils.verifyUserSession(headers); + + expect(isLoggedUser).to.be.false; + }); + }); + + describe('verifyFluxTeamSession tests', () => { + beforeEach(async () => { + await serviceHelper.initiateDB(); + const db = serviceHelper.databaseConnection(); + const database = db.db(config.database.local.database); + const collection = config.database.local.collections.loggedUsers; + + try { + await database.collection(collection).drop(); + } catch (err) { + console.log('Collection not found.'); + } + + await database.collection(collection).insertMany(insertUsers); + }); + + it("should return true when requested by the flux team", async () => { + const headers = { + zelidauth: { + zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', + signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' + } + }; + + const isFluxTeamSession = await verificationHelperUtils.verifyFluxTeamSession(headers); + + expect(isFluxTeamSession).to.be.true; + }); + + it("should return false when zelid is not the flux team", async () => { + const headers = { + zelidauth: { + zelid: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', + signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=' + } + }; + + const isFluxTeamSession = await verificationHelperUtils.verifyFluxTeamSession(headers); + + expect(isFluxTeamSession).to.be.false; + }); + + + it("should return false when signature is invalid", async () => { + const headers = { + zelidauth: { + zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', + signature: 'N4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' + } + }; + + const isFluxTeamSession = await verificationHelperUtils.verifyFluxTeamSession(headers); + + expect(isFluxTeamSession).to.be.false; + }); + + it("should return false when zelid is invalid", async () => { + const headers = { + zelidauth: { + zelid: '1NH9BP1z5Rp3HSf5ef6NpUbE8JcyLRruAM', + signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' + } + }; + + const isFluxTeamSession = await verificationHelperUtils.verifyFluxTeamSession(headers); + + expect(isFluxTeamSession).to.be.false; + }); + + it("should return false when data is empty", async () => { + const headers = { + zelidauth: { + zelid: '', + signature: '' + } + }; + + const isFluxTeamSession = await verificationHelperUtils.verifyFluxTeamSession(headers); + + expect(isFluxTeamSession).to.be.false; + }); + + it("should return false when data are true bools", async () => { + const headers = { + zelidauth: { + zelid: true, + signature: true + } + }; + + const isFluxTeamSession = await verificationHelperUtils.verifyFluxTeamSession(headers); + + expect(isFluxTeamSession).to.be.false; + }); + + it("should return false when header is empty", async () => { + const headers = {}; + + const isFluxTeamSession = await verificationHelperUtils.verifyFluxTeamSession(headers); + + expect(isFluxTeamSession).to.be.false; + }); + + it("should return false when no header is passed", async () => { + const isFluxTeamSession = await verificationHelperUtils.verifyFluxTeamSession(); + + expect(isFluxTeamSession).to.be.false; + }); + }); + + describe('verifyAdminAndFluxTeamSession tests', () => { + beforeEach(async () => { + await serviceHelper.initiateDB(); + const db = serviceHelper.databaseConnection(); + const database = db.db(config.database.local.database); + const collection = config.database.local.collections.loggedUsers; + + try { + await database.collection(collection).drop(); + } catch (err) { + console.log('Collection not found.'); + } + + await database.collection(collection).insertMany(insertUsers); + }); + + it("should return true when requested by the flux team", async () => { + const headers = { + zelidauth: { + zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', + signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' + } + }; + + const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(headers); + + expect(isAdminOrFluxTeam).to.be.true; + }); + + it("should return true when requested by the admin", async () => { + const headers = { + zelidauth: { + zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' + } + }; + + const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(headers); + + expect(isAdminOrFluxTeam).to.be.true; + }); + + it("should return false when zelid is not the flux team", async () => { + const headers = { + zelidauth: { + zelid: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', + signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=' + } + }; + + const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(headers); + + expect(isAdminOrFluxTeam).to.be.false; + }); + + + it("should return false when signature is invalid", async () => { + const headers = { + zelidauth: { + zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', + signature: 'N4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' + } + }; + + const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(headers); + + expect(isAdminOrFluxTeam).to.be.false; + }); + + it("should return false when zelid is invalid", async () => { + const headers = { + zelidauth: { + zelid: '1NH9BP1z5Rp3HSf5ef6NpUbE8JcyLRruAM', + signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' + } + }; + + const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(headers); + + expect(isAdminOrFluxTeam).to.be.false; + }); + + it("should return false when data is empty", async () => { + const headers = { + zelidauth: { + zelid: '', + signature: '' + } + }; + + const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(headers); + + expect(isAdminOrFluxTeam).to.be.false; + }); + + it("should return false when data are true bools", async () => { + const headers = { + zelidauth: { + zelid: true, + signature: true + } + }; + + const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(headers); + + expect(isAdminOrFluxTeam).to.be.false; + }); + + it("should return false when header is empty", async () => { + const headers = {}; + + const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(headers); + + expect(isAdminOrFluxTeam).to.be.false; + }); + + it("should return false when no header is passed", async () => { + const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(); + + expect(isAdminOrFluxTeam).to.be.false; + }); + }); + + describe('verifyAppOwnerSession tests', () => { + beforeEach(async () => { + await serviceHelper.initiateDB(); + const db = serviceHelper.databaseConnection(); + const databaseLocal = db.db(config.database.local.database); + const collectionLoggedUsers = config.database.local.collections.loggedUsers; + + try { + await databaseLocal.collection(collectionLoggedUsers).drop(); + } catch (err) { + console.log('Collection not found.'); + } + + await databaseLocal.collection(collectionLoggedUsers).insertMany(insertUsers); + + + const databaseGlobal = db.db(config.database.appsglobal.database); + const collectionApps = config.database.appsglobal.collections.appsInformation; + + try { + await databaseGlobal.collection(collectionApps).drop(); + } catch (err) { + console.log('Collection not found.'); + } + await serviceHelper.insertOneToDatabase(databaseGlobal, collectionApps, insertApp); + + }); + + it("should return true when requested by the app owner", async () => { + const headers = { + zelidauth: { + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', + signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=' + } + }; + const appName = 'PolkadotNode'; + const isOwnerSession = await verificationHelperUtils.verifyAppOwnerSession(headers, appName); + + expect(isOwnerSession).to.be.true; + }); + + it("should return false when requested by the admin", async () => { + const headers = { + zelidauth: { + zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' + } + }; + const appName = 'PolkadotNode'; + const isOwnerSession = await verificationHelperUtils.verifyAppOwnerSession(headers, appName); + + expect(isOwnerSession).to.be.false; + }); + + it("should return false when requested by the owner with a wrong signature", async () => { + const headers = { + zelidauth: { + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' + } + }; + const appName = 'PolkadotNode'; + const isOwnerSession = await verificationHelperUtils.verifyAppOwnerSession(headers, appName); + + expect(isOwnerSession).to.be.false; + }); + + it("should return false when requested with empty header data", async () => { + const headers = { + zelidauth: { + zelid: '', + signature: '' + } + }; + const appName = 'PolkadotNode'; + const isOwnerSession = await verificationHelperUtils.verifyAppOwnerSession(headers, appName); + + expect(isOwnerSession).to.be.false; + }); + + it("should return false when requested with empty header ", async () => { + const headers = {}; + + const appName = 'PolkadotNode'; + const isOwnerSession = await verificationHelperUtils.verifyAppOwnerSession(headers, appName); + + expect(isOwnerSession).to.be.false; + }); + + it("should return true when requested with an empty app name", async () => { + const headers = { + zelidauth: { + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', + signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=' + } + }; + const appName = ''; + const isOwnerSession = await verificationHelperUtils.verifyAppOwnerSession(headers, appName); + + expect(isOwnerSession).to.be.false; + }); + }); + + describe('verifyAppOwnerSessionOrHigher tests', () => { + beforeEach(async () => { + await serviceHelper.initiateDB(); + const db = serviceHelper.databaseConnection(); + const databaseLocal = db.db(config.database.local.database); + const collectionLoggedUsers = config.database.local.collections.loggedUsers; + + try { + await databaseLocal.collection(collectionLoggedUsers).drop(); + } catch (err) { + console.log('Collection not found.'); + } + + await databaseLocal.collection(collectionLoggedUsers).insertMany(insertUsers); + + const databaseGlobal = db.db(config.database.appsglobal.database); + const collectionApps = config.database.appsglobal.collections.appsInformation; + + try { + await databaseGlobal.collection(collectionApps).drop(); + } catch (err) { + console.log('Collection not found.'); + } + await serviceHelper.insertOneToDatabase(databaseGlobal, collectionApps, insertApp); + + }); + + it("should return true when requested by the app owner", async () => { + const headers = { + zelidauth: { + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', + signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=' + } + }; + const appName = 'PolkadotNode'; + const isOwnerOrHigherSession = await verificationHelperUtils.verifyAppOwnerOrHigherSession(headers, appName); + + expect(isOwnerOrHigherSession).to.be.true; + }); + + it("should return true when requested by the admin", async () => { + const headers = { + zelidauth: { + zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' + } + }; + const appName = 'PolkadotNode'; + const isOwnerOrHigherSession = await verificationHelperUtils.verifyAppOwnerOrHigherSession(headers, appName); + + expect(isOwnerOrHigherSession).to.be.true; + }); + + it("should return true when requested by the flux team", async () => { + const headers = { + zelidauth: { + zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', + signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' + } + }; + const appName = 'PolkadotNode'; + const isOwnerOrHigherSession = await verificationHelperUtils.verifyAppOwnerOrHigherSession(headers, appName); + + expect(isOwnerOrHigherSession).to.be.true; + }); + + it("should return false when requested by a regular user", async () => { + const headers = { + zelidauth: { + zelid: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', + signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=' + } + }; + const appName = 'PolkadotNode'; + const isOwnerOrHigherSession = await verificationHelperUtils.verifyAppOwnerOrHigherSession(headers, appName); + + expect(isOwnerOrHigherSession).to.be.false; + }); + + it("should return false when requested by the owner with a wrong signature", async () => { + const headers = { + zelidauth: { + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' + } + }; + const appName = 'PolkadotNode'; + const isOwnerOrHigherSession = await verificationHelperUtils.verifyAppOwnerOrHigherSession(headers, appName); + + expect(isOwnerOrHigherSession).to.be.false; + }); + + it("should return false when requested with empty header data", async () => { + const headers = { + zelidauth: { + zelid: '', + signature: '' + } + }; + const appName = 'PolkadotNode'; + const isOwnerOrHigherSession = await verificationHelperUtils.verifyAppOwnerOrHigherSession(headers, appName); + + expect(isOwnerOrHigherSession).to.be.false; + }); + + it("should return false when requested with empty header ", async () => { + const headers = {}; + + const appName = 'PolkadotNode'; + const isOwnerOrHigherSession = await verificationHelperUtils.verifyAppOwnerOrHigherSession(headers, appName); + + expect(isOwnerOrHigherSession).to.be.false; + }); + + it("should return true when requested with an empty app name", async () => { + const headers = { + zelidauth: { + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', + signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=' + } + }; + const appName = ''; + const isOwnerOrHigherSession = await verificationHelperUtils.verifyAppOwnerOrHigherSession(headers, appName); + + expect(isOwnerOrHigherSession).to.be.false; + }); + }); +}); From d6b003f0148fb824742bd6f7ccd3fd85e37e7c04 Mon Sep 17 00:00:00 2001 From: Tadeas Kmenta Date: Mon, 21 Feb 2022 18:43:00 +0700 Subject: [PATCH 16/41] block processing for insight nodes --- ZelBack/src/services/explorerService.js | 75 +++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 5 deletions(-) diff --git a/ZelBack/src/services/explorerService.js b/ZelBack/src/services/explorerService.js index 4dba84935..d25b7334e 100644 --- a/ZelBack/src/services/explorerService.js +++ b/ZelBack/src/services/explorerService.js @@ -221,8 +221,7 @@ async function processBlockTransactions(txs, height) { return transactions; } -async function getVerboseBlock(heightOrHash) { - const verbosity = 2; +async function getVerboseBlock(heightOrHash, verbosity = 2) { const req = { params: { hashheight: heightOrHash, @@ -251,6 +250,67 @@ function decodeMessage(asm) { return message; } +async function processInsight(blockDataVerbose, database) { + // get Block Deltas information + const txs = blockDataVerbose.tx; + // go through each transaction in deltas + // eslint-disable-next-line no-restricted-syntax + for (const tx in txs) { + if (tx.version < 5 && tx.version > 0) { + let message = ''; + let isFluxAppMessageValue = 0; + tx.vout.forEach((receiver) => { + if (receiver.scriptPubKey.addresses) { // count for messages + if (receiver.scriptPubKey.addresses[0] === config.fluxapps.address) { + // it is an app message. Get Satoshi amount + isFluxAppMessageValue += receiver.valueSat; + } + } + if (receiver.scriptPubKey.asm) { + message = decodeMessage(receiver.scriptPubKey.asm); + } + }); + const intervals = config.fluxapps.price.filter((i) => i.height <= blockDataVerbose.height); + const priceSpecifications = intervals[intervals.length - 1]; // filter does not change order + // MAY contain App transaction. Store it. + if (isFluxAppMessageValue >= (priceSpecifications.minPrice * 1e8) && message.length === 64 && blockDataVerbose.height >= config.fluxapps.epochstart) { // min of 1 flux had to be paid for us bothering checking + const appTxRecord = { + txid: tx.txid, height: blockDataVerbose.height, hash: message, value: isFluxAppMessageValue, message: false, // message is boolean saying if we already have it stored as permanent message + }; + // Unique hash - If we already have a hash of this app in our database, do not insert it! + try { + // 5501c7dd6516c3fc2e68dee8d4fdd20d92f57f8cfcdc7b4fcbad46499e43ed6f + const querySearch = { + hash: message, + }; + const projectionSearch = { + projection: { + _id: 0, + txid: 1, + hash: 1, + height: 1, + value: 1, + message: 1, + }, + }; + // eslint-disable-next-line no-await-in-loop + const result = await serviceHelper.findOneInDatabase(database, appsHashesCollection, querySearch, projectionSearch); // this search can be later removed if nodes rescan apps and reconstruct the index for unique + if (!result) { + // eslint-disable-next-line no-await-in-loop + await serviceHelper.insertOneToDatabase(database, appsHashesCollection, appTxRecord); + appsService.checkAndRequestApp(message, tx.txid, blockDataVerbose.height, isFluxAppMessageValue); + } else { + throw new Error(`Found an existing hash app ${serviceHelper.ensureString(result)}`); + } + } catch (error) { + log.error(`Hash ${message} already exists. Not adding at height ${blockDataVerbose.height}`); + log.error(error); + } + } + } + } +} + async function processStandard(blockDataVerbose, database) { // get Block transactions information const transactions = await processBlockTransactions(blockDataVerbose.tx, blockDataVerbose.height); @@ -366,13 +426,14 @@ async function processBlock(blockHeight, isInsightExplorer) { const db = serviceHelper.databaseConnection(); const database = db.db(config.database.daemon.database); // get Block information - const blockDataVerbose = await getVerboseBlock(blockHeight); + const verbosity = 2; + const blockDataVerbose = await getVerboseBlock(blockHeight, verbosity); if (blockDataVerbose.height % 50 === 0) { console.log(blockDataVerbose.height); } if (isInsightExplorer) { - // we essentially only care about - await processStandard(blockDataVerbose, database); // TODO + // only process Flux transactions + await processInsight(blockDataVerbose, database); } else { await processStandard(blockDataVerbose, database); } @@ -673,6 +734,10 @@ async function initiateBlockProcessor(restoreDatabase, deepRestore, reindexOrRes } isInInitiationOfBP = false; const isInsightExplorer = daemonService.isInsightExplorer(); + if (isInsightExplorer) { + // if node is insight explorer based, we are only processing flux app messages + scannedBlockHeight = config.fluxapps.epochstart - 1; + } processBlock(scannedBlockHeight + 1, isInsightExplorer); } else { isInInitiationOfBP = false; From 5083b468fc221925423cb6da25e7ec6bb7af9ad1 Mon Sep 17 00:00:00 2001 From: Tadeas Kmenta Date: Mon, 21 Feb 2022 19:37:20 +0700 Subject: [PATCH 17/41] address index for single address correct new rpc post calls --- ZelBack/src/routes.js | 15 +++ ZelBack/src/services/daemonService.js | 133 ++++++++++++++++++++++---- 2 files changed, 127 insertions(+), 21 deletions(-) diff --git a/ZelBack/src/routes.js b/ZelBack/src/routes.js index 45b13779e..d991e84cd 100644 --- a/ZelBack/src/routes.js +++ b/ZelBack/src/routes.js @@ -595,6 +595,21 @@ module.exports = (app, expressWs) => { app.get('/daemon/zcsamplejoinsplit', (req, res) => { daemonService.zcSampleJoinSplit(req, res); }); + app.get('/daemon/getaddresstxids/:address?/:start?/:end?', (req, res) => { + daemonService.getSingleAddresssTxids(req, res); + }); + app.get('/daemon/getaddressbalance/:address?', (req, res) => { + daemonService.getSingleAddressBalance(req, res); + }); + app.get('/daemon/getaddressdeltas/:address?/:start?/:end?/:chaininfo?', (req, res) => { + daemonService.getSingleAddressDeltas(req, res); + }); + app.get('/daemon/getaddressutxos/:address?/:chaininfo?', (req, res) => { + daemonService.getSingleAddressUtxos(req, res); + }); + app.get('/daemon/getaddressmempool/:address?', (req, res) => { + daemonService.getSingleAddressMempool(req, res); + }); app.get('/id/loggedusers', (req, res) => { idService.loggedUsers(req, res); diff --git a/ZelBack/src/services/daemonService.js b/ZelBack/src/services/daemonService.js index 81c7cc85d..b3db5036f 100644 --- a/ZelBack/src/services/daemonService.js +++ b/ZelBack/src/services/daemonService.js @@ -548,8 +548,7 @@ async function getBlockHashes(req, res) { options.logicalTimes = serviceHelper.ensureBoolean(logicalTimes); } if (options.noOrphans !== undefined || options.logicalTimes !== undefined) { - const optionsString = serviceHelper.ensureString(options); - rpcparameters.push(optionsString); + rpcparameters.push(options); } response = await executeCall(rpccall, rpcparameters); @@ -570,7 +569,7 @@ async function getBlockHashesPost(req, res) { const rpcparameters = [high, low]; if (options) { - rpcparameters.push(serviceHelper.ensureString(options)); + rpcparameters.push(options); } response = await executeCall(rpccall, rpcparameters); @@ -733,7 +732,7 @@ async function getSpentInfo(req, res) { txid: serviceHelper.ensureString(txid), index: serviceHelper.ensureNumber(index), }; - const rpcparameters = [serviceHelper.ensureString(options)]; + const rpcparameters = [options]; response = await executeCall(rpccall, rpcparameters); @@ -752,10 +751,9 @@ async function getSpentInfoPost(req, res) { txid, index, }; - const optionsString = serviceHelper.ensureString(options); const rpccall = 'getspentinfo'; - const rpcparameters = [optionsString]; + const rpcparameters = [options]; response = await executeCall(rpccall, rpcparameters); @@ -779,10 +777,8 @@ async function getAddressTxids(req, res) { end, }; - const optionsString = serviceHelper.ensureString(options); - const rpccall = 'getaddresstxids'; - const rpcparameters = [optionsString]; + const rpcparameters = [options]; response = await executeCall(rpccall, rpcparameters); @@ -790,6 +786,28 @@ async function getAddressTxids(req, res) { }); } +async function getSingleAddresssTxids(req, res) { + let { address } = req.params; + address = address || req.query.address; + let { start } = req.params; + start = start || req.query.start; + let { end } = req.params; + end = end || req.query.end; + + const options = { + addresses: [address], + start, + end, + }; + + const rpccall = 'getaddressdeltas'; + const rpcparameters = [options]; + + response = await executeCall(rpccall, rpcparameters); + + return res ? res.json(response) : response; +} + async function getAddressBalance(req, res) { let body = ''; req.on('data', (data) => { @@ -803,10 +821,8 @@ async function getAddressBalance(req, res) { addresses, }; - const optionsString = serviceHelper.ensureString(options); - const rpccall = 'getaddressbalance'; - const rpcparameters = [optionsString]; + const rpcparameters = [options]; response = await executeCall(rpccall, rpcparameters); @@ -814,6 +830,22 @@ async function getAddressBalance(req, res) { }); } +async function getSingleAddressBalance(req, res) { + let { address } = req.params; + address = address || req.query.address; + + const options = { + addresses: [address], + }; + + const rpccall = 'getaddressbalance'; + const rpcparameters = [options]; + + response = await executeCall(rpccall, rpcparameters); + + return res ? res.json(response) : response; +} + async function getAddressDeltas(req, res) { let body = ''; req.on('data', (data) => { @@ -832,10 +864,8 @@ async function getAddressDeltas(req, res) { chainInfo, }; - const optionsString = serviceHelper.ensureString(options); - const rpccall = 'getaddressdeltas'; - const rpcparameters = [optionsString]; + const rpcparameters = [options]; response = await executeCall(rpccall, rpcparameters); @@ -843,6 +873,31 @@ async function getAddressDeltas(req, res) { }); } +async function getSingleAddressDeltas(req, res) { + let { address } = req.params; + address = address || req.query.address; + let { start } = req.params; + start = start || req.query.start; + let { end } = req.params; + end = end || req.query.end; + let { chaininfo } = req.params; + chaininfo = chaininfo || req.query.chaininfo; + + const options = { + addresses: [address], + start, + end, + chainInfo: chaininfo, + }; + + const rpccall = 'getaddressdeltas'; + const rpcparameters = [options]; + + response = await executeCall(rpccall, rpcparameters); + + return res ? res.json(response) : response; +} + async function getAddressUtxos(req, res) { let body = ''; req.on('data', (data) => { @@ -859,10 +914,8 @@ async function getAddressUtxos(req, res) { chainInfo, }; - const optionsString = serviceHelper.ensureString(options); - const rpccall = 'getaddressutxos'; - const rpcparameters = [optionsString]; + const rpcparameters = [options]; response = await executeCall(rpccall, rpcparameters); @@ -870,6 +923,25 @@ async function getAddressUtxos(req, res) { }); } +async function getSingleAddressUtxos(req, res) { + let { address } = req.params; + address = address || req.query.address; + let { chaininfo } = req.params; + chaininfo = chaininfo || req.query.chaininfo; + + const options = { + addresses: [address], + chainInfo: chaininfo, + }; + + const rpccall = 'getaddressutxos'; + const rpcparameters = [options]; + + response = await executeCall(rpccall, rpcparameters); + + return res ? res.json(response) : response; +} + async function getAddressMempool(req, res) { let body = ''; req.on('data', (data) => { @@ -885,10 +957,8 @@ async function getAddressMempool(req, res) { addresses, }; - const optionsString = serviceHelper.ensureString(options); - const rpccall = 'getaddressmempool'; - const rpcparameters = [optionsString]; + const rpcparameters = [options]; response = await executeCall(rpccall, rpcparameters); @@ -896,6 +966,22 @@ async function getAddressMempool(req, res) { }); } +async function getSingleAddressMempool(req, res) { + let { address } = req.params; + address = address || req.query.address; + + const options = { + addresses: [address], + }; + + const rpccall = 'getaddressmempool'; + const rpcparameters = [options]; + + response = await executeCall(rpccall, rpcparameters); + + return res ? res.json(response) : response; +} + // == Mining == async function getBlockSubsidy(req, res) { let { height } = req.params; @@ -3093,10 +3179,15 @@ module.exports = { // == AddressIndex == getAddressTxids, // insight explorer + getSingleAddresssTxids, getAddressBalance, // insight explorer + getSingleAddressBalance, getAddressDeltas, // insight explorer + getSingleAddressDeltas, getAddressUtxos, // insight explorer + getSingleAddressUtxos, getAddressMempool, // insight explorer + getSingleAddressMempool, // == Disclosure == // intentionally left out as of experimental feature From f3872f8412c4fc8cb6b3e5f0bdcf59c93f2310bc Mon Sep 17 00:00:00 2001 From: Tadeas Kmenta Date: Mon, 21 Feb 2022 20:09:49 +0700 Subject: [PATCH 18/41] insight explorer processing, explorer --- ZelBack/src/services/daemonService.js | 2 +- ZelBack/src/services/explorerService.js | 155 ++++++++++++++++-------- 2 files changed, 106 insertions(+), 51 deletions(-) diff --git a/ZelBack/src/services/daemonService.js b/ZelBack/src/services/daemonService.js index b3db5036f..15661d534 100644 --- a/ZelBack/src/services/daemonService.js +++ b/ZelBack/src/services/daemonService.js @@ -800,7 +800,7 @@ async function getSingleAddresssTxids(req, res) { end, }; - const rpccall = 'getaddressdeltas'; + const rpccall = 'getaddresstxids'; const rpcparameters = [options]; response = await executeCall(rpccall, rpcparameters); diff --git a/ZelBack/src/services/explorerService.js b/ZelBack/src/services/explorerService.js index d25b7334e..1e6c497f4 100644 --- a/ZelBack/src/services/explorerService.js +++ b/ZelBack/src/services/explorerService.js @@ -736,7 +736,9 @@ async function initiateBlockProcessor(restoreDatabase, deepRestore, reindexOrRes const isInsightExplorer = daemonService.isInsightExplorer(); if (isInsightExplorer) { // if node is insight explorer based, we are only processing flux app messages - scannedBlockHeight = config.fluxapps.epochstart - 1; + if (scannedBlockHeight < config.fluxapps.epochstart - 1) { + scannedBlockHeight = config.fluxapps.epochstart - 1; + } } processBlock(scannedBlockHeight + 1, isInsightExplorer); } else { @@ -906,24 +908,51 @@ async function getAddressUtxos(req, res) { if (!address) { throw new Error('No address provided'); } - const dbopen = serviceHelper.databaseConnection(); - const database = dbopen.db(config.database.daemon.database); - const query = { address }; - const projection = { - projection: { - _id: 0, - txid: 1, - vout: 1, - height: 1, - address: 1, - satoshis: 1, - scriptPubKey: 1, - coinbase: 1, - }, - }; - const results = await serviceHelper.findInDatabase(database, utxoIndexCollection, query, projection); - const resMessage = serviceHelper.createDataMessage(results); - res.json(resMessage); + const isInsightExplorer = daemonService.isInsightExplorer(); + if (isInsightExplorer) { + const daemonRequest = { + params: { + address, + }, + }; + const insightResult = daemonService.getSingleAddressUtxos(daemonRequest); + const syncStatus = daemonService.isDaemonSynced(); + const curHeight = syncStatus.data.height; + const utxos = []; + insightResult.data.forEach((utxo) => { + const adjustedUtxo = { + address: utxo.address, + txid: utxo.txid, + vout: utxo.outputIndex, + height: utxo.height, + satoshis: utxo.satoshis, + scriptPubKey: utxo.script, + confirmations: curHeight - utxo.height, // HERE DIFFERS, insight more compatible with zelcore as coinbase is spendable after 100 + }; + utxos.push(adjustedUtxo); + }); + const resMessage = serviceHelper.createDataMessage(utxos); + res.json(resMessage); + } else { + const dbopen = serviceHelper.databaseConnection(); + const database = dbopen.db(config.database.daemon.database); + const query = { address }; + const projection = { + projection: { + _id: 0, + txid: 1, + vout: 1, + height: 1, + address: 1, + satoshis: 1, + scriptPubKey: 1, + coinbase: 1, // HERE DIFFERS + }, + }; + const results = await serviceHelper.findInDatabase(database, utxoIndexCollection, query, projection); + const resMessage = serviceHelper.createDataMessage(results); + res.json(resMessage); + } } catch (error) { log.error(error); const errMessage = serviceHelper.createErrorMessage(error.message, error.name, error.code); @@ -1026,15 +1055,28 @@ async function getAddressTransactions(req, res) { if (!address) { throw new Error('No address provided'); } - const dbopen = serviceHelper.databaseConnection(); - const database = dbopen.db(config.database.daemon.database); - const query = { address }; - const distinct = 'transactions'; - const results = await serviceHelper.distinctDatabase(database, addressTransactionIndexCollection, distinct, query); - // TODO FIX documentation. UPDATE for an amount of last txs needed. - // now we have array of transactions [{txid, height}, {}...] - const resMessage = serviceHelper.createDataMessage(results); - res.json(resMessage); + const isInsightExplorer = daemonService.isInsightExplorer(); + if (isInsightExplorer) { + const daemonRequest = { + params: { + address, + }, + }; + const insightResult = daemonService.getSingleAddresssTxids(daemonRequest); + const txids = insightResult.data.reverse(); + const resMessage = serviceHelper.createDataMessage(txids); + res.json(resMessage); + } else { + const dbopen = serviceHelper.databaseConnection(); + const database = dbopen.db(config.database.daemon.database); + const query = { address }; + const distinct = 'transactions'; + const results = await serviceHelper.distinctDatabase(database, addressTransactionIndexCollection, distinct, query); + // TODO FIX documentation. UPDATE for an amount of last txs needed. + // now we have array of transactions [{txid, height}, {}...] + const resMessage = serviceHelper.createDataMessage(results); + res.json(resMessage); + } } catch (error) { log.error(error); const errMessage = serviceHelper.createErrorMessage(error.message, error.name, error.code); @@ -1234,28 +1276,41 @@ async function getAddressBalance(req, res) { if (!address) { throw new Error('No address provided'); } - const dbopen = serviceHelper.databaseConnection(); - const database = dbopen.db(config.database.daemon.database); - const query = { address }; - const projection = { - projection: { - _id: 0, - // txid: 1, - // vout: 1, - // height: 1, - // address: 1, - satoshis: 1, - // scriptPubKey: 1, - // coinbase: 1, - }, - }; - const results = await serviceHelper.findInDatabase(database, utxoIndexCollection, query, projection); - let balance = 0; - results.forEach((utxo) => { - balance += utxo.satoshis; - }); - const resMessage = serviceHelper.createDataMessage(balance); - res.json(resMessage); + const isInsightExplorer = daemonService.isInsightExplorer(); + if (isInsightExplorer) { + const daemonRequest = { + params: { + address, + }, + }; + const insightResult = daemonService.getSingleAddressBalance(daemonRequest); + const { balance } = insightResult.data; + const resMessage = serviceHelper.createDataMessage(balance); + res.json(resMessage); + } else { + const dbopen = serviceHelper.databaseConnection(); + const database = dbopen.db(config.database.daemon.database); + const query = { address }; + const projection = { + projection: { + _id: 0, + // txid: 1, + // vout: 1, + // height: 1, + // address: 1, + satoshis: 1, + // scriptPubKey: 1, + // coinbase: 1, + }, + }; + const results = await serviceHelper.findInDatabase(database, utxoIndexCollection, query, projection); + let balance = 0; + results.forEach((utxo) => { + balance += utxo.satoshis; + }); + const resMessage = serviceHelper.createDataMessage(balance); + res.json(resMessage); + } } catch (error) { log.error(error); const errMessage = serviceHelper.createErrorMessage(error.message, error.name, error.code); From 177f13640e9fb25c428cd99f3dd2eb1c98004e2a Mon Sep 17 00:00:00 2001 From: Tadeas Kmenta Date: Mon, 21 Feb 2022 20:13:56 +0700 Subject: [PATCH 19/41] fix missing query object --- ZelBack/src/services/explorerService.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ZelBack/src/services/explorerService.js b/ZelBack/src/services/explorerService.js index 1e6c497f4..57669e2a1 100644 --- a/ZelBack/src/services/explorerService.js +++ b/ZelBack/src/services/explorerService.js @@ -914,6 +914,7 @@ async function getAddressUtxos(req, res) { params: { address, }, + query: {}, }; const insightResult = daemonService.getSingleAddressUtxos(daemonRequest); const syncStatus = daemonService.isDaemonSynced(); @@ -1061,6 +1062,7 @@ async function getAddressTransactions(req, res) { params: { address, }, + query: {}, }; const insightResult = daemonService.getSingleAddresssTxids(daemonRequest); const txids = insightResult.data.reverse(); @@ -1282,6 +1284,7 @@ async function getAddressBalance(req, res) { params: { address, }, + query: {}, }; const insightResult = daemonService.getSingleAddressBalance(daemonRequest); const { balance } = insightResult.data; From 71f75e4b80f4523dc85f92242762fa4e9f30c192 Mon Sep 17 00:00:00 2001 From: Tadeas Kmenta Date: Mon, 21 Feb 2022 20:16:52 +0700 Subject: [PATCH 20/41] fix missing await --- ZelBack/src/services/explorerService.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ZelBack/src/services/explorerService.js b/ZelBack/src/services/explorerService.js index 57669e2a1..673ccd235 100644 --- a/ZelBack/src/services/explorerService.js +++ b/ZelBack/src/services/explorerService.js @@ -916,7 +916,7 @@ async function getAddressUtxos(req, res) { }, query: {}, }; - const insightResult = daemonService.getSingleAddressUtxos(daemonRequest); + const insightResult = await daemonService.getSingleAddressUtxos(daemonRequest); const syncStatus = daemonService.isDaemonSynced(); const curHeight = syncStatus.data.height; const utxos = []; @@ -1064,7 +1064,7 @@ async function getAddressTransactions(req, res) { }, query: {}, }; - const insightResult = daemonService.getSingleAddresssTxids(daemonRequest); + const insightResult = await daemonService.getSingleAddresssTxids(daemonRequest); const txids = insightResult.data.reverse(); const resMessage = serviceHelper.createDataMessage(txids); res.json(resMessage); @@ -1286,7 +1286,7 @@ async function getAddressBalance(req, res) { }, query: {}, }; - const insightResult = daemonService.getSingleAddressBalance(daemonRequest); + const insightResult = await daemonService.getSingleAddressBalance(daemonRequest); const { balance } = insightResult.data; const resMessage = serviceHelper.createDataMessage(balance); res.json(resMessage); From d73b7e5e0c0b900e1ff02d39f2b632de387f3393 Mon Sep 17 00:00:00 2001 From: Tadeas Kmenta Date: Mon, 21 Feb 2022 21:01:46 +0700 Subject: [PATCH 21/41] add flux tx processing for insight --- ZelBack/config/default.js | 6 +- ZelBack/src/routes.js | 2 +- ZelBack/src/services/explorerService.js | 106 +++++++++++++++++++----- 3 files changed, 89 insertions(+), 25 deletions(-) diff --git a/ZelBack/config/default.js b/ZelBack/config/default.js index 4bf7e8a80..1e838ac92 100644 --- a/ZelBack/config/default.js +++ b/ZelBack/config/default.js @@ -56,7 +56,7 @@ module.exports = { rpcporttestnet: 26224, }, daemon: { - chainValidHeight: 770000, + chainValidHeight: 1062000, port: 16125, rpcport: 16124, porttestnet: 26125, @@ -126,7 +126,7 @@ module.exports = { ram: 2000, // 2000mb hdd: 30, // 30gb // this value is likely to rise }, - fluxSpecifics: { + fluxSpecifics: { // tbd during forks cpu: { basic: 20, // 10 available for apps super: 40, // 30 available for apps @@ -142,7 +142,7 @@ module.exports = { super: 150, // 120 for apps bamf: 600, // 570 for apps }, - collateral: { + collateral: { // tbd during forks basic: 10000, super: 25000, bamf: 100000, diff --git a/ZelBack/src/routes.js b/ZelBack/src/routes.js index d991e84cd..1fef213d0 100644 --- a/ZelBack/src/routes.js +++ b/ZelBack/src/routes.js @@ -340,7 +340,7 @@ module.exports = (app, expressWs) => { // explorerService.getAllFluxTransactions(req, res); // }); // filter can be IP, address, collateralHash. - app.get('/explorer/fluxtxs/:filter?', cache('30 seconds'), (req, res) => { // deprecated + app.get('/explorer/fluxtxs/:filter?', cache('30 seconds'), (req, res) => { explorerService.getFilteredFluxTxs(req, res); }); app.get('/explorer/utxo/:address?', cache('30 seconds'), (req, res) => { diff --git a/ZelBack/src/services/explorerService.js b/ZelBack/src/services/explorerService.js index 673ccd235..87c04226d 100644 --- a/ZelBack/src/services/explorerService.js +++ b/ZelBack/src/services/explorerService.js @@ -35,20 +35,65 @@ async function getSenderTransactionFromDaemon(txid) { throw txContent.data; } +async function getSenderForFluxTxInsight(txid, vout) { + const db = serviceHelper.databaseConnection(); + const database = db.db(config.database.daemon.database); + const queryFluxTx = { + collateralHash: txid, + collateralIndex: vout, + }; + // we do not need other data as we are just asking what the sender address is. + const projectionFluxTx = { + projection: { + _id: 0, + collateralHash: 1, + zelAddress: 1, + lockedAmount: 1, + }, + }; + // find previous flux transaction that + const txContent = await serviceHelper.findOneInDatabase(database, fluxTransactionCollection, queryFluxTx, projectionFluxTx); + if (!txContent) { + // ask blockchain for the transaction + const verbose = 1; + const req = { + params: { + txid, + verbose, + }, + }; + const transaction = await daemonService.getRawTransaction(req); + if (transaction.status === 'success' && transaction.data.vout && transaction.data.vout[0]) { + const transactionOutput = transaction.data.vout.find((txVout) => txVout.n === vout); + if (transactionOutput) { + const adjustedTxContent = { + txid, + address: transactionOutput.scriptPubKey.addresses[0], + satoshis: transactionOutput.valueSat, + }; + return adjustedTxContent; + } + } + } + if (!txContent) { + log.warn(`Transaction ${txid} ${vout} was not found anywhere. Uncomplete tx!`); + const adjustedTxContent = { + txid, + address: undefined, + satoshis: undefined, + }; + return adjustedTxContent; + } + const sender = txContent; + return sender; +} + async function getSenderForFluxTx(txid, vout) { const db = serviceHelper.databaseConnection(); const database = db.db(config.database.daemon.database); const query = { - $and: [ - { txid: new RegExp(`^${txid}`) }, - { vout }, - { - $or: [ - { satoshis: 1000000000000 }, - { satoshis: 2500000000000 }, - { satoshis: 10000000000000 }, - ], - }], + txid, + vout, }; // we do not need other data as we are just asking what the sender address is. const projection = { @@ -69,16 +114,8 @@ async function getSenderForFluxTx(txid, vout) { if (!txContent) { log.info(`Transaction ${txid} ${vout} not found in database. Falling back to previous Flux transaction`); const queryFluxTx = { - $and: [ - { collateralHash: new RegExp(`^${txid}`) }, - { collateralIndex: vout }, - { - $or: [ - { lockedAmount: 1000000000000 }, - { lockedAmount: 2500000000000 }, - { lockedAmount: 10000000000000 }, - ], - }], + collateralHash: txid, + collateralIndex: vout, }; // we do not need other data as we are just asking what the sender address is. const projectionFluxTx = { @@ -307,6 +344,27 @@ async function processInsight(blockDataVerbose, database) { log.error(error); } } + } else if (tx.version === 5) { + // todo include to daemon better information about hash and index and preferably address associated + const collateralHash = tx.txhash; + const collateralIndex = tx.outidx; + // eslint-disable-next-line no-await-in-loop + const senderInfo = await getSenderForFluxTxInsight(collateralHash, collateralIndex); + const fluxTxData = { + txid: tx.txid, + version: tx.version, + type: tx.type, + updateType: tx.update_type, + ip: tx.ip, + benchTier: tx.benchmark_tier, + collateralHash, + collateralIndex, + zelAddress: senderInfo.address || senderInfo.zelAddress, + lockedAmount: senderInfo.satoshis || senderInfo.lockedAmount, + height: blockDataVerbose.height, + }; + // eslint-disable-next-line no-await-in-loop + await serviceHelper.insertOneToDatabase(database, fluxTransactionCollection, fluxTxData); } } } @@ -1066,7 +1124,13 @@ async function getAddressTransactions(req, res) { }; const insightResult = await daemonService.getSingleAddresssTxids(daemonRequest); const txids = insightResult.data.reverse(); - const resMessage = serviceHelper.createDataMessage(txids); + const txidsOK = []; + txids.forEach((txid) => { + txidsOK.push({ + txid, + }); + }); + const resMessage = serviceHelper.createDataMessage(txidsOK); res.json(resMessage); } else { const dbopen = serviceHelper.databaseConnection(); From 07c12e96c665a91d9087f3794ed44ea215056c81 Mon Sep 17 00:00:00 2001 From: Tadeas Kmenta Date: Mon, 21 Feb 2022 21:08:09 +0700 Subject: [PATCH 22/41] change insight epoch to deterministicNodesStart --- ZelBack/config/default.js | 1 + ZelBack/src/services/explorerService.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ZelBack/config/default.js b/ZelBack/config/default.js index 1e838ac92..a59e5b822 100644 --- a/ZelBack/config/default.js +++ b/ZelBack/config/default.js @@ -63,6 +63,7 @@ module.exports = { rpcporttestnet: 26124, }, fluxTeamZelId: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', + deterministicNodesStart: 558000, fluxapps: { // in flux main chain per month (blocksLasting) price: [{ // any price fork can be done by adjusting object similarily. diff --git a/ZelBack/src/services/explorerService.js b/ZelBack/src/services/explorerService.js index 87c04226d..db19efbf0 100644 --- a/ZelBack/src/services/explorerService.js +++ b/ZelBack/src/services/explorerService.js @@ -794,8 +794,8 @@ async function initiateBlockProcessor(restoreDatabase, deepRestore, reindexOrRes const isInsightExplorer = daemonService.isInsightExplorer(); if (isInsightExplorer) { // if node is insight explorer based, we are only processing flux app messages - if (scannedBlockHeight < config.fluxapps.epochstart - 1) { - scannedBlockHeight = config.fluxapps.epochstart - 1; + if (scannedBlockHeight < config.deterministicNodesStart - 1) { + scannedBlockHeight = config.deterministicNodesStart - 1; } } processBlock(scannedBlockHeight + 1, isInsightExplorer); From c718d4cbb8fa129c4adfb2a972394413ec60102b Mon Sep 17 00:00:00 2001 From: Tadeas Kmenta Date: Mon, 21 Feb 2022 21:37:10 +0700 Subject: [PATCH 23/41] fix tx processing, logging --- ZelBack/src/services/explorerService.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ZelBack/src/services/explorerService.js b/ZelBack/src/services/explorerService.js index db19efbf0..de0fc99ae 100644 --- a/ZelBack/src/services/explorerService.js +++ b/ZelBack/src/services/explorerService.js @@ -292,7 +292,7 @@ async function processInsight(blockDataVerbose, database) { const txs = blockDataVerbose.tx; // go through each transaction in deltas // eslint-disable-next-line no-restricted-syntax - for (const tx in txs) { + for (const tx of txs) { if (tx.version < 5 && tx.version > 0) { let message = ''; let isFluxAppMessageValue = 0; @@ -496,14 +496,16 @@ async function processBlock(blockHeight, isInsightExplorer) { await processStandard(blockDataVerbose, database); } if (blockHeight % config.fluxapps.expireFluxAppsPeriod === 0) { - const result = await serviceHelper.collectionStats(database, utxoIndexCollection); - const resultB = await serviceHelper.collectionStats(database, addressTransactionIndexCollection); + if (!isInsightExplorer) { + const result = await serviceHelper.collectionStats(database, utxoIndexCollection); + const resultB = await serviceHelper.collectionStats(database, addressTransactionIndexCollection); + const resultFusion = await serviceHelper.collectionStats(database, coinbaseFusionIndexCollection); + log.info(`UTXO documents: ${result.size}, ${result.count}, ${result.avgObjSize}`); + log.info(`ADDR documents: ${resultB.size}, ${resultB.count}, ${resultB.avgObjSize}`); + log.info(`Fusion documents: ${resultFusion.size}, ${resultFusion.count}, ${resultFusion.avgObjSize}`); + } const resultC = await serviceHelper.collectionStats(database, fluxTransactionCollection); - log.info(`UTXO documents: ${result.size}, ${result.count}, ${result.avgObjSize}`); - log.info(`ADDR documents: ${resultB.size}, ${resultB.count}, ${resultB.avgObjSize}`); log.info(`FLUX documents: ${resultC.size}, ${resultC.count}, ${resultC.avgObjSize}`); - const resultFusion = await serviceHelper.collectionStats(database, coinbaseFusionIndexCollection); - log.info(`Fusion documents: ${resultFusion.size}, ${resultFusion.count}, ${resultFusion.avgObjSize}`); if (blockDataVerbose.height >= config.fluxapps.epochstart) { appsService.expireGlobalApplications(); } From b6755a3c15924d0ad4c6774fdadbfad41e7ea880 Mon Sep 17 00:00:00 2001 From: Tadeas Kmenta Date: Mon, 21 Feb 2022 21:50:26 +0700 Subject: [PATCH 24/41] convert to number comparison --- ZelBack/src/services/explorerService.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ZelBack/src/services/explorerService.js b/ZelBack/src/services/explorerService.js index de0fc99ae..e371073d1 100644 --- a/ZelBack/src/services/explorerService.js +++ b/ZelBack/src/services/explorerService.js @@ -64,7 +64,7 @@ async function getSenderForFluxTxInsight(txid, vout) { }; const transaction = await daemonService.getRawTransaction(req); if (transaction.status === 'success' && transaction.data.vout && transaction.data.vout[0]) { - const transactionOutput = transaction.data.vout.find((txVout) => txVout.n === vout); + const transactionOutput = transaction.data.vout.find((txVout) => +txVout.n === +vout); if (transactionOutput) { const adjustedTxContent = { txid, From 835ef45f1a441cf6e6f9f1ff3b6a4fc3c5ddb994 Mon Sep 17 00:00:00 2001 From: JacekAdamczyk Date: Mon, 21 Feb 2022 19:37:12 +0100 Subject: [PATCH 25/41] add verifyZelID, verifyMessage, deleteLoginPhrase tests --- ZelBack/src/services/serviceHelper.js | 2 +- tests/ZelBack/serviceHelper.js | 30 ----- tests/unit/serviceHelper.test.js | 148 ++++++++++----------- tests/unit/verificationHelper.test.js | 6 +- tests/unit/verificationHelperUtils.test.js | 92 ++++++++++++- 5 files changed, 166 insertions(+), 112 deletions(-) delete mode 100644 tests/ZelBack/serviceHelper.js diff --git a/ZelBack/src/services/serviceHelper.js b/ZelBack/src/services/serviceHelper.js index e7c99aea2..c03476d9d 100644 --- a/ZelBack/src/services/serviceHelper.js +++ b/ZelBack/src/services/serviceHelper.js @@ -490,7 +490,7 @@ function verifyZelID(address) { } isValid = true; } catch (e) { - log.error(e); + // log.error(e); - the function is not used at the moment, commented out to clean up test logs isValid = e; } return isValid; diff --git a/tests/ZelBack/serviceHelper.js b/tests/ZelBack/serviceHelper.js deleted file mode 100644 index 412aa89f2..000000000 --- a/tests/ZelBack/serviceHelper.js +++ /dev/null @@ -1,30 +0,0 @@ -process.env.NODE_CONFIG_DIR = `${process.cwd()}/ZelBack/config/`; -const helper = require("../../ZelBack/src/services/serviceHelper"); -const chai = require('chai'); -const expect = chai.expect; - -describe('Flux signer', () => { - it('signs and verifies messages correctly', () => { - const message = 'abc'; - const privKey = '5JTeg79dTLzzHXoJPALMWuoGDM8QmLj4n5f6MeFjx8dzsirvjAh'; - const pubKey = '0474eb4690689bb408139249eda7f361b7881c4254ccbe303d3b4d58c2b48897d0f070b44944941998551f9ea0e1befd96f13adf171c07c885e62d0c2af56d3dab'; - const signature = helper.signMessage(message, privKey); - console.log(signature); - const verification = helper.verifyMessage(message, pubKey, signature); - expect(verification).to.equal(true); - const verification2 = helper.verifyMessage(message, 'abc', signature); - expect(verification2).to.be.an('error'); - const signature2 = helper.signMessage(message, 'asd'); - expect(signature2).to.be.an('error'); - const verification3 = helper.verifyMessage(message, pubKey, 'kappa'); - expect(verification3).to.be.an('error'); - const verification4 = helper.verifyMessage(message, '1KoXq8mLxpNt3BSnNLq2HzKC39Ne2pVJtF', signature); - expect(verification4).to.equal(true); - const verification5 = helper.verifyMessage(message, '1KoXq8mLxpNt3BSnNLqd2HzKC39Ne2pVJtF', signature); - expect(verification5).to.be.an('error'); - const verification6 = helper.verifyMessage(message, 'bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq', signature); - expect(verification6).to.equal(false); - const verification7 = helper.verifyMessage(message, '1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2', signature); - expect(verification7).to.equal(false); - }); -}); \ No newline at end of file diff --git a/tests/unit/serviceHelper.test.js b/tests/unit/serviceHelper.test.js index 8efdad2b7..64af5862f 100644 --- a/tests/unit/serviceHelper.test.js +++ b/tests/unit/serviceHelper.test.js @@ -359,106 +359,100 @@ describe('serviceHelper tests', () => { }); }); - describe('verifyAdminSession tests', () => { - beforeEach(async () => { - await serviceHelper.initiateDB(); - const db = serviceHelper.databaseConnection(); - const database = db.db(config.database.local.database); - const collection = config.database.local.collections.loggedUsers; - const insertUsers = [{ - "_id": ObjectId("60cad0767247ac0a779fb3f0"), - "zelid": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", // admin - "loginPhrase": "16125160820394ddsh5skgwv0ipodku92y0jbwvpyj17bh68lzrjlxq9", - "signature": "IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=" - }, { - "_id": ObjectId("6108fbb9f04dfe1ef624b819"), - "zelid": "1hjy4bCYBJr4mny4zCE85J94RXa8W6q37", // regular user - "loginPhrase": "162797868130153vt9r89dzjjjfg6kf34ntf1d8aa5zqlk04j3zy8z40ni", - "signature": "H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=" - }]; + describe('verifyZelID tests', () => { + it('should throw error if ZelID is empty', () => { + const isValid = serviceHelper.verifyZelID(); + expect(isValid).to.be.an('error'); + }); - try { - await database.collection(collection).drop(); - } catch (err) { - console.log('Collection not found.'); - } + it('should return throw error if ZelID is invalid', () => { + const isValid = serviceHelper.verifyZelID('34xp4vRoCGJym3xR7yCVPFHoCNxv4Twseo'); + expect(isValid).to.be.an('error'); - for (let insertUser of insertUsers) { - await serviceHelper.insertOneToDatabase(database, collection, insertUser); - } }); - it("should return true when requested by admin", async () => { - const headers = { - zelidauth: { - zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', - signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' - } - } + it('should return true if ZelID is valid', () => { + const isValid = serviceHelper.verifyZelID('1P5ZEDWTKTFGxQjZphgWPQUpe554WKDfHQ'); + expect(isValid).to.be.true; + }); + }); - const isAdmin = await serviceHelper.verifyAdminSession(headers); + describe('verifyMessage tests', () => { + const message = 'test'; + const publicKey = '0474eb4690689bb408139249eda7f361b7881c4254ccbe303d3b4d58c2b48897d0f070b44944941998551f9ea0e1befd96f13adf171c07c885e62d0c2af56d3dab'; + const validSignature = 'G6wvdaMqtuQYqa5BAtKsLHFCYQwB4PXoTwG0YSGtWU6ude/brDNM5MraSBfT64HU3XPhObGohFjLLo6KjtMgnlc='; + const address = '1KoXq8mLxpNt3BSnNLq2HzKC39Ne2pVJtF'; - expect(isAdmin).to.be.true; + it('should return true if message is signed properly with a public key', () => { + const verification = serviceHelper.verifyMessage(message, publicKey, validSignature); + expect(verification).to.be.true; }); - it("should return false when requested by regular user", async () => { - const headers = { - zelidauth: { - zelid: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', - signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=' - } - } - - const isAdmin = await serviceHelper.verifyAdminSession(headers); + it('should return true if message is signed properly with an address', () => { + const verification = serviceHelper.verifyMessage(message, address, validSignature); + expect(verification).to.be.true; + }); - expect(isAdmin).to.be.false; + it('should return error if the address is invalid', () => { + const verification = serviceHelper.verifyMessage(message, '12355', validSignature); + expect(verification).to.be.an('error'); }); - it("should return false if signature is invalid", async () => { - const headers = { - zelidauth: { - zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', - signature: 'IH9d68fk/dYQtzMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' - } - } + it('should return false if the publicKey is invalid', () => { + const verification = serviceHelper.verifyMessage(message, '0474eb4690689bb408139249eda7f361b7881c4254ccbe30', validSignature); + expect(verification).to.be.false; + }); - const isAdmin = await serviceHelper.verifyAdminSession(headers); + it('should return error if there is no signature', () => { + const verification = serviceHelper.verifyMessage(message, address); + expect(verification).to.be.an('error'); + }); - expect(isAdmin).to.be.false; + it('should return false if the address is wrong', () => { + const verification = serviceHelper.verifyMessage(message, '1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2', validSignature); + expect(verification).to.be.false; }); - it("should return false if zelID is invalid", async () => { - const headers = { - zelidauth: { - zelid: '2CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', - signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' - } - } + it('should return error if the signature is invalid', () => { + const verification = serviceHelper.verifyMessage(message, address, '1234567ASDFG'); + expect(verification).to.be.an('error'); + }); + }); - const isAdmin = await serviceHelper.verifyAdminSession(headers); + describe.only('deleteLoginPhrase tests', () => { + const query = { "loginPhrase": { $eq: "1644935809116x5fpl862o5fnyl29vfpmd9vzmgaddlgqbud8cxks8hj" } }; + const loginPhrase = { + "_id": ObjectId("620bba81c04b4966674013a4"), + "loginPhrase": "1644935809116x5fpl862o5fnyl29vfpmd9vzmgaddlgqbud8cxks8hj", + "createdAt": new Date("2022-02-15T14:36:49.116Z"), + "expireAt": new Date("2022-02-15T14:51:49.116Z") + } + let db; + let database; + let collection; - expect(isAdmin).to.be.false; - }); + beforeEach(async () => { + await serviceHelper.initiateDB(); + db = serviceHelper.databaseConnection(); + database = db.db(config.database.local.database); + collection = config.database.local.collections.activeLoginPhrases; - it("should return false if header values are empty", async () => { - const headers = { - zelidauth: { - zelid: '', - signature: '' - } + try { + await database.collection(collection).drop(); + } catch (err) { + console.log('Collection not found.'); } - const isAdmin = await serviceHelper.verifyAdminSession(headers); + await database.collection(collection).insertOne(loginPhrase); - expect(isAdmin).to.be.false; + const initialInsert = await database.collection(collection).findOne(query); + expect(initialInsert).to.eql(loginPhrase); }); - it("should return false if header is empty", async () => { - const headers = {} - - const isAdmin = await serviceHelper.verifyAdminSession(headers); - - expect(isAdmin).to.be.false; + it('should delete the login phrase properly', async () => { + await serviceHelper.deleteLoginPhrase('1644935809116x5fpl862o5fnyl29vfpmd9vzmgaddlgqbud8cxks8hj'); + const afterDeletionResult = await database.collection(collection).findOne(query); + expect(afterDeletionResult).to.be.null; }); }); diff --git a/tests/unit/verificationHelper.test.js b/tests/unit/verificationHelper.test.js index e49d8a960..719a970f7 100644 --- a/tests/unit/verificationHelper.test.js +++ b/tests/unit/verificationHelper.test.js @@ -5,7 +5,7 @@ const sinon = require('sinon'); const verificationHelperUtils = require("../../ZelBack/src/services/verificationHelperUtils"); const { verifyPrivilege } = require("../../ZelBack/src/services/verificationHelper"); -//placeholders - verification functions are mocked, since they've already been tested in verificationHelperUtils.test +//placeholders - verification functions are mocked, they have already been tested in verificationHelperUtils.test const req = { headers: { zelidauth: { @@ -78,14 +78,14 @@ describe('verificationHelper tests', () => { stub.reset(); }); - it('should return false when a wrong flag - "test" is passed', async () => { + it('should return false when a wrong flag - string "test" is passed', async () => { const privilege = 'test'; const verifyPrivilegeResult = await verifyPrivilege(privilege, req); expect(verifyPrivilegeResult).to.be.false; }); - it('should return false when a wrong flag - true is passed', async () => { + it('should return false when a wrong flag - bool true is passed', async () => { const privilege = true; const verifyPrivilegeResult = await verifyPrivilege(privilege, req); diff --git a/tests/unit/verificationHelperUtils.test.js b/tests/unit/verificationHelperUtils.test.js index b19572ced..a2cdb147f 100644 --- a/tests/unit/verificationHelperUtils.test.js +++ b/tests/unit/verificationHelperUtils.test.js @@ -46,6 +46,96 @@ const insertApp = { } describe('verificationHelperUtils tests', () => { + describe('verifyAdminSession tests', () => { + beforeEach(async () => { + await serviceHelper.initiateDB(); + const db = serviceHelper.databaseConnection(); + const database = db.db(config.database.local.database); + const collection = config.database.local.collections.loggedUsers; + + try { + await database.collection(collection).drop(); + } catch (err) { + console.log('Collection not found.'); + } + + await database.collection(collection).insertMany(insertUsers); + }); + + it("should return true when requested by admin", async () => { + const headers = { + zelidauth: { + zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' + } + } + + const isAdmin = await verificationHelperUtils.verifyAdminSession(headers); + + expect(isAdmin).to.be.true; + }); + + it("should return false when requested by regular user", async () => { + const headers = { + zelidauth: { + zelid: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', + signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=' + } + } + + const isAdmin = await verificationHelperUtils.verifyAdminSession(headers); + + expect(isAdmin).to.be.false; + }); + + it("should return false if signature is invalid", async () => { + const headers = { + zelidauth: { + zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + signature: 'IH9d68fk/dYQtzMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' + } + } + + const isAdmin = await verificationHelperUtils.verifyAdminSession(headers); + + expect(isAdmin).to.be.false; + }); + + it("should return false if zelID is invalid", async () => { + const headers = { + zelidauth: { + zelid: '2CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' + } + } + + const isAdmin = await verificationHelperUtils.verifyAdminSession(headers); + + expect(isAdmin).to.be.false; + }); + + it("should return false if header values are empty", async () => { + const headers = { + zelidauth: { + zelid: '', + signature: '' + } + } + + const isAdmin = await verificationHelperUtils.verifyAdminSession(headers); + + expect(isAdmin).to.be.false; + }); + + it("should return false if header is empty", async () => { + const headers = {} + + const isAdmin = await verificationHelperUtils.verifyAdminSession(headers); + + expect(isAdmin).to.be.false; + }); + }); + describe('verifyUserSession tests', () => { beforeEach(async () => { await serviceHelper.initiateDB(); @@ -59,7 +149,7 @@ describe('verificationHelperUtils tests', () => { console.log('Collection not found.'); } - + await database.collection(collection).insertMany(insertUsers); }); From 64697b4be65f54eadf8f851a9f4b9a98ea263a03 Mon Sep 17 00:00:00 2001 From: Tadeas Kmenta Date: Tue, 22 Feb 2022 09:41:14 +0700 Subject: [PATCH 26/41] remove deprecation from fluxtxs --- ZelBack/src/services/explorerService.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/ZelBack/src/services/explorerService.js b/ZelBack/src/services/explorerService.js index e371073d1..2f83259d6 100644 --- a/ZelBack/src/services/explorerService.js +++ b/ZelBack/src/services/explorerService.js @@ -880,10 +880,6 @@ async function getAllFusionCoinbase(req, res) { async function getAllFluxTransactions(req, res) { try { - const isInsightExplorer = daemonService.isInsightExplorer(); - if (isInsightExplorer) { - throw new Error('Data unavailable. Deprecated'); - } const dbopen = serviceHelper.databaseConnection(); const database = dbopen.db(config.database.daemon.database); const query = {}; @@ -1059,10 +1055,6 @@ async function getAddressFusionCoinbase(req, res) { async function getFilteredFluxTxs(req, res) { try { - const isInsightExplorer = daemonService.isInsightExplorer(); - if (isInsightExplorer) { - throw new Error('Data unavailable. Deprecated'); - } let { filter } = req.params; // we accept both help/command and help?command=getinfo filter = filter || req.query.filter; let query = {}; From 1cdef2a9d064b6d30f85f66f5c75b19f54da8369 Mon Sep 17 00:00:00 2001 From: Cabecinha84 <42519726+Cabecinha84@users.noreply.github.com> Date: Tue, 22 Feb 2022 07:51:45 +0000 Subject: [PATCH 27/41] Only processInsight if block after epochstart --- ZelBack/src/services/explorerService.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ZelBack/src/services/explorerService.js b/ZelBack/src/services/explorerService.js index 2f83259d6..c9a7fcfa8 100644 --- a/ZelBack/src/services/explorerService.js +++ b/ZelBack/src/services/explorerService.js @@ -491,7 +491,9 @@ async function processBlock(blockHeight, isInsightExplorer) { } if (isInsightExplorer) { // only process Flux transactions - await processInsight(blockDataVerbose, database); + if (blockDataVerbose.height >= config.fluxapps.epochstart) { + await processInsight(blockDataVerbose, database); + } } else { await processStandard(blockDataVerbose, database); } From 6a9fe4a2e6336fa3f237136334449d24237dd264 Mon Sep 17 00:00:00 2001 From: Cabecinha84 <42519726+Cabecinha84@users.noreply.github.com> Date: Tue, 22 Feb 2022 07:56:05 +0000 Subject: [PATCH 28/41] Revert not needed already done on initiateBlockProcessor --- ZelBack/src/services/explorerService.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ZelBack/src/services/explorerService.js b/ZelBack/src/services/explorerService.js index c9a7fcfa8..2f83259d6 100644 --- a/ZelBack/src/services/explorerService.js +++ b/ZelBack/src/services/explorerService.js @@ -491,9 +491,7 @@ async function processBlock(blockHeight, isInsightExplorer) { } if (isInsightExplorer) { // only process Flux transactions - if (blockDataVerbose.height >= config.fluxapps.epochstart) { - await processInsight(blockDataVerbose, database); - } + await processInsight(blockDataVerbose, database); } else { await processStandard(blockDataVerbose, database); } From 4465e86f5587adab21f5686b23212127a7f421e2 Mon Sep 17 00:00:00 2001 From: Cabecinha84 <42519726+Cabecinha84@users.noreply.github.com> Date: Tue, 22 Feb 2022 09:14:59 +0000 Subject: [PATCH 29/41] store isDaemonInsightExplorer in memory --- ZelBack/src/services/daemonService.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ZelBack/src/services/daemonService.js b/ZelBack/src/services/daemonService.js index 15661d534..6d51b0d48 100644 --- a/ZelBack/src/services/daemonService.js +++ b/ZelBack/src/services/daemonService.js @@ -14,6 +14,7 @@ const rpcport = fnconfig.rpcport() || (isTestnet === true ? config.daemon.rpcpor let currentDaemonHeight = 0; let currentDaemonHeader = isTestnet === true ? 58494 : 1060453; +let isDaemonInsightExplorer = null; const client = new daemonrpc.Client({ port: rpcport, @@ -109,10 +110,15 @@ function getConfigValue(parameter) { } function isInsightExplorer() { + if (isDaemonInsightExplorer != null) { + return isDaemonInsightExplorer; + } const insightValue = getConfigValue('insightexplorer'); if (insightValue === 1 || insightValue === '1') { + isDaemonInsightExplorer = true; return true; } + isDaemonInsightExplorer = false; return false; } From f03888b0b0e7d6849aefdfa3a8f3ead7dc8d33e2 Mon Sep 17 00:00:00 2001 From: JacekAdamczyk Date: Tue, 22 Feb 2022 15:29:17 +0100 Subject: [PATCH 30/41] modify privilige verification reference --- ZelBack/src/services/appsService.js | 49 ++-- ZelBack/src/services/benchmarkService.js | 9 +- ZelBack/src/services/daemonService.js | 165 +++++++------- ZelBack/src/services/explorerService.js | 9 +- ZelBack/src/services/fluxCommunication.js | 21 +- ZelBack/src/services/fluxService.js | 55 ++--- ZelBack/src/services/fluxshareService.js | 27 +-- ZelBack/src/services/idService.js | 31 +-- ZelBack/src/services/serviceHelper.js | 261 ---------------------- tests/unit/serviceHelper.test.js | 2 +- 10 files changed, 189 insertions(+), 440 deletions(-) diff --git a/ZelBack/src/services/appsService.js b/ZelBack/src/services/appsService.js index 7aa4a5faa..4238cc639 100644 --- a/ZelBack/src/services/appsService.js +++ b/ZelBack/src/services/appsService.js @@ -10,6 +10,7 @@ const systemcrontab = require('crontab'); const util = require('util'); const fluxCommunication = require('./fluxCommunication'); const serviceHelper = require('./serviceHelper'); +const verificationHelper = require('./verificationHelper'); const daemonService = require('./daemonService'); const dockerService = require('./dockerService'); const generalService = require('./generalService'); @@ -140,7 +141,7 @@ async function appStart(req, res) { const mainAppName = appname.split('_')[1] || appname; - const authorized = await serviceHelper.verifyPrivilege('appownerabove', req, mainAppName); + const authorized = await verificationHelper.verifyPrivilege('appownerabove', req, mainAppName); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); return res ? res.json(errMessage) : errMessage; @@ -194,7 +195,7 @@ async function appStop(req, res) { const mainAppName = appname.split('_')[1] || appname; - const authorized = await serviceHelper.verifyPrivilege('appownerabove', req, mainAppName); + const authorized = await verificationHelper.verifyPrivilege('appownerabove', req, mainAppName); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); return res ? res.json(errMessage) : errMessage; @@ -248,7 +249,7 @@ async function appRestart(req, res) { const mainAppName = appname.split('_')[1] || appname; - const authorized = await serviceHelper.verifyPrivilege('appownerabove', req, mainAppName); + const authorized = await verificationHelper.verifyPrivilege('appownerabove', req, mainAppName); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); return res ? res.json(errMessage) : errMessage; @@ -302,7 +303,7 @@ async function appKill(req, res) { const mainAppName = appname.split('_')[1] || appname; - const authorized = await serviceHelper.verifyPrivilege('appownerabove', req, mainAppName); + const authorized = await verificationHelper.verifyPrivilege('appownerabove', req, mainAppName); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); return res ? res.json(errMessage) : errMessage; @@ -356,7 +357,7 @@ async function appPause(req, res) { const mainAppName = appname.split('_')[1] || appname; - const authorized = await serviceHelper.verifyPrivilege('appownerabove', req, mainAppName); + const authorized = await verificationHelper.verifyPrivilege('appownerabove', req, mainAppName); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); return res ? res.json(errMessage) : errMessage; @@ -410,7 +411,7 @@ async function appUnpause(req, res) { const mainAppName = appname.split('_')[1] || appname; - const authorized = await serviceHelper.verifyPrivilege('appownerabove', req, mainAppName); + const authorized = await verificationHelper.verifyPrivilege('appownerabove', req, mainAppName); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); return res ? res.json(errMessage) : errMessage; @@ -465,7 +466,7 @@ async function appTop(req, res) { const mainAppName = appname.split('_')[1] || appname; - const authorized = await serviceHelper.verifyPrivilege('appownerabove', req, mainAppName); + const authorized = await verificationHelper.verifyPrivilege('appownerabove', req, mainAppName); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); return res ? res.json(errMessage) : errMessage; @@ -500,7 +501,7 @@ async function appLog(req, res) { const mainAppName = appname.split('_')[1] || appname; - const authorized = await serviceHelper.verifyPrivilege('appownerabove', req, mainAppName); + const authorized = await verificationHelper.verifyPrivilege('appownerabove', req, mainAppName); if (authorized === true) { const logs = await dockerService.dockerContainerLogs(appname, lines); const dataMessage = serviceHelper.createDataMessage(logs); @@ -531,7 +532,7 @@ async function appLogStream(req, res) { const mainAppName = appname.split('_')[1] || appname; - const authorized = await serviceHelper.verifyPrivilege('appownerabove', req, mainAppName); + const authorized = await verificationHelper.verifyPrivilege('appownerabove', req, mainAppName); if (authorized === true) { res.setHeader('Content-Type', 'application/json'); dockerService.dockerContainerLogsStream(appname, res, (error) => { @@ -574,7 +575,7 @@ async function appInspect(req, res) { const mainAppName = appname.split('_')[1] || appname; - const authorized = await serviceHelper.verifyPrivilege('appownerabove', req, mainAppName); + const authorized = await verificationHelper.verifyPrivilege('appownerabove', req, mainAppName); if (authorized === true) { const response = await dockerService.dockerContainerInspect(appname); const appResponse = serviceHelper.createDataMessage(response); @@ -605,7 +606,7 @@ async function appStats(req, res) { const mainAppName = appname.split('_')[1] || appname; - const authorized = await serviceHelper.verifyPrivilege('appownerabove', req, mainAppName); + const authorized = await verificationHelper.verifyPrivilege('appownerabove', req, mainAppName); if (authorized === true) { const response = await dockerService.dockerContainerStats(appname); const appResponse = serviceHelper.createDataMessage(response); @@ -636,7 +637,7 @@ async function appChanges(req, res) { const mainAppName = appname.split('_')[1] || appname; - const authorized = await serviceHelper.verifyPrivilege('appownerabove', req, mainAppName); + const authorized = await verificationHelper.verifyPrivilege('appownerabove', req, mainAppName); if (authorized === true) { const response = await dockerService.dockerContainerChanges(appname); const appResponse = serviceHelper.createDataMessage(response); @@ -675,7 +676,7 @@ async function appExec(req, res) { const mainAppName = processedBody.appname.split('_')[1] || processedBody.appname; - const authorized = await serviceHelper.verifyPrivilege('appowner', req, mainAppName); + const authorized = await verificationHelper.verifyPrivilege('appowner', req, mainAppName); if (authorized === true) { let cmd = processedBody.cmd || []; let env = processedBody.env || []; @@ -721,7 +722,7 @@ async function appExec(req, res) { async function createFluxNetworkAPI(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); return res.json(errMessage); @@ -1752,7 +1753,7 @@ async function removeAppLocallyApi(req, res) { throw new Error('No Flux App specified'); } - const authorized = await serviceHelper.verifyPrivilege('appownerabove', req, appname); + const authorized = await verificationHelper.verifyPrivilege('appownerabove', req, appname); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); res.json(errMessage); @@ -4065,7 +4066,7 @@ async function registerAppGlobalyApi(req, res) { }); req.on('end', async () => { try { - const authorized = await serviceHelper.verifyPrivilege('user', req); + const authorized = await verificationHelper.verifyPrivilege('user', req); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); res.json(errMessage); @@ -4180,7 +4181,7 @@ async function updateAppGlobalyApi(req, res) { }); req.on('end', async () => { try { - const authorized = await serviceHelper.verifyPrivilege('user', req); + const authorized = await verificationHelper.verifyPrivilege('user', req); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); res.json(errMessage); @@ -4350,7 +4351,7 @@ async function installTemporaryLocalApplication(req, res) { if (!appname) { throw new Error('No Flux App specified'); } - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized) { const allApps = await availableApps(); const appSpecifications = allApps.find((app) => app.name === appname); @@ -4723,7 +4724,7 @@ async function checkDockerAccessibility(req, res) { }); req.on('end', async () => { try { - const authorized = await serviceHelper.verifyPrivilege('user', req); + const authorized = await verificationHelper.verifyPrivilege('user', req); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); return res.json(errMessage); @@ -4860,7 +4861,7 @@ async function rescanGlobalAppsInformation(height = 0, removeLastInformation = f async function reindexGlobalAppsLocationAPI(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { await reindexGlobalAppsLocation(); const message = serviceHelper.createSuccessMessage('Reindex successfull'); @@ -4882,7 +4883,7 @@ async function reindexGlobalAppsLocationAPI(req, res) { async function reindexGlobalAppsInformationAPI(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { await reindexGlobalAppsInformation(); const message = serviceHelper.createSuccessMessage('Reindex successfull'); @@ -4904,7 +4905,7 @@ async function reindexGlobalAppsInformationAPI(req, res) { async function rescanGlobalAppsInformationAPI(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { let { blockheight } = req.params; // we accept both help/command and help?command=getinfo blockheight = blockheight || req.query.blockheight; @@ -6034,7 +6035,7 @@ async function redeployAPI(req, res) { force = force || req.query.force || false; force = serviceHelper.ensureBoolean(force); - const authorized = await serviceHelper.verifyPrivilege('appownerabove', req, appname); + const authorized = await verificationHelper.verifyPrivilege('appownerabove', req, appname); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); res.json(errMessage); @@ -6213,7 +6214,7 @@ async function reconstructAppMessagesHashCollection() { async function reconstructAppMessagesHashCollectionAPI(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized) { const result = await reconstructAppMessagesHashCollection(); const message = serviceHelper.createSuccessMessage(result); diff --git a/ZelBack/src/services/benchmarkService.js b/ZelBack/src/services/benchmarkService.js index b2576d5c2..a4b412764 100644 --- a/ZelBack/src/services/benchmarkService.js +++ b/ZelBack/src/services/benchmarkService.js @@ -3,6 +3,7 @@ const config = require('config'); const path = require('path'); const fs = require('fs'); const serviceHelper = require('./serviceHelper'); +const verificationHelper = require('./verificationHelper'); const userconfig = require('../../../config/userconfig'); const isTestnet = userconfig.initial.testnet; @@ -52,7 +53,7 @@ async function getStatus(req, res) { } async function restartNodeBenchmarks(req, res) { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const rpccall = 'restartnodebenchmarks'; @@ -65,7 +66,7 @@ async function restartNodeBenchmarks(req, res) { } async function signFluxTransaction(req, res) { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); let { hexstring } = req.params; hexstring = hexstring || req.query.hexstring; if (authorized === true) { @@ -91,7 +92,7 @@ async function signFluxTransactionPost(req, res) { req.on('end', async () => { const processedBody = serviceHelper.ensureObject(body); const { hexstring } = processedBody; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'signzelnodetransaction'; const rpcparameters = []; @@ -120,7 +121,7 @@ async function help(req, res) { } async function stop(req, res) { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'stop'; diff --git a/ZelBack/src/services/daemonService.js b/ZelBack/src/services/daemonService.js index ff9e3ffb9..fa7f662f2 100644 --- a/ZelBack/src/services/daemonService.js +++ b/ZelBack/src/services/daemonService.js @@ -3,6 +3,7 @@ const fullnode = require('fullnode'); const LRU = require('lru-cache'); const config = require('config'); const serviceHelper = require('./serviceHelper'); +const verificationHelper = require('./verificationHelper'); const log = require('../lib/log'); const userconfig = require('../../../config/userconfig'); @@ -126,7 +127,7 @@ async function getInfo(req, res) { response = await executeCall(rpccall); if (res) { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized !== true) { delete response.data.balance; } @@ -138,7 +139,7 @@ async function getInfo(req, res) { } async function stop(req, res) { // practically useless - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'stop'; @@ -174,7 +175,7 @@ async function listZelNodes(req, res) { } async function listZelNodeConf(req, res) { // practically useless - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); let { filter } = req.params; filter = filter || req.query.filter; if (authorized === true) { @@ -193,7 +194,7 @@ async function listZelNodeConf(req, res) { // practically useless } async function createZelNodeKey(req, res) { // practically useless - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'createzelnodekey'; @@ -214,7 +215,7 @@ async function znsync(req, res) { response = await executeCall(rpccall, rpcparameters); } else { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'znsync'; const rpcparameters = [mode]; @@ -233,7 +234,7 @@ async function createZelNodeBroadcast(req, res) { let { alias } = req.params; alias = alias || req.query.alias || ''; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'createzelnodebroadcast'; const rpcparameters = [command, alias]; @@ -286,7 +287,7 @@ async function getStartList(req, res) { } async function getZelNodeOutputs(req, res) { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'getzelnodeoutputs'; @@ -368,7 +369,7 @@ async function startDeterministicZelNode(req, res) { alias = alias || req.query.alias; let { lockwallet } = req.params; lockwallet = lockwallet || req.query.lockwallet || false; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'startdeterministiczelnode'; const rpcparameters = []; @@ -393,7 +394,7 @@ async function startZelNode(req, res) { lockwallet = lockwallet || req.query.lockwallet; let { alias } = req.params; alias = alias || req.query.alias; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'startzelnode'; const rpcparameters = []; @@ -611,7 +612,7 @@ async function verifyChain(req, res) { checklevel = checklevel || req.query.checklevel || 3; let { numblocks } = req.params; numblocks = numblocks || req.query.numblocks || 288; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { checklevel = serviceHelper.ensureNumber(checklevel); numblocks = serviceHelper.ensureNumber(numblocks); @@ -730,7 +731,7 @@ async function prioritiseTransaction(req, res) { prioritydelta = prioritydelta || req.query.prioritydelta; let { feedelta } = req.params; feedelta = feedelta || req.query.feedelta; - const authorized = await serviceHelper.verifyPrivilege('user', req); + const authorized = await verificationHelper.verifyPrivilege('user', req); if (authorized === true) { const rpccall = 'prioritiseTransaction'; let rpcparameters = []; @@ -753,7 +754,7 @@ async function submitBlock(req, res) { hexdata = hexdata || req.query.hexdata; let { jsonparametersobject } = req.params; jsonparametersobject = jsonparametersobject || req.query.jsonparametersobject; - const authorized = await serviceHelper.verifyPrivilege('user', req); + const authorized = await verificationHelper.verifyPrivilege('user', req); if (authorized === true) { const rpccall = 'submitBlock'; let rpcparameters = []; @@ -782,7 +783,7 @@ async function submitBlockPost(req, res) { const { hexdata } = processedBody; let { jsonparametersobject } = processedBody; - const authorized = await serviceHelper.verifyPrivilege('user', req); + const authorized = await verificationHelper.verifyPrivilege('user', req); if (authorized === true) { const rpccall = 'submitBlock'; let rpcparameters = []; @@ -808,7 +809,7 @@ async function addNode(req, res) { node = node || req.query.node; let { command } = req.params; command = command || req.query.command; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'addNode'; let rpcparameters = []; @@ -825,7 +826,7 @@ async function addNode(req, res) { } async function clearBanned(req, res) { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'clearBanned'; @@ -840,7 +841,7 @@ async function clearBanned(req, res) { async function disconnectNode(req, res) { let { node } = req.params; node = node || req.query.node; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'disconnectNode'; let rpcparameters = []; @@ -861,7 +862,7 @@ async function getAddedNodeInfo(req, res) { dns = dns || req.query.dns; let { node } = req.params; node = node || req.query.node; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'getAddedNodeInfo'; const rpcparameters = []; @@ -930,7 +931,7 @@ async function listBanned(req, res) { } async function ping(req, res) { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const rpccall = 'ping'; @@ -951,7 +952,7 @@ async function setBan(req, res) { bantime = bantime || req.query.bantime; let { absolute } = req.params; absolute = absolute || req.query.absolute; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'setBan'; const rpcparameters = []; @@ -1212,7 +1213,7 @@ async function signRawTransaction(req, res) { sighashtype = sighashtype || req.query.sighashtype || 'ALL'; let { branchid } = req.params; branchid = branchid || req.query.branchid; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'signRawTransaction'; const rpcparameters = []; @@ -1252,7 +1253,7 @@ async function signRawTransactionPost(req, res) { let { sighashtype } = processedBody; sighashtype = sighashtype || 'ALL'; const { branchid } = processedBody; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'signRawTransaction'; const rpcparameters = []; @@ -1363,7 +1364,7 @@ async function validateAddress(req, res) { response = await executeCall(rpccall, rpcparameters); if (res) { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized !== true) { delete response.data.ismine; delete response.data.iswatchonly; @@ -1436,7 +1437,7 @@ async function addMultiSigAddress(req, res) { n = n || req.query.n; let { keysobject } = req.params; keysobject = keysobject || req.query.keysobject; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'addMultiSigAddress'; let rpcparameters = []; @@ -1462,7 +1463,7 @@ async function addMultiSigAddressPost(req, res) { const processedBody = serviceHelper.ensureObject(body); let { n } = processedBody; let { keysobject } = processedBody; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'addMultiSigAddress'; let rpcparameters = []; @@ -1483,7 +1484,7 @@ async function addMultiSigAddressPost(req, res) { async function backupWallet(req, res) { let { destination } = req.params; destination = destination || req.query.destination; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'backupWallet'; let rpcparameters = []; @@ -1501,7 +1502,7 @@ async function backupWallet(req, res) { async function dumpPrivKey(req, res) { let { taddr } = req.params; taddr = taddr || req.query.taddr; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'dumpPrivKey'; let rpcparameters = []; @@ -1521,7 +1522,7 @@ async function getBalance(req, res) { minconf = minconf || req.query.minconf || 1; let { includewatchonly } = req.params; includewatchonly = includewatchonly || req.query.includewatchonly || false; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'getBalance'; minconf = serviceHelper.ensureNumber(minconf); @@ -1536,7 +1537,7 @@ async function getBalance(req, res) { } async function getNewAddress(req, res) { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'getNewAddress'; response = await executeCall(rpccall); @@ -1548,7 +1549,7 @@ async function getNewAddress(req, res) { } async function getRawChangeAddress(req, res) { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'getRawChangeAddress'; response = await executeCall(rpccall); @@ -1564,7 +1565,7 @@ async function getReceivedByAddress(req, res) { zelcashaddress = zelcashaddress || req.query.zelcashaddress; let { minconf } = req.params; minconf = minconf || req.query.minconf || 1; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'getReceivedByAddress'; let rpcparameters = []; @@ -1598,7 +1599,7 @@ async function getTransaction(req, res) { } async function getUnconfirmedBalance(req, res) { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'getUnconfirmedBalance'; response = await executeCall(rpccall); @@ -1610,7 +1611,7 @@ async function getUnconfirmedBalance(req, res) { } async function getWalletInfo(req, res) { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'getWalletInfo'; response = await executeCall(rpccall); @@ -1628,7 +1629,7 @@ async function importAddress(req, res) { label = label || req.query.label || ''; let { rescan } = req.params; rescan = rescan || req.query.rescan || true; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'importAddress'; let rpcparameters = []; @@ -1651,7 +1652,7 @@ async function importPrivKey(req, res) { label = label || req.query.label || ''; let { rescan } = req.params; rescan = rescan || req.query.rescan || true; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'importPrivKey'; let rpcparameters = []; @@ -1670,7 +1671,7 @@ async function importPrivKey(req, res) { async function importWallet(req, res) { let { filename } = req.params; filename = filename || req.query.filename; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'importWallet'; let rpcparameters = []; @@ -1688,7 +1689,7 @@ async function importWallet(req, res) { async function keyPoolRefill(req, res) { let { newsize } = req.params; newsize = newsize || req.query.newsize || 100; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'keyPoolRefill'; newsize = serviceHelper.ensureNumber(newsize); @@ -1702,7 +1703,7 @@ async function keyPoolRefill(req, res) { } async function listAddressGroupings(req, res) { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'listAddressGroupings'; response = await executeCall(rpccall); @@ -1714,7 +1715,7 @@ async function listAddressGroupings(req, res) { } async function listLockUnspent(req, res) { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'listLockUnspent'; response = await executeCall(rpccall); @@ -1728,7 +1729,7 @@ async function listLockUnspent(req, res) { async function rescanBlockchain(req, res) { let { startheight } = req.params; startheight = startheight || req.query.startheight || 0; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { startheight = serviceHelper.ensureNumber(startheight); const rpccall = 'rescanblockchain'; @@ -1748,7 +1749,7 @@ async function listReceivedByAddress(req, res) { includeempty = includeempty || req.query.includeempty || false; let { includewatchonly } = req.params; includewatchonly = includewatchonly || req.query.includewatchonly || false; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { minconf = serviceHelper.ensureNumber(minconf); includeempty = serviceHelper.ensureBoolean(includeempty); @@ -1770,7 +1771,7 @@ async function listSinceBlock(req, res) { targetconfirmations = targetconfirmations || req.query.targetconfirmations || 1; let { includewatchonly } = req.params; includewatchonly = includewatchonly || req.query.includewatchonly || false; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { targetconfirmations = serviceHelper.ensureNumber(targetconfirmations); includewatchonly = serviceHelper.ensureBoolean(includewatchonly); @@ -1792,7 +1793,7 @@ async function listTransactions(req, res) { from = from || req.query.from || 0; let { includewatchonly } = req.params; includewatchonly = includewatchonly || req.query.includewatchonly || false; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { count = serviceHelper.ensureNumber(count); from = serviceHelper.ensureNumber(from); @@ -1814,7 +1815,7 @@ async function listUnspent(req, res) { maxconf = maxconf || req.query.maxconf || 9999999; let { addresses } = req.params; addresses = addresses || req.query.addresses; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { minconf = serviceHelper.ensureNumber(minconf); maxconf = serviceHelper.ensureNumber(maxconf); @@ -1838,7 +1839,7 @@ async function lockUnspent(req, res) { unlock = unlock || req.query.unlock; let { transactions } = req.params; transactions = transactions || req.query.transactions; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'lockUnspent'; let rpcparameters = []; @@ -1868,7 +1869,7 @@ async function sendFrom(req, res) { comment = comment || req.query.comment || ''; let { commentto } = req.params; commentto = commentto || req.query.commentto || ''; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'sendFrom'; let rpcparameters = []; @@ -1902,7 +1903,7 @@ async function sendFromPost(req, res) { minconf = minconf || 1; comment = comment || ''; commentto = commentto || ''; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'sendFrom'; let rpcparameters = []; @@ -1931,7 +1932,7 @@ async function sendMany(req, res) { comment = comment || req.query.comment || ''; let { substractfeefromamount } = req.params; substractfeefromamount = substractfeefromamount || req.query.substractfeefromamount; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'sendMany'; let rpcparameters = []; @@ -1967,7 +1968,7 @@ async function sendManyPost(req, res) { const fromaccount = ''; minconf = minconf || 1; comment = comment || ''; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'sendMany'; let rpcparameters = []; @@ -2001,7 +2002,7 @@ async function sendToAddress(req, res) { commentto = commentto || req.query.commentto || ''; let { substractfeefromamount } = req.params; substractfeefromamount = substractfeefromamount || req.query.substractfeefromamount || false; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'sendToAddress'; let rpcparameters = []; @@ -2034,7 +2035,7 @@ async function sendToAddressPost(req, res) { comment = comment || ''; commentto = commentto || ''; substractfeefromamount = substractfeefromamount || false; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'sendToAddress'; let rpcparameters = []; @@ -2056,7 +2057,7 @@ async function sendToAddressPost(req, res) { async function setTxFee(req, res) { let { amount } = req.params; amount = amount || req.query.amount; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'setTxFee'; let rpcparameters = []; @@ -2078,7 +2079,7 @@ async function signMessage(req, res) { taddr = taddr || req.query.taddr; let { message } = req.params; message = message || req.query.message; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'signMessage'; let rpcparameters = []; @@ -2104,7 +2105,7 @@ async function signMessagePost(req, res) { const { taddr } = processedBody; const { message } = processedBody; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'signMessage'; let rpcparameters = []; @@ -2124,7 +2125,7 @@ async function signMessagePost(req, res) { async function zExportKey(req, res) { let { zaddr } = req.params; zaddr = zaddr || req.query.zaddr; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'z_exportkey'; let rpcparameters = []; @@ -2143,7 +2144,7 @@ async function zExportKey(req, res) { async function zExportViewingKey(req, res) { let { zaddr } = req.params; zaddr = zaddr || req.query.zaddr; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'z_exportviewingkey'; let rpcparameters = []; @@ -2164,7 +2165,7 @@ async function zGetBalance(req, res) { address = address || req.query.address; let { minconf } = req.params; minconf = minconf || req.query.minconf || 1; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'z_getbalance'; let rpcparameters = []; @@ -2182,7 +2183,7 @@ async function zGetBalance(req, res) { } async function zGetMigrationStatus(req, res) { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'z_getmigrationstatus'; @@ -2197,7 +2198,7 @@ async function zGetMigrationStatus(req, res) { async function zGetNewAddress(req, res) { let { type } = req.params; type = type || req.query.type || 'sapling'; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'z_getnewaddress'; const rpcparameters = [type]; @@ -2213,7 +2214,7 @@ async function zGetNewAddress(req, res) { async function zGetOperationResult(req, res) { let { operationid } = req.params; operationid = operationid || req.query.operationid || []; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { operationid = serviceHelper.ensureObject(operationid); const rpccall = 'z_getoperationresult'; @@ -2230,7 +2231,7 @@ async function zGetOperationResult(req, res) { async function zGetOperationStatus(req, res) { let { operationid } = req.params; operationid = operationid || req.query.operationid || []; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { operationid = serviceHelper.ensureObject(operationid); const rpccall = 'z_getoperationstatus'; @@ -2249,7 +2250,7 @@ async function zGetTotalBalance(req, res) { minconf = minconf || req.query.minconf || 1; let { includewatchonly } = req.params; includewatchonly = includewatchonly || req.query.includewatchonly || false; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { minconf = serviceHelper.ensureNumber(minconf); includewatchonly = serviceHelper.ensureBoolean(includewatchonly); @@ -2271,7 +2272,7 @@ async function zImportKey(req, res) { rescan = rescan || req.query.rescan || 'whenkeyisnew'; let { startheight } = req.params; startheight = startheight || req.query.startheight || 0; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'z_importkey'; let rpcparameters = []; @@ -2295,7 +2296,7 @@ async function zImportViewingKey(req, res) { rescan = rescan || req.query.rescan || 'whenkeyisnew'; let { startheight } = req.params; startheight = startheight || req.query.startheight || 0; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'z_importviewingkey'; let rpcparameters = []; @@ -2315,7 +2316,7 @@ async function zImportViewingKey(req, res) { async function zImportWallet(req, res) { let { filename } = req.params; filename = filename || req.query.filename; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'z_importwallet'; let rpcparameters = []; @@ -2334,7 +2335,7 @@ async function zImportWallet(req, res) { async function zListAddresses(req, res) { let { includewatchonly } = req.params; includewatchonly = includewatchonly || req.query.includewatchonly || false; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { includewatchonly = serviceHelper.ensureBoolean(includewatchonly); const rpccall = 'z_listaddresses'; @@ -2349,7 +2350,7 @@ async function zListAddresses(req, res) { } async function zListOperationIds(req, res) { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'z_listoperationids'; @@ -2366,7 +2367,7 @@ async function zListReceivedByAddress(req, res) { address = address || req.query.address; let { minconf } = req.params; minconf = minconf || req.query.minconf || 1; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'z_listreceivedbyaddress'; let rpcparameters = []; @@ -2392,7 +2393,7 @@ async function zListUnspent(req, res) { includewatchonly = includewatchonly || req.query.includewatchonly || false; let { addresses } = req.params; addresses = addresses || req.query.addresses; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'z_listunspent'; minconf = serviceHelper.ensureNumber(minconf); @@ -2425,7 +2426,7 @@ async function zMergeToAddress(req, res) { shieldedlimit = shieldedlimit || req.query.shieldedlimit || 20; // 0 for as many as can fit let { memo } = req.params; memo = memo || req.query.memo || ''; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'z_mergetoaddress'; let rpcparameters = []; @@ -2453,7 +2454,7 @@ async function zSendMany(req, res) { minconf = minconf || req.query.minconf || 1; let { fee } = req.params; fee = fee || req.query.fee || 0.0001; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'z_sendmany'; let rpcparameters = []; @@ -2484,7 +2485,7 @@ async function zSendManyPost(req, res) { let { fee } = processedBody; minconf = minconf || 1; fee = fee || 0.0001; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'z_sendmany'; let rpcparameters = []; @@ -2506,7 +2507,7 @@ async function zSendManyPost(req, res) { async function zSetMigration(req, res) { let { enabled } = req.params; enabled = enabled || req.query.enabled; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'z_setmigration'; let rpcparameters = []; @@ -2531,7 +2532,7 @@ async function zShieldCoinBase(req, res) { fee = fee || req.query.fee || 0.0001; let { limit } = req.params; limit = limit || req.query.limit || 50; // 0 for as many as can fit - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'z_shieldcoinbase'; let rpcparameters = []; @@ -2553,7 +2554,7 @@ async function zcBenchmark(req, res) { benchmarktype = benchmarktype || req.query.benchmarktype; let { samplecount } = req.params; samplecount = samplecount || req.query.samplecount; - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const rpccall = 'zcbenchmark'; let rpcparameters = []; @@ -2580,7 +2581,7 @@ async function zcRawJoinSplit(req, res) { vpubold = vpubold || req.query.vpubold; let { vpubnew } = req.params; vpubnew = vpubnew || req.query.vpubnew; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'zcrawjoinsplit'; let rpcparameters = []; @@ -2610,7 +2611,7 @@ async function zcRawJoinSplitPost(req, res) { const { vpubold } = processedBody; const { vpubnew } = processedBody; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'zcrawjoinsplit'; let rpcparameters = []; @@ -2629,7 +2630,7 @@ async function zcRawJoinSplitPost(req, res) { } async function zcRawKeygen(req, res) { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'zcrawkeygen'; response = await executeCall(rpccall); @@ -2645,7 +2646,7 @@ async function zcRawReceive(req, res) { zcsecretkey = zcsecretkey || req.query.zcsecretkey; let { encryptednote } = req.params; encryptednote = encryptednote || req.query.encryptednote; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'zcrawreceive'; let rpcparameters = []; @@ -2670,7 +2671,7 @@ async function zcRawReceivePost(req, res) { const { zcsecretkey } = processedBody; const { encryptednote } = processedBody; - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const rpccall = 'zcrawreceive'; let rpcparameters = []; @@ -2687,7 +2688,7 @@ async function zcRawReceivePost(req, res) { } async function zcSampleJoinSplit(req, res) { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const rpccall = 'zcsamplejoinsplit'; response = await executeCall(rpccall); @@ -2716,7 +2717,7 @@ async function getBenchStatus(req, res) { } async function startBenchmarkD(req, res) { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const rpccall = 'startzelbenchd'; response = await executeCall(rpccall); @@ -2728,7 +2729,7 @@ async function startBenchmarkD(req, res) { } async function stopBenchmarkD(req, res) { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const rpccall = 'stopzelbenchd'; response = await executeCall(rpccall); diff --git a/ZelBack/src/services/explorerService.js b/ZelBack/src/services/explorerService.js index a26524432..fe56d84e6 100644 --- a/ZelBack/src/services/explorerService.js +++ b/ZelBack/src/services/explorerService.js @@ -2,6 +2,7 @@ const config = require('config'); const log = require('../lib/log'); const serviceHelper = require('./serviceHelper'); +const verificationHelper = require('./verificationHelper'); const daemonService = require('./daemonService'); const appsService = require('./appsService'); @@ -988,7 +989,7 @@ async function checkBlockProcessingStopped(i, callback) { } async function stopBlockProcessing(req, res) { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const i = 0; checkBlockProcessingStopped(i, async (response) => { @@ -1002,7 +1003,7 @@ async function stopBlockProcessing(req, res) { } async function restartBlockProcessing(req, res) { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const i = 0; checkBlockProcessingStopped(i, async () => { @@ -1017,7 +1018,7 @@ async function restartBlockProcessing(req, res) { } async function reindexExplorer(req, res) { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { // stop block processing const i = 0; @@ -1061,7 +1062,7 @@ async function reindexExplorer(req, res) { async function rescanExplorer(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { // since what blockheight let { blockheight } = req.params; // we accept both help/command and help?command=getinfo diff --git a/ZelBack/src/services/fluxCommunication.js b/ZelBack/src/services/fluxCommunication.js index cceb4860b..f7bf37701 100644 --- a/ZelBack/src/services/fluxCommunication.js +++ b/ZelBack/src/services/fluxCommunication.js @@ -10,6 +10,7 @@ const path = require('path'); const util = require('util'); const log = require('../lib/log'); const serviceHelper = require('./serviceHelper'); +const verificationHelper = require('./verificationHelper'); const daemonService = require('./daemonService'); const benchmarkService = require('./benchmarkService'); const userconfig = require('../../../config/userconfig'); @@ -667,7 +668,7 @@ async function broadcastMessageToOutgoingFromUser(req, res) { if (data === undefined || data === null) { throw new Error('No message to broadcast attached.'); } - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { await broadcastMessageToOutgoing(data); @@ -699,7 +700,7 @@ async function broadcastMessageToOutgoingFromUserPost(req, res) { if (processedBody === undefined || processedBody === null || processedBody === '') { throw new Error('No message to broadcast attached.'); } - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { await broadcastMessageToOutgoing(processedBody); const message = serviceHelper.createSuccessMessage('Message successfully broadcasted to Flux network'); @@ -727,7 +728,7 @@ async function broadcastMessageToIncomingFromUser(req, res) { if (data === undefined || data === null) { throw new Error('No message to broadcast attached.'); } - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { await broadcastMessageToIncoming(data); @@ -759,7 +760,7 @@ async function broadcastMessageToIncomingFromUserPost(req, res) { if (processedBody === undefined || processedBody === null || processedBody === '') { throw new Error('No message to broadcast attached.'); } - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { await broadcastMessageToIncoming(processedBody); const message = serviceHelper.createSuccessMessage('Message successfully broadcasted to Flux network'); @@ -787,7 +788,7 @@ async function broadcastMessageFromUser(req, res) { if (data === undefined || data === null) { throw new Error('No message to broadcast attached.'); } - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { await broadcastMessageToOutgoing(data); @@ -820,7 +821,7 @@ async function broadcastMessageFromUserPost(req, res) { if (processedBody === undefined || processedBody === null || processedBody === '') { throw new Error('No message to broadcast attached.'); } - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { await broadcastMessageToOutgoing(processedBody); await broadcastMessageToIncoming(processedBody); @@ -1092,7 +1093,7 @@ async function addPeer(req, res) { const errMessage = serviceHelper.createErrorMessage(`Already connected to ${ip}`); return res.json(errMessage); } - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { initiateAndHandleConnection(ip); @@ -1189,7 +1190,7 @@ async function removePeer(req, res) { const errMessage = serviceHelper.createErrorMessage('No IP address specified.'); return res.json(errMessage); } - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const closeResponse = await closeConnection(ip); @@ -1207,7 +1208,7 @@ async function removeIncomingPeer(req, res, expressWS) { const errMessage = serviceHelper.createErrorMessage('No IP address specified.'); return res.json(errMessage); } - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const closeResponse = await closeIncomingConnection(ip, expressWS); @@ -1482,7 +1483,7 @@ async function allowPortApi(req, res) { const errMessage = serviceHelper.createErrorMessage('No Port address specified.'); return res.json(errMessage); } - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const portResponseOK = await allowPort(port); diff --git a/ZelBack/src/services/fluxService.js b/ZelBack/src/services/fluxService.js index 37c75fee0..a99522850 100644 --- a/ZelBack/src/services/fluxService.js +++ b/ZelBack/src/services/fluxService.js @@ -10,6 +10,7 @@ const fsPromises = fs.promises; const log = require('../lib/log'); const packageJson = require('../../../package.json'); const serviceHelper = require('./serviceHelper'); +const verificationHelper = require('./verificationHelper'); const daemonService = require('./daemonService'); const benchmarkService = require('./benchmarkService'); const appsService = require('./appsService'); @@ -26,7 +27,7 @@ async function fluxBackendFolder(req, res) { // eslint-disable-next-line consistent-return async function updateFlux(req, res) { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const nodedpath = path.join(__dirname, '../../../'); const exec = `cd ${nodedpath} && npm run updateflux`; @@ -46,7 +47,7 @@ async function updateFlux(req, res) { // eslint-disable-next-line consistent-return async function softUpdateFlux(req, res) { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const nodedpath = path.join(__dirname, '../../../'); const exec = `cd ${nodedpath} && npm run softupdate`; @@ -66,7 +67,7 @@ async function softUpdateFlux(req, res) { // eslint-disable-next-line consistent-return async function softUpdateFluxInstall(req, res) { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const nodedpath = path.join(__dirname, '../../../'); const exec = `cd ${nodedpath} && npm run softupdateinstall`; @@ -86,7 +87,7 @@ async function softUpdateFluxInstall(req, res) { // eslint-disable-next-line consistent-return async function hardUpdateFlux(req, res) { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const nodedpath = path.join(__dirname, '../../../'); const exec = `cd ${nodedpath} && npm run hardupdateflux`; @@ -106,7 +107,7 @@ async function hardUpdateFlux(req, res) { // eslint-disable-next-line consistent-return async function rebuildHome(req, res) { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const nodedpath = path.join(__dirname, '../../../'); const exec = `cd ${nodedpath} && npm run homebuild`; @@ -126,7 +127,7 @@ async function rebuildHome(req, res) { // eslint-disable-next-line consistent-return async function updateDaemon(req, res) { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const nodedpath = path.join(__dirname, '../../../helpers'); const exec = `cd ${nodedpath} && bash updateDaemon.sh`; @@ -146,7 +147,7 @@ async function updateDaemon(req, res) { // eslint-disable-next-line consistent-return async function updateBenchmark(req, res) { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const nodedpath = path.join(__dirname, '../../../helpers'); const exec = `cd ${nodedpath} && bash updateBenchmark.sh`; @@ -166,7 +167,7 @@ async function updateBenchmark(req, res) { // eslint-disable-next-line consistent-return async function startBenchmark(req, res) { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { let exec = 'zelbenchd -daemon'; if (fs.existsSync('/usr/local/bin/fluxbenchd')) { @@ -189,7 +190,7 @@ async function startBenchmark(req, res) { // eslint-disable-next-line consistent-return async function restartBenchmark(req, res) { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const nodedpath = path.join(__dirname, '../../../helpers'); const exec = `cd ${nodedpath} && bash restartBenchmark.sh`; @@ -210,7 +211,7 @@ async function restartBenchmark(req, res) { // eslint-disable-next-line consistent-return async function startDaemon(req, res) { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { let exec = 'zelcashd'; if (fs.existsSync('/usr/local/bin/fluxd')) { @@ -233,7 +234,7 @@ async function startDaemon(req, res) { // eslint-disable-next-line consistent-return async function restartDaemon(req, res) { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const nodedpath = path.join(__dirname, '../../../helpers'); const exec = `cd ${nodedpath} && bash restartDaemon.sh`; @@ -254,7 +255,7 @@ async function restartDaemon(req, res) { // eslint-disable-next-line consistent-return async function reindexDaemon(req, res) { - const authorized = await serviceHelper.verifyAdminSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const nodedpath = path.join(__dirname, '../../../helpers'); const exec = `cd ${nodedpath} && bash reindexDaemon.sh`; @@ -310,7 +311,7 @@ function getFluxKadena(req, res) { } async function daemonDebug(req, res) { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); return res.json(errMessage); @@ -324,7 +325,7 @@ async function daemonDebug(req, res) { } async function benchmarkDebug(req, res) { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); return res.json(errMessage); @@ -341,7 +342,7 @@ async function benchmarkDebug(req, res) { } async function tailDaemonDebug(req, res) { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const defaultDir = new fullnode.Config().defaultFolder(); const datadir = daemonService.getConfigValue('datadir') || defaultDir; @@ -363,7 +364,7 @@ async function tailDaemonDebug(req, res) { } async function tailBenchmarkDebug(req, res) { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const homeDirPath = path.join(__dirname, '../../../../'); const newBenchmarkPath = path.join(homeDirPath, '.fluxbenchmark'); @@ -397,7 +398,7 @@ async function fluxLog(res, filelog) { async function fluxErrorLog(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); res.json(errMessage); @@ -411,7 +412,7 @@ async function fluxErrorLog(req, res) { async function fluxWarnLog(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); res.json(errMessage); @@ -425,7 +426,7 @@ async function fluxWarnLog(req, res) { async function fluxInfoLog(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); res.json(errMessage); @@ -439,7 +440,7 @@ async function fluxInfoLog(req, res) { async function fluxDebugLog(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('adminandfluxteam', req); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (!authorized) { const errMessage = serviceHelper.errUnauthorizedMessage(); res.json(errMessage); @@ -452,7 +453,7 @@ async function fluxDebugLog(req, res) { } async function tailFluxLog(req, res, logfile) { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { const homeDirPath = path.join(__dirname, '../../../'); const filepath = `${homeDirPath}${logfile}.log`; @@ -474,7 +475,7 @@ async function tailFluxLog(req, res, logfile) { async function tailFluxErrorLog(req, res) { try { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { tailFluxLog(req, res, 'error'); } else { @@ -488,7 +489,7 @@ async function tailFluxErrorLog(req, res) { async function tailFluxWarnLog(req, res) { try { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { tailFluxLog(req, res, 'warn'); } else { @@ -502,7 +503,7 @@ async function tailFluxWarnLog(req, res) { async function tailFluxInfoLog(req, res) { try { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { tailFluxLog(req, res, 'info'); } else { @@ -516,7 +517,7 @@ async function tailFluxInfoLog(req, res) { async function tailFluxDebugLog(req, res) { try { - const authorized = await serviceHelper.verifyAdminAndFluxTeamSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('adminandfluxteam', req); if (authorized === true) { tailFluxLog(req, res, 'debug'); } else { @@ -639,7 +640,7 @@ async function getFluxInfo(req, res) { async function adjustCruxID(req, res) { try { - const authorized = await serviceHelper.verifyAdminSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { let { cruxid } = req.params; cruxid = cruxid || req.query.cruxid; @@ -680,7 +681,7 @@ async function adjustCruxID(req, res) { async function adjustKadenaAccount(req, res) { try { - const authorized = await serviceHelper.verifyAdminSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { let { account } = req.params; account = account || req.query.account; diff --git a/ZelBack/src/services/fluxshareService.js b/ZelBack/src/services/fluxshareService.js index 614a8226f..623e0fe0b 100644 --- a/ZelBack/src/services/fluxshareService.js +++ b/ZelBack/src/services/fluxshareService.js @@ -8,6 +8,7 @@ const archiver = require('archiver'); // eslint-disable-next-line import/no-extraneous-dependencies const util = require('util'); const serviceHelper = require('./serviceHelper'); +const verificationHelper = require('./verificationHelper'); const generalService = require('./generalService'); const log = require('../lib/log'); @@ -140,7 +141,7 @@ async function fluxShareSharedFiles() { async function fluxShareGetSharedFiles(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized) { const files = await fluxShareSharedFiles(); const resultsResponse = serviceHelper.createDataMessage(files); @@ -167,7 +168,7 @@ async function fluxShareGetSharedFiles(req, res) { async function fluxShareUnshareFile(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized) { let { file } = req.params; file = file || req.query.file; @@ -197,7 +198,7 @@ async function fluxShareUnshareFile(req, res) { async function fluxShareShareFile(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized) { let { file } = req.params; file = file || req.query.file; @@ -229,7 +230,7 @@ async function fluxShareDownloadFolder(req, res, authorized = false) { try { let auth = authorized; if (!auth) { - auth = await serviceHelper.verifyPrivilege('admin', req); + auth = await verificationHelper.verifyPrivilege('admin', req); } if (auth) { @@ -286,7 +287,7 @@ async function fluxShareDownloadFolder(req, res, authorized = false) { async function fluxShareDownloadFile(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized) { let { file } = req.params; file = file || req.query.file; @@ -366,7 +367,7 @@ async function fluxShareDownloadFile(req, res) { // oldpath is relative path to default fluxshare directory; newname is just a new name of folder/file async function fluxShareRename(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized) { let { oldpath } = req.params; oldpath = oldpath || req.query.oldpath; @@ -420,7 +421,7 @@ async function fluxShareRename(req, res) { async function fluxShareRemoveFile(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized) { let { file } = req.params; file = file || req.query.file; @@ -460,7 +461,7 @@ async function fluxShareRemoveFile(req, res) { async function fluxShareRemoveFolder(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized) { let { folder } = req.params; folder = folder || req.query.folder; @@ -496,7 +497,7 @@ async function fluxShareRemoveFolder(req, res) { async function fluxShareGetFolder(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized) { let { folder } = req.params; folder = folder || req.query.folder || ''; @@ -562,7 +563,7 @@ async function fluxShareGetFolder(req, res) { async function fluxShareCreateFolder(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized) { let { folder } = req.params; folder = folder || req.query.folder || ''; @@ -587,7 +588,7 @@ async function fluxShareCreateFolder(req, res) { async function fluxShareFileExists(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized) { let { file } = req.params; file = file || req.query.file; @@ -661,7 +662,7 @@ async function getSpaceAvailableForFluxShare() { async function fluxShareStorageStats(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized) { const spaceAvailableForFluxShare = await getSpaceAvailableForFluxShare(); let spaceUsedByFluxShare = getFluxShareSize(); @@ -686,7 +687,7 @@ async function fluxShareStorageStats(req, res) { async function fluxShareUpload(req, res) { try { - const authorized = await serviceHelper.verifyPrivilege('admin', req); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (!authorized) { throw new Error('Unauthorized. Access denied.'); } diff --git a/ZelBack/src/services/idService.js b/ZelBack/src/services/idService.js index 33a936d19..d6843c38d 100644 --- a/ZelBack/src/services/idService.js +++ b/ZelBack/src/services/idService.js @@ -6,6 +6,7 @@ const os = require('os'); const userconfig = require('../../../config/userconfig'); const log = require('../lib/log'); const serviceHelper = require('./serviceHelper'); +const verificationHelper = require('./verificationHelper'); const generalService = require('./generalService'); const dockerService = require('./dockerService'); const fluxCommunication = require('./fluxCommunication'); @@ -321,7 +322,7 @@ async function provideSign(req, res) { async function activeLoginPhrases(req, res) { try { - const authorized = await serviceHelper.verifyAdminSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const db = serviceHelper.databaseConnection(); @@ -349,7 +350,7 @@ async function activeLoginPhrases(req, res) { async function loggedUsers(req, res) { try { - const authorized = await serviceHelper.verifyAdminSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const db = serviceHelper.databaseConnection(); const database = db.db(config.database.local.database); @@ -372,7 +373,7 @@ async function loggedUsers(req, res) { async function loggedSessions(req, res) { try { - const authorized = await serviceHelper.verifyUserSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('user', req); if (authorized === true) { const db = serviceHelper.databaseConnection(); @@ -398,7 +399,7 @@ async function loggedSessions(req, res) { async function logoutCurrentSession(req, res) { try { - const authorized = await serviceHelper.verifyUserSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('user', req); if (authorized === true) { const auth = serviceHelper.ensureObject(req.headers.zelidauth); const db = serviceHelper.databaseConnection(); @@ -428,7 +429,7 @@ async function logoutSpecificSession(req, res) { }); req.on('end', async () => { try { - const authorized = await serviceHelper.verifyUserSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('user', req); if (authorized === true) { const processedBody = serviceHelper.ensureObject(body); const obtainedLoginPhrase = processedBody.loginPhrase; @@ -458,7 +459,7 @@ async function logoutSpecificSession(req, res) { async function logoutAllSessions(req, res) { try { - const authorized = await serviceHelper.verifyUserSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('user', req); if (authorized === true) { const auth = serviceHelper.ensureObject(req.headers.zelidauth); const db = serviceHelper.databaseConnection(); @@ -482,7 +483,7 @@ async function logoutAllSessions(req, res) { async function logoutAllUsers(req, res) { try { - const authorized = await serviceHelper.verifyAdminSession(req.headers); + const authorized = await verificationHelper.verifyPrivilege('admin', req); if (authorized === true) { const db = serviceHelper.databaseConnection(); const database = db.db(config.database.local.database); @@ -664,25 +665,27 @@ async function checkLoggedUser(req, res) { if (!signature) { throw new Error('No user ZelID signature specificed'); } - const headers = { - zelidauth: { - zelid, - signature, + const request = { + headers: { + zelidauth: { + zelid, + signature, + }, }, }; - const isAdmin = await serviceHelper.verifyAdminSession(headers); + const isAdmin = await verificationHelper.verifyPrivilege('admin', request); if (isAdmin) { const message = serviceHelper.createSuccessMessage('admin'); res.json(message); return; } - const isFluxTeam = await serviceHelper.verifyFluxTeamSession(headers); + const isFluxTeam = await verificationHelper.verifyPrivilege('fluxteam', request); if (isFluxTeam) { const message = serviceHelper.createSuccessMessage('fluxteam'); res.json(message); return; } - const isUser = await serviceHelper.verifyUserSession(headers); + const isUser = await verificationHelper.verifyPrivilege('user', request); if (isUser) { const message = serviceHelper.createSuccessMessage('user'); res.json(message); diff --git a/ZelBack/src/services/serviceHelper.js b/ZelBack/src/services/serviceHelper.js index c03476d9d..ec0587322 100644 --- a/ZelBack/src/services/serviceHelper.js +++ b/ZelBack/src/services/serviceHelper.js @@ -7,7 +7,6 @@ const zeltrezjs = require('zeltrezjs'); const { randomBytes } = require('crypto'); const qs = require('qs'); -const userconfig = require('../../../config/userconfig'); const log = require('../lib/log'); const { MongoClient } = mongodb; @@ -220,259 +219,6 @@ async function getApplicationOwner(appName) { return null; } -// Verification functions -async function verifyAdminSession(headers) { - if (headers && headers.zelidauth) { - const auth = ensureObject(headers.zelidauth); - if (auth.zelid && auth.signature) { - if (auth.zelid === userconfig.initial.zelid) { - const db = databaseConnection(); - const database = db.db(config.database.local.database); - const collection = config.database.local.collections.loggedUsers; - const query = { $and: [{ signature: auth.signature }, { zelid: auth.zelid }] }; - const projection = {}; - const result = await findOneInDatabase(database, collection, query, projection); - const loggedUser = result; - // console.log(result) - if (loggedUser) { - // check if signature corresponds to message with that zelid - let valid = false; - try { - valid = bitcoinMessage.verify(loggedUser.loginPhrase, auth.zelid, auth.signature); - } catch (error) { - return false; - } - // console.log(valid) - if (valid) { - // now we know this is indeed a logged admin - return true; - } - } else { - return false; - } - } else { - return false; - } - } else { - return false; - } - } - return false; -} - -async function verifyUserSession(headers) { - if (headers && headers.zelidauth) { - const auth = ensureObject(headers.zelidauth); - if (auth.zelid && auth.signature) { - const db = databaseConnection(); - const database = db.db(config.database.local.database); - const collection = config.database.local.collections.loggedUsers; - const query = { $and: [{ signature: auth.signature }, { zelid: auth.zelid }] }; - const projection = {}; - const result = await findOneInDatabase(database, collection, query, projection); - const loggedUser = result; - // console.log(result) - if (loggedUser) { - // check if signature corresponds to message with that zelid - let valid = false; - try { - valid = bitcoinMessage.verify(loggedUser.loginPhrase, auth.zelid, auth.signature); - } catch (error) { - return false; - } - // console.log(valid) - if (valid) { - // now we know this is indeed a logged admin - return true; - } - } else { - return false; - } - } else { - return false; - } - } - return false; -} - -async function verifyFluxTeamSession(headers) { - if (headers && headers.zelidauth) { - const auth = ensureObject(headers.zelidauth); - if (auth.zelid && auth.signature) { - if (auth.zelid === config.fluxTeamZelId) { - const db = databaseConnection(); - const database = db.db(config.database.local.database); - const collection = config.database.local.collections.loggedUsers; - const query = { $and: [{ signature: auth.signature }, { zelid: auth.zelid }] }; - const projection = {}; - const result = await findOneInDatabase(database, collection, query, projection); - const loggedUser = result; - if (loggedUser) { - // check if signature corresponds to message with that zelid - let valid = false; - try { - valid = bitcoinMessage.verify(loggedUser.loginPhrase, auth.zelid, auth.signature); - } catch (error) { - return false; - } - if (valid) { - // now we know this is indeed a logged fluxteam - return true; - } - } else { - return false; - } - } else { - return false; - } - } else { - return false; - } - } - return false; -} - -async function verifyAdminAndFluxTeamSession(headers) { - if (headers && headers.zelidauth) { - const auth = ensureObject(headers.zelidauth); - if (auth.zelid && auth.signature) { - if (auth.zelid === config.fluxTeamZelId || auth.zelid === userconfig.initial.zelid) { // admin is considered as fluxTeam - const db = databaseConnection(); - const database = db.db(config.database.local.database); - const collection = config.database.local.collections.loggedUsers; - const query = { $and: [{ signature: auth.signature }, { zelid: auth.zelid }] }; - const projection = {}; - const result = await findOneInDatabase(database, collection, query, projection); - const loggedUser = result; - if (loggedUser) { - // check if signature corresponds to message with that zelid - let valid = false; - try { - valid = bitcoinMessage.verify(loggedUser.loginPhrase, auth.zelid, auth.signature); - } catch (error) { - return false; - } - if (valid) { - // now we know this is indeed a logged admin or fluxteam - return true; - } - } else { - return false; - } - } else { - return false; - } - } else { - return false; - } - } - return false; -} - -async function verifyAppOwnerSession(headers, appName) { - if (headers && headers.zelidauth && appName) { - const auth = ensureObject(headers.zelidauth); - if (auth.zelid && auth.signature) { - const ownerZelID = await getApplicationOwner(appName); - if (auth.zelid === ownerZelID) { - const db = databaseConnection(); - const database = db.db(config.database.local.database); - const collection = config.database.local.collections.loggedUsers; - const query = { $and: [{ signature: auth.signature }, { zelid: auth.zelid }] }; - const projection = {}; - const result = await findOneInDatabase(database, collection, query, projection); - const loggedUser = result; - if (loggedUser) { - // check if signature corresponds to message with that zelid - let valid = false; - try { - valid = bitcoinMessage.verify(loggedUser.loginPhrase, auth.zelid, auth.signature); - } catch (error) { - return false; - } - if (valid) { - // now we know this is indeed a logged application owner - return true; - } - } else { - return false; - } - } else { - return false; - } - } else { - return false; - } - } - return false; -} - -async function verifyAppOwnerOrHigherSession(headers, appName) { - if (headers && headers.zelidauth && appName) { - const auth = ensureObject(headers.zelidauth); - if (auth.zelid && auth.signature) { - const ownerZelID = await getApplicationOwner(appName); - if (auth.zelid === ownerZelID || auth.zelid === config.fluxTeamZelId || auth.zelid === userconfig.initial.zelid) { - const db = databaseConnection(); - const database = db.db(config.database.local.database); - const collection = config.database.local.collections.loggedUsers; - const query = { $and: [{ signature: auth.signature }, { zelid: auth.zelid }] }; - const projection = {}; - const result = await findOneInDatabase(database, collection, query, projection); - const loggedUser = result; - if (loggedUser) { - // check if signature corresponds to message with that zelid - let valid = false; - try { - valid = bitcoinMessage.verify(loggedUser.loginPhrase, auth.zelid, auth.signature); - } catch (error) { - return false; - } - if (valid) { - // now we know this is indeed a logged application owner - return true; - } - } else { - return false; - } - } else { - return false; - } - } else { - return false; - } - } - return false; -} - -async function verifyPrivilege(privilege, req, appName) { - let authorized; - switch (privilege) { - case 'admin': - authorized = await verifyAdminSession(req.headers); - break; - case 'fluxteam': - authorized = await verifyFluxTeamSession(req.headers); - break; - case 'adminandfluxteam': - authorized = await verifyAdminAndFluxTeamSession(req.headers); - break; - case 'appownerabove': - authorized = await verifyAppOwnerOrHigherSession(req.headers, appName); - break; - case 'appowner': - authorized = await verifyAppOwnerSession(req.headers, appName); - break; - case 'user': - authorized = await verifyUserSession(req.headers); - break; - default: - authorized = false; - break; - } - return authorized; -} - function verifyZelID(address) { let isValid = false; try { @@ -585,13 +331,6 @@ module.exports = { removeDocumentsFromCollection, dropCollection, collectionStats, - verifyAdminSession, - verifyUserSession, - verifyFluxTeamSession, - verifyAdminAndFluxTeamSession, - verifyAppOwnerOrHigherSession, - verifyAppOwnerSession, - verifyPrivilege, signMessage, verifyMessage, createDataMessage, diff --git a/tests/unit/serviceHelper.test.js b/tests/unit/serviceHelper.test.js index 64af5862f..ed535d6a6 100644 --- a/tests/unit/serviceHelper.test.js +++ b/tests/unit/serviceHelper.test.js @@ -419,7 +419,7 @@ describe('serviceHelper tests', () => { }); }); - describe.only('deleteLoginPhrase tests', () => { + describe('deleteLoginPhrase tests', () => { const query = { "loginPhrase": { $eq: "1644935809116x5fpl862o5fnyl29vfpmd9vzmgaddlgqbud8cxks8hj" } }; const loginPhrase = { "_id": ObjectId("620bba81c04b4966674013a4"), From a8f7182112010a608514a937d060307c086414e4 Mon Sep 17 00:00:00 2001 From: TheTrunk Date: Wed, 23 Feb 2022 21:15:58 +0700 Subject: [PATCH 31/41] Update package.json --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 2b4b2d535..c9da8371b 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,6 @@ "node-df": "~0.1.4", "nodemon": "~2.0.15", "path": "~0.12.7", - "qs": "~6.10.2", "qs": "~6.10.3", "store": "~2.0.12", "stream": "~0.0.2", From 8b08f1d7832b014ca150d5e8c3b8545a000da51c Mon Sep 17 00:00:00 2001 From: TheTrunk Date: Wed, 23 Feb 2022 22:29:10 +0700 Subject: [PATCH 32/41] use lint for tests lint adjust github action to run service test update default test config --- .eslintignore | 2 +- .github/workflows/nodejs.yml | 5 +- tests/ZelBack/apiTests.js | 20 +- tests/ZelBack/appsService.js | 414 +++++++++++---------- tests/ZelBack/daemonService.js | 6 +- tests/ZelBack/fluxCommunication.js | 33 +- tests/unit/.eslintrc.js | 3 + tests/unit/globalconfig/default.js | 7 +- tests/unit/serviceHelper.test.js | 96 +++-- tests/unit/verificationHelper.test.js | 18 +- tests/unit/verificationHelperUtils.test.js | 314 ++++++++-------- 11 files changed, 462 insertions(+), 456 deletions(-) diff --git a/.eslintignore b/.eslintignore index 81ab89ac7..ed35f5c3c 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,5 +2,5 @@ /config/userconfig.js /lib/zelcashrpc/ /lib/daemonrpc/ -/tests/ +/tests/e2e/ /ZelApps/ \ No newline at end of file diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index d88666f46..48d620078 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -5,11 +5,11 @@ on: [push] jobs: build: - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 strategy: matrix: - node-version: [12.x] + node-version: [14.x] services: mongodb: @@ -29,5 +29,6 @@ jobs: npm run ciconfig npm run homebuild npm run test:zelback + npm run test:zelback:unit env: CI: true diff --git a/tests/ZelBack/apiTests.js b/tests/ZelBack/apiTests.js index dcdd32bd3..75097cb70 100644 --- a/tests/ZelBack/apiTests.js +++ b/tests/ZelBack/apiTests.js @@ -2,28 +2,30 @@ process.env.NODE_CONFIG_DIR = `${process.cwd()}/ZelBack/config/`; const request = require('supertest'); const config = require('config'); const chai = require('chai'); -const expect = chai.expect; -const app = require('../../ZelBack/src/lib/server.js'); +const app = require('../../ZelBack/src/lib/server'); const log = require('../../ZelBack/src/lib/log'); +const serviceHelper = require('../../ZelBack/src/services/serviceHelper'); + const packageJson = require('../../package.json'); + +const { expect } = chai; const { version } = packageJson; const server = app.listen(config.server.apiport, () => { log.info(`Flux listening on port ${config.server.apiport}!`); }); -describe('loading express', function () { - after(function (done) { +describe('loading express', () => { + after((done) => { server.close(done); setTimeout(() => { process.exit(); }, 10000); }); before(async () => { - const serviceHelper = require('../../ZelBack/src/services/serviceHelper'); await serviceHelper.initiateDB(); }); - it('/flux/version', function testSlash(done) { + it('/flux/version', (done) => { request(server) .get('/flux/version') .expect(200) @@ -35,12 +37,12 @@ describe('loading express', function () { return done(); }); }); - it('non-existing-path', function testPath(done) { + it('non-existing-path', (done) => { request(server) .get('/foo/bar') .expect(404, done); }); - it('/id/loginphrase', function testSlash(done) { + it('/id/loginphrase', (done) => { request(server) .get('/id/loginphrase') .expect(200) @@ -53,4 +55,4 @@ describe('loading express', function () { return done(); }); }); -}); \ No newline at end of file +}); diff --git a/tests/ZelBack/appsService.js b/tests/ZelBack/appsService.js index c90842cd5..aca9af181 100644 --- a/tests/ZelBack/appsService.js +++ b/tests/ZelBack/appsService.js @@ -1,8 +1,10 @@ +/* eslint-disable func-names */ process.env.NODE_CONFIG_DIR = `${process.cwd()}/ZelBack/config/`; -const appService = require("../../ZelBack/src/services/appsService"); -const generalService = require("../../ZelBack/src/services/generalService"); const chai = require('chai'); -const expect = chai.expect; +const appService = require('../../ZelBack/src/services/appsService'); +const generalService = require('../../ZelBack/src/services/generalService'); + +const { expect } = chai; // describe('checkAndRequestApp', () => { // it('signs checks and requests app properly', async () => { @@ -18,226 +20,226 @@ const expect = chai.expect; describe('checkHWParameters', () => { it('Verifies HW specs are correct', () => { const fluxAppSpecs = { - "version": 2, - "name": "FoldingAtHome", - "description": "Folding @ Home is cool :)", - "repotag": "yurinnick/folding-at-home:latest", - "owner": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", - "ports": [30001], - "containerPorts": [7396], - "domains": [''], - "enviromentParameters": [ - "USER=foldingUser", - "TEAM=262156", - "ENABLE_GPU=false", - "ENABLE_SMP=true" + version: 2, + name: 'FoldingAtHome', + description: 'Folding @ Home is cool :)', + repotag: 'yurinnick/folding-at-home:latest', + owner: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + ports: [30001], + containerPorts: [7396], + domains: [''], + enviromentParameters: [ + 'USER=foldingUser', + 'TEAM=262156', + 'ENABLE_GPU=false', + 'ENABLE_SMP=true', ], - "commands": [ - "--allow", - "0/0", - "--web-allow", - "0/0" + commands: [ + '--allow', + '0/0', + '--web-allow', + '0/0', ], - "containerData": "/config", - "cpu": 0.5, - "ram": 500, - "hdd": 5, - "tiered": true, - "cpubasic": 0.5, - "cpusuper": 1, - "cpubamf": 2, - "rambasic": 500, - "ramsuper": 1000, - "rambamf": 2000, - "hddbasic": 5, - "hddsuper": 5, - "hddbamf": 5 + containerData: '/config', + cpu: 0.5, + ram: 500, + hdd: 5, + tiered: true, + cpubasic: 0.5, + cpusuper: 1, + cpubamf: 2, + rambasic: 500, + ramsuper: 1000, + rambamf: 2000, + hddbasic: 5, + hddsuper: 5, + hddbamf: 5, }; expect(appService.checkHWParameters(fluxAppSpecs)).to.be.equal(true); }); it('Verifies HW specs are badly asssigned', () => { const fluxAppSpecs = { - "version": 2, - "name": "FoldingAtHome", - "description": "Folding @ Home is cool :)", - "repotag": "yurinnick/folding-at-home:latest", - "owner": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", - "ports": [30001], - "containerPorts": [7396], - "domains": [''], - "enviromentParameters": [ - "USER=foldingUser", - "TEAM=262156", - "ENABLE_GPU=false", - "ENABLE_SMP=true" + version: 2, + name: 'FoldingAtHome', + description: 'Folding @ Home is cool :)', + repotag: 'yurinnick/folding-at-home:latest', + owner: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + ports: [30001], + containerPorts: [7396], + domains: [''], + enviromentParameters: [ + 'USER=foldingUser', + 'TEAM=262156', + 'ENABLE_GPU=false', + 'ENABLE_SMP=true', ], - "commands": [ - "--allow", - "0/0", - "--web-allow", - "0/0" + commands: [ + '--allow', + '0/0', + '--web-allow', + '0/0', ], - "containerData": "/config", - "cpu": 0.5, - "ram": 'badly assigned', - "hdd": 5, - "tiered": true, - "cpubasic": 0.5, - "cpusuper": 1, - "cpubamf": 2, - "rambasic": 500, - "ramsuper": 1000, - "rambamf": 2000, - "hddbasic": 5, - "hddsuper": 5, - "hddbamf": 5 + containerData: '/config', + cpu: 0.5, + ram: 'badly assigned', + hdd: 5, + tiered: true, + cpubasic: 0.5, + cpusuper: 1, + cpubamf: 2, + rambasic: 500, + ramsuper: 1000, + rambamf: 2000, + hddbasic: 5, + hddsuper: 5, + hddbamf: 5, }; - const specs = function () { appService.checkHWParameters(fluxAppSpecs) }; + const specs = function () { appService.checkHWParameters(fluxAppSpecs); }; expect(specs).to.throw(); }); it('Verifies HW specs are missing', () => { const fluxAppSpecs = { - "version": 2, - "name": "FoldingAtHome", - "description": "Folding @ Home is cool :)", - "repotag": "yurinnick/folding-at-home:latest", - "owner": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", - "ports": [30001], - "containerPorts": [7396], - "domains": [''], - "enviromentParameters": [ - "USER=foldingUser", - "TEAM=262156", - "ENABLE_GPU=false", - "ENABLE_SMP=true", + version: 2, + name: 'FoldingAtHome', + description: 'Folding @ Home is cool :)', + repotag: 'yurinnick/folding-at-home:latest', + owner: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + ports: [30001], + containerPorts: [7396], + domains: [''], + enviromentParameters: [ + 'USER=foldingUser', + 'TEAM=262156', + 'ENABLE_GPU=false', + 'ENABLE_SMP=true', ], - "commands": [ - "--allow", - "0/0", - "--web-allow", - "0/0" + commands: [ + '--allow', + '0/0', + '--web-allow', + '0/0', ], - "containerData": "/config", - "cpu": null, - "ram": 4000, - "hdd": 5, - "tiered": true, - "cpubasic": 0.5, - "cpusuper": 1, - "cpubamf": 2, - "rambasic": 500, - "ramsuper": 1000, - "rambamf": 2000, - "hddbasic": 5, - "hddsuper": 5, - "hddbamf": 21 + containerData: '/config', + cpu: null, + ram: 4000, + hdd: 5, + tiered: true, + cpubasic: 0.5, + cpusuper: 1, + cpubamf: 2, + rambasic: 500, + ramsuper: 1000, + rambamf: 2000, + hddbasic: 5, + hddsuper: 5, + hddbamf: 21, }; - const hwSpecs = function () { appService.checkHWParameters(fluxAppSpecs) }; + const hwSpecs = function () { appService.checkHWParameters(fluxAppSpecs); }; expect(hwSpecs).to.throw(); }); it('Verifies repository exists or is not correct', async () => { const fluxAppSpecs = { - "repotag": "yurinnick/folding-at-home:latest", - "repotagB": "yurinnick/folding-at-home:latestaaa", + repotag: 'yurinnick/folding-at-home:latest', + repotagB: 'yurinnick/folding-at-home:latestaaa', }; const repA = await appService.verifyRepository(fluxAppSpecs.repotag); expect(repA).to.be.equal(true); const repB = await appService.verifyRepository(fluxAppSpecs.repotagB).catch((error) => { - expect(error.message).to.be.equal('Repository yurinnick/folding-at-home:latestaaa is not found on docker hub in expected format') + expect(error.message).to.be.equal('Repository yurinnick/folding-at-home:latestaaa is not found on docker hub in expected format'); }); - expect(repB).to.be.equal(undefined) + expect(repB).to.be.equal(undefined); // expect(appService.verifyAppSpecifications(fluxAppSpecs)).to.not.throw(); }); it('Message Hash is correctly calculated', async () => { const fluxAppSpecs = { - "version": 2, - "name": "FoldingAtHome", - "description": "Folding @ Home is cool :)", - "repotag": "yurinnick/folding-at-home:latest", - "owner": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", - "ports": [30001], - "containerPorts": [7396], - "domains": [''], - "enviromentParameters": [ - "USER=foldingUser", - "TEAM=262156", - "ENABLE_GPU=false", - "ENABLE_SMP=true" + version: 2, + name: 'FoldingAtHome', + description: 'Folding @ Home is cool :)', + repotag: 'yurinnick/folding-at-home:latest', + owner: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + ports: [30001], + containerPorts: [7396], + domains: [''], + enviromentParameters: [ + 'USER=foldingUser', + 'TEAM=262156', + 'ENABLE_GPU=false', + 'ENABLE_SMP=true', ], - "commands": [ - "--allow", - "0/0", - "--web-allow", - "0/0" + commands: [ + '--allow', + '0/0', + '--web-allow', + '0/0', ], - "containerData": "/config", - "cpu": 0.5, - "ram": 500, - "hdd": 5, - "tiered": true, - "cpubasic": 0.5, - "cpusuper": 1, - "cpubamf": 2, - "rambasic": 500, - "ramsuper": 1000, - "rambamf": 2000, - "hddbasic": 5, - "hddsuper": 5, - "hddbamf": 5 + containerData: '/config', + cpu: 0.5, + ram: 500, + hdd: 5, + tiered: true, + cpubasic: 0.5, + cpusuper: 1, + cpubamf: 2, + rambasic: 500, + ramsuper: 1000, + rambamf: 2000, + hddbasic: 5, + hddsuper: 5, + hddbamf: 5, }; const type = 'fluxappregister'; const version = 1; - const timestamp = 1592988806887 + const timestamp = 1592988806887; const signature = 'H7AP+VrFUTrmi+DqG8x0nllBFXB+oD09AkSE/JEpemeOTzMglftjTtPaEY3rMW/FUezEiad0WZNgxiInFrUn6S8='; - const messageHash = 'c509eae87618e0c4c40106d3c515923d7611070bcafad261de9520238617c972' + const messageHash = 'c509eae87618e0c4c40106d3c515923d7611070bcafad261de9520238617c972'; const message = type + version + JSON.stringify(fluxAppSpecs) + timestamp + signature; expect(await generalService.messageHash(message)).to.be.equal(messageHash); }); it('Message Hash is correctly verified', async () => { const fluxAppSpecs = { - "version": 2, - "name": "FoldingAtHome", - "description": "Folding @ Home is cool :)", - "repotag": "yurinnick/folding-at-home:latest", - "owner": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", - "ports": [30001], - "containerPorts": [7396], - "domains": [''], - "enviromentParameters": [ - "USER=foldingUser", - "TEAM=262156", - "ENABLE_GPU=false", - "ENABLE_SMP=true" + version: 2, + name: 'FoldingAtHome', + description: 'Folding @ Home is cool :)', + repotag: 'yurinnick/folding-at-home:latest', + owner: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + ports: [30001], + containerPorts: [7396], + domains: [''], + enviromentParameters: [ + 'USER=foldingUser', + 'TEAM=262156', + 'ENABLE_GPU=false', + 'ENABLE_SMP=true', ], - "commands": [ - "--allow", - "0/0", - "--web-allow", - "0/0" + commands: [ + '--allow', + '0/0', + '--web-allow', + '0/0', ], - "containerData": "/config", - "cpu": 0.5, - "ram": 500, - "hdd": 5, - "tiered": true, - "cpubasic": 0.5, - "cpusuper": 1, - "cpubamf": 2, - "rambasic": 500, - "ramsuper": 1000, - "rambamf": 2000, - "hddbasic": 5, - "hddsuper": 5, - "hddbamf": 5 + containerData: '/config', + cpu: 0.5, + ram: 500, + hdd: 5, + tiered: true, + cpubasic: 0.5, + cpusuper: 1, + cpubamf: 2, + rambasic: 500, + ramsuper: 1000, + rambamf: 2000, + hddbasic: 5, + hddsuper: 5, + hddbamf: 5, }; const type = 'fluxappregister'; const version = 1; - const timestamp = 1592988806887 + const timestamp = 1592988806887; const signature = 'H7AP+VrFUTrmi+DqG8x0nllBFXB+oD09AkSE/JEpemeOTzMglftjTtPaEY3rMW/FUezEiad0WZNgxiInFrUn6S8='; const messageHash = 'c509eae87618e0c4c40106d3c515923d7611070bcafad261de9520238617c972'; const message = { @@ -247,50 +249,50 @@ describe('checkHWParameters', () => { appSpecifications: fluxAppSpecs, timestamp, signature, - } + }; expect(await appService.verifyAppHash(message)).to.be.equal(true); }); it('Message is correctly signed', async () => { const fluxAppSpecs = { - "version": 2, - "name": "FoldingAtHome", - "description": "Folding @ Home is cool :)", - "repotag": "yurinnick/folding-at-home:latest", - "owner": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", - "ports": [30001], - "containerPorts": [7396], - "domains": [''], - "enviromentParameters": [ - "USER=foldingUser", - "TEAM=262156", - "ENABLE_GPU=false", - "ENABLE_SMP=true" + version: 2, + name: 'FoldingAtHome', + description: 'Folding @ Home is cool :)', + repotag: 'yurinnick/folding-at-home:latest', + owner: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', + ports: [30001], + containerPorts: [7396], + domains: [''], + enviromentParameters: [ + 'USER=foldingUser', + 'TEAM=262156', + 'ENABLE_GPU=false', + 'ENABLE_SMP=true', ], - "commands": [ - "--allow", - "0/0", - "--web-allow", - "0/0" + commands: [ + '--allow', + '0/0', + '--web-allow', + '0/0', ], - "containerData": "/config", - "cpu": 0.5, - "ram": 500, - "hdd": 5, - "tiered": true, - "cpubasic": 0.5, - "cpusuper": 1, - "cpubamf": 2, - "rambasic": 500, - "ramsuper": 1000, - "rambamf": 2000, - "hddbasic": 5, - "hddsuper": 5, - "hddbamf": 5 + containerData: '/config', + cpu: 0.5, + ram: 500, + hdd: 5, + tiered: true, + cpubasic: 0.5, + cpusuper: 1, + cpubamf: 2, + rambasic: 500, + ramsuper: 1000, + rambamf: 2000, + hddbasic: 5, + hddsuper: 5, + hddbamf: 5, }; const type = 'fluxappregister'; const version = 1; - const timestamp = 1592988806887 + const timestamp = 1592988806887; const messageToVerify = type + version + JSON.stringify(fluxAppSpecs) + timestamp; console.log(messageToVerify); const signature = 'H7AP+VrFUTrmi+DqG8x0nllBFXB+oD09AkSE/JEpemeOTzMglftjTtPaEY3rMW/FUezEiad0WZNgxiInFrUn6S8='; diff --git a/tests/ZelBack/daemonService.js b/tests/ZelBack/daemonService.js index e5d7e1b71..e8df31371 100644 --- a/tests/ZelBack/daemonService.js +++ b/tests/ZelBack/daemonService.js @@ -1,7 +1,9 @@ +/* eslint-disable max-len */ process.env.NODE_CONFIG_DIR = `${process.cwd()}/ZelBack/config/`; const axios = require('axios'); const chai = require('chai'); -const expect = chai.expect; + +const { expect } = chai; describe('Daemon Service calls', () => { it('correctly communicates with Flux and obtains data from a Daemon service', () => { @@ -14,5 +16,3 @@ describe('Daemon Service calls', () => { }); }).timeout(5000); }); - - diff --git a/tests/ZelBack/fluxCommunication.js b/tests/ZelBack/fluxCommunication.js index 471190a9a..9cac03228 100644 --- a/tests/ZelBack/fluxCommunication.js +++ b/tests/ZelBack/fluxCommunication.js @@ -1,10 +1,10 @@ process.env.NODE_CONFIG_DIR = `${process.cwd()}/ZelBack/config/`; -const communication = require('../../ZelBack/src/services/fluxCommunication'); -const fluxList = require('./data/listfluxnodes.json') const chai = require('chai'); -const expect = chai.expect; -const qs = require('qs'); const WebSocket = require('ws'); +const communication = require('../../ZelBack/src/services/fluxCommunication'); +const fluxList = require('./data/listfluxnodes.json'); + +const { expect } = chai; describe('getFluxMessageSignature', () => { it('correctly signs Flux message', async () => { @@ -24,8 +24,8 @@ describe('getFluxMessageSignature', () => { const badPubKey = '074eb4690689bb408139249eda7f361b7881c4254ccbe303d3b4d58c2b48897d0f070b44944941998551f9ea0e1befd96f13adf171c07c885e62d0c2af56d3dab'; const data = { app: 'testapp', - data: 'test' - } + data: 'test', + }; const message = JSON.stringify(data); const messageToSign = version + message + timeStamp; const signature = await communication.getFluxMessageSignature(messageToSign, privKey); @@ -35,8 +35,8 @@ describe('getFluxMessageSignature', () => { pubKey, timestamp: timeStamp, data, - signature - } + signature, + }; const validRequest = await communication.verifyOriginalFluxBroadcast(dataToSend, fluxList); expect(validRequest).to.equal(true); const dataToSend2 = { @@ -44,8 +44,8 @@ describe('getFluxMessageSignature', () => { pubKey, timestamp: timeStamp - 500000, data, - signature - } + signature, + }; const invalidRequest = await communication.verifyOriginalFluxBroadcast(dataToSend2, fluxList); expect(invalidRequest).to.equal(false); const dataToSend3 = { @@ -53,8 +53,8 @@ describe('getFluxMessageSignature', () => { pubKey: badPubKey, timestamp: timeStamp, data, - signature - } + signature, + }; const invalidRequest2 = await communication.verifyOriginalFluxBroadcast(dataToSend3, fluxList); expect(invalidRequest2).to.equal(false); const dataToSend4 = { @@ -62,8 +62,8 @@ describe('getFluxMessageSignature', () => { pubKey, timestamp: timeStamp, data, - signature: 'abc' - } + signature: 'abc', + }; const invalidRequest3 = await communication.verifyOriginalFluxBroadcast(dataToSend4, fluxList); expect(invalidRequest3).to.equal(false); }).timeout(5000); @@ -73,10 +73,11 @@ describe('getFluxMessageSignature', () => { const privKey = '5JTeg79dTLzzHXoJPALMWuoGDM8QmLj4n5f6MeFjx8dzsirvjAh'; const messageToSend = await communication.serialiseAndSignFluxBroadcast(data, privKey); console.log(messageToSend); - const wsuri = `ws://62.171.163.150:16127/ws/flux/`; // locally running 127.0.0.1 + const wsuri = 'ws://62.171.163.150:16127/ws/flux/'; // locally running 127.0.0.1 const websocket = new WebSocket(wsuri); websocket.on('open', (msg) => { + console.log(msg); websocket.send(messageToSend); }); websocket.on('message', (msg) => { @@ -86,4 +87,4 @@ describe('getFluxMessageSignature', () => { websocket.close(1000); }); }); -}); \ No newline at end of file +}); diff --git a/tests/unit/.eslintrc.js b/tests/unit/.eslintrc.js index 42275b7cd..4fcbeb728 100644 --- a/tests/unit/.eslintrc.js +++ b/tests/unit/.eslintrc.js @@ -2,4 +2,7 @@ module.exports = { env: { mocha: true, }, + rules: { + 'no-unused-expressions': 'off', + }, }; diff --git a/tests/unit/globalconfig/default.js b/tests/unit/globalconfig/default.js index 43b160e29..de4da8697 100644 --- a/tests/unit/globalconfig/default.js +++ b/tests/unit/globalconfig/default.js @@ -56,13 +56,14 @@ module.exports = { rpcporttestnet: 26224, }, daemon: { - chainValidHeight: 770000, + chainValidHeight: 1062000, port: 16125, rpcport: 16124, porttestnet: 26125, rpcporttestnet: 26124, }, fluxTeamZelId: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', + deterministicNodesStart: 558000, fluxapps: { // in flux main chain per month (blocksLasting) price: [{ // any price fork can be done by adjusting object similarily. @@ -126,7 +127,7 @@ module.exports = { ram: 2000, // 2000mb hdd: 30, // 30gb // this value is likely to rise }, - fluxSpecifics: { + fluxSpecifics: { // tbd during forks cpu: { basic: 20, // 10 available for apps super: 40, // 30 available for apps @@ -142,7 +143,7 @@ module.exports = { super: 150, // 120 for apps bamf: 600, // 570 for apps }, - collateral: { + collateral: { // tbd during forks basic: 10000, super: 25000, bamf: 100000, diff --git a/tests/unit/serviceHelper.test.js b/tests/unit/serviceHelper.test.js index ed535d6a6..58ab6e161 100644 --- a/tests/unit/serviceHelper.test.js +++ b/tests/unit/serviceHelper.test.js @@ -1,23 +1,23 @@ +/* eslint-disable no-restricted-syntax */ const chai = require('chai'); const config = require('config'); const { ObjectId } = require('mongodb'); -var proxyquire = require('proxyquire'); -const expect = chai.expect; -const sinon = require('sinon'); +const proxyquire = require('proxyquire'); -let serviceHelper = require("../../ZelBack/src/services/serviceHelper"); +const { expect } = chai; + +let serviceHelper = require('../../ZelBack/src/services/serviceHelper'); const adminConfig = { initial: { ipaddress: '83.51.212.243', zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', - testnet: true - } -} + testnet: true, + }, +}; serviceHelper = proxyquire('../../ZelBack/src/services/serviceHelper', { '../../../config/userconfig': adminConfig }); - describe('serviceHelper tests', () => { describe('ensureBoolean function tests', () => { const falseBools = ['false', false, 0, '0']; @@ -25,25 +25,25 @@ describe('serviceHelper tests', () => { const restOfTruthyValues = [3, 3n, 'test', [1, 2], { name: 'testobject' }]; const restOfFalsyValues = [0n, null, undefined, NaN, '']; - for (let falseBool of falseBools) { + for (const falseBool of falseBools) { it(`parameter ${falseBool} of type ${typeof falseBool} should return false`, () => { expect(serviceHelper.ensureBoolean(falseBool)).to.equal(false); }); } - for (let trueBool of trueBools) { + for (const trueBool of trueBools) { it(`parameter ${trueBool} of type ${typeof trueBool} should return false`, () => { expect(serviceHelper.ensureBoolean(trueBool)).to.equal(true); }); } - for (let truthyValue of restOfTruthyValues) { + for (const truthyValue of restOfTruthyValues) { it(`parameter ${truthyValue} of type ${typeof truthyValue} should return undefined`, () => { expect(serviceHelper.ensureBoolean(truthyValue)).to.be.undefined; }); } - for (let falsyValue of restOfFalsyValues) { + for (const falsyValue of restOfFalsyValues) { it(`parameter ${falsyValue} of type ${typeof falsyValue} should return undefined`, () => { expect(serviceHelper.ensureBoolean(falsyValue)).to.be.undefined; }); @@ -55,25 +55,25 @@ describe('serviceHelper tests', () => { }); describe('ensureNumber function tests', () => { - const numbersList = [1, '1', 2.5, '2.5'] + const numbersList = [1, '1', 2.5, '2.5']; - for (let number of numbersList) { + for (const number of numbersList) { it(`parameter ${number} should return number value`, () => { const ensureNumberOutput = serviceHelper.ensureNumber(1); - expect(ensureNumberOutput).to.be.a('number') + expect(ensureNumberOutput).to.be.a('number'); }); } it('parameter "test" of type string should return NaN', () => { - const ensureNumberOutput = serviceHelper.ensureNumber("test"); + const ensureNumberOutput = serviceHelper.ensureNumber('test'); - expect(ensureNumberOutput).to.be.NaN + expect(ensureNumberOutput).to.be.NaN; }); it('parameter {name: 1} of type object should return NaN', () => { const ensureNumberOutput = serviceHelper.ensureNumber({ name: 1 }); - expect(ensureNumberOutput).to.be.NaN + expect(ensureNumberOutput).to.be.NaN; }); }); @@ -81,8 +81,8 @@ describe('serviceHelper tests', () => { it('parameter of type object should return the same object', () => { const testObject = { id: 1, - username: 'Testing user' - } + username: 'Testing user', + }; const ensureObjectOutput = serviceHelper.ensureObject(testObject); @@ -97,11 +97,11 @@ describe('serviceHelper tests', () => { }); it('parameter of type json string should return an object', () => { - stringObject = JSON.stringify({ "id": 1, "username": "Testing user" }) + const stringObject = JSON.stringify({ id: 1, username: 'Testing user' }); const expected = { id: 1, - username: 'Testing user' - } + username: 'Testing user', + }; const ensureObjectOutput = serviceHelper.ensureObject(stringObject); @@ -113,8 +113,8 @@ describe('serviceHelper tests', () => { const queryString = 'username=Tester&id=1'; const expected = { id: '1', - username: 'Tester' - } + username: 'Tester', + }; const ensureObjectOutput = serviceHelper.ensureObject(queryString); @@ -125,8 +125,8 @@ describe('serviceHelper tests', () => { it('parameter of type string should return an object', () => { const testString = 'test'; const expected = { - test: "", - } + test: '', + }; const ensureObjectOutput = serviceHelper.ensureObject(testString); @@ -143,8 +143,8 @@ describe('serviceHelper tests', () => { expect(ensureObjectOutput).to.eql(testArr); }); - const otherTypes = [1, true] - for (let param of otherTypes) { + const otherTypes = [1, true]; + for (const param of otherTypes) { it(`parameter of type ${typeof param} should return undefined`, () => { expect(serviceHelper.ensureObject(param)).to.be.an('object').that.is.empty; }); @@ -164,9 +164,9 @@ describe('serviceHelper tests', () => { it('parameter of type object should return a string', () => { const testObject = { id: 1, - username: 'Testing user' - } - const expected = '{"id":1,"username":"Testing user"}' + username: 'Testing user', + }; + const expected = '{"id":1,"username":"Testing user"}'; const ensureStringOutput = serviceHelper.ensureString(testObject); @@ -176,7 +176,7 @@ describe('serviceHelper tests', () => { it('parameter of type number should return a string', () => { const testNumber = 42; - const expected = '42' + const expected = '42'; const ensureStringOutput = serviceHelper.ensureString(testNumber); @@ -324,11 +324,11 @@ describe('serviceHelper tests', () => { const database = db.db(config.database.appsglobal.database); const collection = config.database.appsglobal.collections.appsInformation; const insertApp = { - "_id": ObjectId("6147045cd774409b374d253d"), - "name": "PolkadotNode", - "description": "Polkadot is a heterogeneous multi-chain interchange.", - "owner": "196GJWyLxzAw3MirTT7Bqs2iGpUQio29GH", - } + _id: ObjectId('6147045cd774409b374d253d'), + name: 'PolkadotNode', + description: 'Polkadot is a heterogeneous multi-chain interchange.', + owner: '196GJWyLxzAw3MirTT7Bqs2iGpUQio29GH', + }; try { await database.collection(collection).drop(); @@ -338,21 +338,21 @@ describe('serviceHelper tests', () => { await serviceHelper.insertOneToDatabase(database, collection, insertApp); }); - it("should return application owner if app exists in database", async () => { + it('should return application owner if app exists in database', async () => { const appOwner = '196GJWyLxzAw3MirTT7Bqs2iGpUQio29GH'; const getOwnerResult = await serviceHelper.getApplicationOwner('PolkadotNode'); expect(getOwnerResult).to.equal(appOwner); }); - it("should return application owner if app is in available apps, but not in db", async () => { + it('should return application owner if app is in available apps, but not in db', async () => { const appOwner = '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC'; const getOwnerResult = await serviceHelper.getApplicationOwner('FoldingAtHomeB'); expect(getOwnerResult).to.equal(appOwner); }); - it("should return null if the app does not exist", async () => { + it('should return null if the app does not exist', async () => { const getOwnerResult = await serviceHelper.getApplicationOwner('testing'); expect(getOwnerResult).to.be.null; @@ -368,7 +368,6 @@ describe('serviceHelper tests', () => { it('should return throw error if ZelID is invalid', () => { const isValid = serviceHelper.verifyZelID('34xp4vRoCGJym3xR7yCVPFHoCNxv4Twseo'); expect(isValid).to.be.an('error'); - }); it('should return true if ZelID is valid', () => { @@ -420,13 +419,13 @@ describe('serviceHelper tests', () => { }); describe('deleteLoginPhrase tests', () => { - const query = { "loginPhrase": { $eq: "1644935809116x5fpl862o5fnyl29vfpmd9vzmgaddlgqbud8cxks8hj" } }; + const query = { loginPhrase: { $eq: '1644935809116x5fpl862o5fnyl29vfpmd9vzmgaddlgqbud8cxks8hj' } }; const loginPhrase = { - "_id": ObjectId("620bba81c04b4966674013a4"), - "loginPhrase": "1644935809116x5fpl862o5fnyl29vfpmd9vzmgaddlgqbud8cxks8hj", - "createdAt": new Date("2022-02-15T14:36:49.116Z"), - "expireAt": new Date("2022-02-15T14:51:49.116Z") - } + _id: ObjectId('620bba81c04b4966674013a4'), + loginPhrase: '1644935809116x5fpl862o5fnyl29vfpmd9vzmgaddlgqbud8cxks8hj', + createdAt: new Date('2022-02-15T14:36:49.116Z'), + expireAt: new Date('2022-02-15T14:51:49.116Z'), + }; let db; let database; let collection; @@ -455,5 +454,4 @@ describe('serviceHelper tests', () => { expect(afterDeletionResult).to.be.null; }); }); - }); diff --git a/tests/unit/verificationHelper.test.js b/tests/unit/verificationHelper.test.js index 719a970f7..9c75e1f75 100644 --- a/tests/unit/verificationHelper.test.js +++ b/tests/unit/verificationHelper.test.js @@ -1,22 +1,22 @@ const chai = require('chai'); -const expect = chai.expect; + +const { expect } = chai; const sinon = require('sinon'); -const verificationHelperUtils = require("../../ZelBack/src/services/verificationHelperUtils"); -const { verifyPrivilege } = require("../../ZelBack/src/services/verificationHelper"); +const verificationHelperUtils = require('../../ZelBack/src/services/verificationHelperUtils'); +const { verifyPrivilege } = require('../../ZelBack/src/services/verificationHelper'); -//placeholders - verification functions are mocked, they have already been tested in verificationHelperUtils.test +// placeholders - verification functions are mocked, they have already been tested in verificationHelperUtils.test const req = { headers: { zelidauth: { zelid: 'testing1', - signature: 'testing2' - } - } + signature: 'testing2', + }, + }, }; const appName = 'myTestAppName'; - describe('verificationHelper tests', () => { it('should call verifyAdminSession when flag "admin" is passed', async () => { const privilege = 'admin'; @@ -91,4 +91,4 @@ describe('verificationHelper tests', () => { expect(verifyPrivilegeResult).to.be.false; }); -}); \ No newline at end of file +}); diff --git a/tests/unit/verificationHelperUtils.test.js b/tests/unit/verificationHelperUtils.test.js index a2cdb147f..cfdefbafd 100644 --- a/tests/unit/verificationHelperUtils.test.js +++ b/tests/unit/verificationHelperUtils.test.js @@ -2,48 +2,53 @@ const chai = require('chai'); const config = require('config'); const { ObjectId } = require('mongodb'); const proxyquire = require('proxyquire'); -const expect = chai.expect; -let serviceHelper = require("../../ZelBack/src/services/serviceHelper"); + +const { expect } = chai; +const serviceHelper = require('../../ZelBack/src/services/serviceHelper'); const adminConfig = { initial: { ipaddress: '83.51.212.243', zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', - testnet: true - } -} + testnet: true, + }, +}; const verificationHelperUtils = proxyquire('../../ZelBack/src/services/verificationHelperUtils', { '../../../config/userconfig': adminConfig }); -const insertUsers = [{ - "_id": ObjectId("6108fbb9f04dfe1ef624b819"), - "zelid": "1hjy4bCYBJr4mny4zCE85J94RXa8W6q37", // regular user - "loginPhrase": "162797868130153vt9r89dzjjjfg6kf34ntf1d8aa5zqlk04j3zy8z40ni", - "signature": "H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=" -}, { - "_id": ObjectId("60cad0767247ac0a779fb3f0"), - "zelid": "1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC", // admin - "loginPhrase": "16125160820394ddsh5skgwv0ipodku92y0jbwvpyj17bh68lzrjlxq9", - "signature": "IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=" -}, { - "_id": ObjectId("620bbc40c04b4966674013a8"), - "zelid": "1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t", // app owner - "loginPhrase": "1644935889016mtmbo4uah32tvvwrmzg4j8qzv04ba8g8n56cevn6b", - "signature": "H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=" -}, { - "_id": ObjectId("61967125f3178f082a296100"), - "zelid": "1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM", // Flux team - "loginPhrase": "1623904359736pja76q7y68deb4264olbml6o8gyhot2yvj5oevgv9k2", - "signature": "H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=" -} +const insertUsers = [ + { + _id: ObjectId('6108fbb9f04dfe1ef624b819'), + zelid: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', // regular user + loginPhrase: '162797868130153vt9r89dzjjjfg6kf34ntf1d8aa5zqlk04j3zy8z40ni', + signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=', + }, + { + _id: ObjectId('60cad0767247ac0a779fb3f0'), + zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', // admin + loginPhrase: '16125160820394ddsh5skgwv0ipodku92y0jbwvpyj17bh68lzrjlxq9', + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=', + }, + { + _id: ObjectId('620bbc40c04b4966674013a8'), + zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', // app owner + loginPhrase: '1644935889016mtmbo4uah32tvvwrmzg4j8qzv04ba8g8n56cevn6b', + signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=', + }, + { + _id: ObjectId('61967125f3178f082a296100'), + zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', // Flux team + loginPhrase: '1623904359736pja76q7y68deb4264olbml6o8gyhot2yvj5oevgv9k2', + signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=', + }, ]; const insertApp = { - "_id": ObjectId("6147045cd774409b374d253d"), - "name": "PolkadotNode", - "description": "Polkadot is a heterogeneous multi-chain interchange.", - "owner": "1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t", -} + _id: ObjectId('6147045cd774409b374d253d'), + name: 'PolkadotNode', + description: 'Polkadot is a heterogeneous multi-chain interchange.', + owner: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', +}; describe('verificationHelperUtils tests', () => { describe('verifyAdminSession tests', () => { @@ -62,73 +67,72 @@ describe('verificationHelperUtils tests', () => { await database.collection(collection).insertMany(insertUsers); }); - it("should return true when requested by admin", async () => { + it('should return true when requested by admin', async () => { const headers = { zelidauth: { zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', - signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' - } - } + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=', + }, + }; const isAdmin = await verificationHelperUtils.verifyAdminSession(headers); expect(isAdmin).to.be.true; }); - it("should return false when requested by regular user", async () => { + it('should return false when requested by regular user', async () => { const headers = { zelidauth: { zelid: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', - signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=' - } - } + signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=', + }, + }; const isAdmin = await verificationHelperUtils.verifyAdminSession(headers); expect(isAdmin).to.be.false; }); - it("should return false if signature is invalid", async () => { + it('should return false if signature is invalid', async () => { const headers = { zelidauth: { zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', - signature: 'IH9d68fk/dYQtzMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' - } - } + signature: 'IH9d68fk/dYQtzMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=', + }, + }; const isAdmin = await verificationHelperUtils.verifyAdminSession(headers); expect(isAdmin).to.be.false; }); - it("should return false if zelID is invalid", async () => { + it('should return false if zelID is invalid', async () => { const headers = { zelidauth: { zelid: '2CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', - signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' - } - } + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=', + }, + }; const isAdmin = await verificationHelperUtils.verifyAdminSession(headers); - expect(isAdmin).to.be.false; }); - it("should return false if header values are empty", async () => { + it('should return false if header values are empty', async () => { const headers = { zelidauth: { zelid: '', - signature: '' - } - } + signature: '', + }, + }; const isAdmin = await verificationHelperUtils.verifyAdminSession(headers); expect(isAdmin).to.be.false; }); - it("should return false if header is empty", async () => { - const headers = {} + it('should return false if header is empty', async () => { + const headers = {}; const isAdmin = await verificationHelperUtils.verifyAdminSession(headers); @@ -149,61 +153,60 @@ describe('verificationHelperUtils tests', () => { console.log('Collection not found.'); } - await database.collection(collection).insertMany(insertUsers); }); - it("should return true when requested by a logged user", async () => { + it('should return true when requested by a logged user', async () => { const headers = { zelidauth: { zelid: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', - signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=' - } - } + signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=', + }, + }; const isLoggedUser = await verificationHelperUtils.verifyUserSession(headers); expect(isLoggedUser).to.be.true; }); - it("should return false if called with a wrong zelid", async () => { + it('should return false if called with a wrong zelid', async () => { const headers = { zelidauth: { zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBu9t', - signature: 'IMDMG1GuDasjPMkrGaRQhkLpFO0saBV+v+N6h3wP6/QlF3J9ymLAPZy7DCBd/RnOSzUxmTHruenVeR7LghzRnHA=' - } - } + signature: 'IMDMG1GuDasjPMkrGaRQhkLpFO0saBV+v+N6h3wP6/QlF3J9ymLAPZy7DCBd/RnOSzUxmTHruenVeR7LghzRnHA=', + }, + }; const isLoggedUser = await verificationHelperUtils.verifyUserSession(headers); expect(isLoggedUser).to.be.false; }); - it("should return false if called with a wrong signature", async () => { + it('should return false if called with a wrong signature', async () => { const headers = { zelidauth: { zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', - signature: 'IMDMG1GuDasjPMkrGaRQhkLpFO0saBZ+v+N6h3wP6/QlF3J9ymLAPZy7DCBd/RnOSzUxmTHruenVeR7LghzRnHA=' - } - } + signature: 'IMDMG1GuDasjPMkrGaRQhkLpFO0saBZ+v+N6h3wP6/QlF3J9ymLAPZy7DCBd/RnOSzUxmTHruenVeR7LghzRnHA=', + }, + }; const isLoggedUser = await verificationHelperUtils.verifyUserSession(headers); expect(isLoggedUser).to.be.false; }); - it("should return false if called with no header", async () => { + it('should return false if called with no header', async () => { const isLoggedUser = await verificationHelperUtils.verifyUserSession(); expect(isLoggedUser).to.be.false; }); - it("should return false if called with empty data", async () => { + it('should return false if called with empty data', async () => { const headers = { zelidauth: { zelid: '', - signature: '' - } - } + signature: '', + }, + }; const isLoggedUser = await verificationHelperUtils.verifyUserSession(headers); @@ -227,12 +230,12 @@ describe('verificationHelperUtils tests', () => { await database.collection(collection).insertMany(insertUsers); }); - it("should return true when requested by the flux team", async () => { + it('should return true when requested by the flux team', async () => { const headers = { zelidauth: { zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', - signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' - } + signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=', + }, }; const isFluxTeamSession = await verificationHelperUtils.verifyFluxTeamSession(headers); @@ -240,12 +243,12 @@ describe('verificationHelperUtils tests', () => { expect(isFluxTeamSession).to.be.true; }); - it("should return false when zelid is not the flux team", async () => { + it('should return false when zelid is not the flux team', async () => { const headers = { zelidauth: { zelid: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', - signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=' - } + signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=', + }, }; const isFluxTeamSession = await verificationHelperUtils.verifyFluxTeamSession(headers); @@ -253,13 +256,12 @@ describe('verificationHelperUtils tests', () => { expect(isFluxTeamSession).to.be.false; }); - - it("should return false when signature is invalid", async () => { + it('should return false when signature is invalid', async () => { const headers = { zelidauth: { zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', - signature: 'N4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' - } + signature: 'N4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=', + }, }; const isFluxTeamSession = await verificationHelperUtils.verifyFluxTeamSession(headers); @@ -267,12 +269,12 @@ describe('verificationHelperUtils tests', () => { expect(isFluxTeamSession).to.be.false; }); - it("should return false when zelid is invalid", async () => { + it('should return false when zelid is invalid', async () => { const headers = { zelidauth: { zelid: '1NH9BP1z5Rp3HSf5ef6NpUbE8JcyLRruAM', - signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' - } + signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=', + }, }; const isFluxTeamSession = await verificationHelperUtils.verifyFluxTeamSession(headers); @@ -280,12 +282,12 @@ describe('verificationHelperUtils tests', () => { expect(isFluxTeamSession).to.be.false; }); - it("should return false when data is empty", async () => { + it('should return false when data is empty', async () => { const headers = { zelidauth: { zelid: '', - signature: '' - } + signature: '', + }, }; const isFluxTeamSession = await verificationHelperUtils.verifyFluxTeamSession(headers); @@ -293,12 +295,12 @@ describe('verificationHelperUtils tests', () => { expect(isFluxTeamSession).to.be.false; }); - it("should return false when data are true bools", async () => { + it('should return false when data are true bools', async () => { const headers = { zelidauth: { zelid: true, - signature: true - } + signature: true, + }, }; const isFluxTeamSession = await verificationHelperUtils.verifyFluxTeamSession(headers); @@ -306,7 +308,7 @@ describe('verificationHelperUtils tests', () => { expect(isFluxTeamSession).to.be.false; }); - it("should return false when header is empty", async () => { + it('should return false when header is empty', async () => { const headers = {}; const isFluxTeamSession = await verificationHelperUtils.verifyFluxTeamSession(headers); @@ -314,7 +316,7 @@ describe('verificationHelperUtils tests', () => { expect(isFluxTeamSession).to.be.false; }); - it("should return false when no header is passed", async () => { + it('should return false when no header is passed', async () => { const isFluxTeamSession = await verificationHelperUtils.verifyFluxTeamSession(); expect(isFluxTeamSession).to.be.false; @@ -337,12 +339,12 @@ describe('verificationHelperUtils tests', () => { await database.collection(collection).insertMany(insertUsers); }); - it("should return true when requested by the flux team", async () => { + it('should return true when requested by the flux team', async () => { const headers = { zelidauth: { zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', - signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' - } + signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=', + }, }; const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(headers); @@ -350,12 +352,12 @@ describe('verificationHelperUtils tests', () => { expect(isAdminOrFluxTeam).to.be.true; }); - it("should return true when requested by the admin", async () => { + it('should return true when requested by the admin', async () => { const headers = { zelidauth: { zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', - signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' - } + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=', + }, }; const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(headers); @@ -363,12 +365,12 @@ describe('verificationHelperUtils tests', () => { expect(isAdminOrFluxTeam).to.be.true; }); - it("should return false when zelid is not the flux team", async () => { + it('should return false when zelid is not the flux team', async () => { const headers = { zelidauth: { zelid: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', - signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=' - } + signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=', + }, }; const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(headers); @@ -376,13 +378,12 @@ describe('verificationHelperUtils tests', () => { expect(isAdminOrFluxTeam).to.be.false; }); - - it("should return false when signature is invalid", async () => { + it('should return false when signature is invalid', async () => { const headers = { zelidauth: { zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', - signature: 'N4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' - } + signature: 'N4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=', + }, }; const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(headers); @@ -390,12 +391,12 @@ describe('verificationHelperUtils tests', () => { expect(isAdminOrFluxTeam).to.be.false; }); - it("should return false when zelid is invalid", async () => { + it('should return false when zelid is invalid', async () => { const headers = { zelidauth: { zelid: '1NH9BP1z5Rp3HSf5ef6NpUbE8JcyLRruAM', - signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' - } + signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=', + }, }; const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(headers); @@ -403,12 +404,12 @@ describe('verificationHelperUtils tests', () => { expect(isAdminOrFluxTeam).to.be.false; }); - it("should return false when data is empty", async () => { + it('should return false when data is empty', async () => { const headers = { zelidauth: { zelid: '', - signature: '' - } + signature: '', + }, }; const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(headers); @@ -416,12 +417,12 @@ describe('verificationHelperUtils tests', () => { expect(isAdminOrFluxTeam).to.be.false; }); - it("should return false when data are true bools", async () => { + it('should return false when data are true bools', async () => { const headers = { zelidauth: { zelid: true, - signature: true - } + signature: true, + }, }; const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(headers); @@ -429,7 +430,7 @@ describe('verificationHelperUtils tests', () => { expect(isAdminOrFluxTeam).to.be.false; }); - it("should return false when header is empty", async () => { + it('should return false when header is empty', async () => { const headers = {}; const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(headers); @@ -437,7 +438,7 @@ describe('verificationHelperUtils tests', () => { expect(isAdminOrFluxTeam).to.be.false; }); - it("should return false when no header is passed", async () => { + it('should return false when no header is passed', async () => { const isAdminOrFluxTeam = await verificationHelperUtils.verifyAdminAndFluxTeamSession(); expect(isAdminOrFluxTeam).to.be.false; @@ -459,7 +460,6 @@ describe('verificationHelperUtils tests', () => { await databaseLocal.collection(collectionLoggedUsers).insertMany(insertUsers); - const databaseGlobal = db.db(config.database.appsglobal.database); const collectionApps = config.database.appsglobal.collections.appsInformation; @@ -469,15 +469,14 @@ describe('verificationHelperUtils tests', () => { console.log('Collection not found.'); } await serviceHelper.insertOneToDatabase(databaseGlobal, collectionApps, insertApp); - }); - it("should return true when requested by the app owner", async () => { + it('should return true when requested by the app owner', async () => { const headers = { zelidauth: { zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', - signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=' - } + signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=', + }, }; const appName = 'PolkadotNode'; const isOwnerSession = await verificationHelperUtils.verifyAppOwnerSession(headers, appName); @@ -485,12 +484,12 @@ describe('verificationHelperUtils tests', () => { expect(isOwnerSession).to.be.true; }); - it("should return false when requested by the admin", async () => { + it('should return false when requested by the admin', async () => { const headers = { zelidauth: { zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', - signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' - } + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=', + }, }; const appName = 'PolkadotNode'; const isOwnerSession = await verificationHelperUtils.verifyAppOwnerSession(headers, appName); @@ -498,12 +497,12 @@ describe('verificationHelperUtils tests', () => { expect(isOwnerSession).to.be.false; }); - it("should return false when requested by the owner with a wrong signature", async () => { + it('should return false when requested by the owner with a wrong signature', async () => { const headers = { zelidauth: { zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', - signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' - } + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=', + }, }; const appName = 'PolkadotNode'; const isOwnerSession = await verificationHelperUtils.verifyAppOwnerSession(headers, appName); @@ -511,12 +510,12 @@ describe('verificationHelperUtils tests', () => { expect(isOwnerSession).to.be.false; }); - it("should return false when requested with empty header data", async () => { + it('should return false when requested with empty header data', async () => { const headers = { zelidauth: { zelid: '', - signature: '' - } + signature: '', + }, }; const appName = 'PolkadotNode'; const isOwnerSession = await verificationHelperUtils.verifyAppOwnerSession(headers, appName); @@ -524,7 +523,7 @@ describe('verificationHelperUtils tests', () => { expect(isOwnerSession).to.be.false; }); - it("should return false when requested with empty header ", async () => { + it('should return false when requested with empty header ', async () => { const headers = {}; const appName = 'PolkadotNode'; @@ -533,12 +532,12 @@ describe('verificationHelperUtils tests', () => { expect(isOwnerSession).to.be.false; }); - it("should return true when requested with an empty app name", async () => { + it('should return true when requested with an empty app name', async () => { const headers = { zelidauth: { zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', - signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=' - } + signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=', + }, }; const appName = ''; const isOwnerSession = await verificationHelperUtils.verifyAppOwnerSession(headers, appName); @@ -571,15 +570,14 @@ describe('verificationHelperUtils tests', () => { console.log('Collection not found.'); } await serviceHelper.insertOneToDatabase(databaseGlobal, collectionApps, insertApp); - }); - it("should return true when requested by the app owner", async () => { + it('should return true when requested by the app owner', async () => { const headers = { zelidauth: { zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', - signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=' - } + signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=', + }, }; const appName = 'PolkadotNode'; const isOwnerOrHigherSession = await verificationHelperUtils.verifyAppOwnerOrHigherSession(headers, appName); @@ -587,12 +585,12 @@ describe('verificationHelperUtils tests', () => { expect(isOwnerOrHigherSession).to.be.true; }); - it("should return true when requested by the admin", async () => { + it('should return true when requested by the admin', async () => { const headers = { zelidauth: { zelid: '1CbErtneaX2QVyUfwU7JGB7VzvPgrgc3uC', - signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' - } + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=', + }, }; const appName = 'PolkadotNode'; const isOwnerOrHigherSession = await verificationHelperUtils.verifyAppOwnerOrHigherSession(headers, appName); @@ -600,12 +598,12 @@ describe('verificationHelperUtils tests', () => { expect(isOwnerOrHigherSession).to.be.true; }); - it("should return true when requested by the flux team", async () => { + it('should return true when requested by the flux team', async () => { const headers = { zelidauth: { zelid: '1NH9BP155Rp3HSf5ef6NpUbE8JcyLRruAM', - signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=' - } + signature: 'H4lWS4PcrR1tMo8RCLzeYYrd042tsJC9PteIKZvn091ZAYE4K9ydfri8M1KKWe905NHdS4LPPsClqvA4nY/G+II=', + }, }; const appName = 'PolkadotNode'; const isOwnerOrHigherSession = await verificationHelperUtils.verifyAppOwnerOrHigherSession(headers, appName); @@ -613,12 +611,12 @@ describe('verificationHelperUtils tests', () => { expect(isOwnerOrHigherSession).to.be.true; }); - it("should return false when requested by a regular user", async () => { + it('should return false when requested by a regular user', async () => { const headers = { zelidauth: { zelid: '1hjy4bCYBJr4mny4zCE85J94RXa8W6q37', - signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=' - } + signature: 'H9oD/ZA7mEVQMWYWNIGDF7T2J++R/EG8tYPfB+fQ+XvQIbOXIcBEhxZwPYmh0HRj531oMc/HfcXPAYjWlN9wCn4=', + }, }; const appName = 'PolkadotNode'; const isOwnerOrHigherSession = await verificationHelperUtils.verifyAppOwnerOrHigherSession(headers, appName); @@ -626,12 +624,12 @@ describe('verificationHelperUtils tests', () => { expect(isOwnerOrHigherSession).to.be.false; }); - it("should return false when requested by the owner with a wrong signature", async () => { + it('should return false when requested by the owner with a wrong signature', async () => { const headers = { zelidauth: { zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', - signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=' - } + signature: 'IH9d68fk/dYQtuMlNN7ioc52MJ6ryRT0IYss6h/KCwVWGcbVNFoI8Jh6hIklRq+w2itV/6vs/xzCWp4TUdSWDBc=', + }, }; const appName = 'PolkadotNode'; const isOwnerOrHigherSession = await verificationHelperUtils.verifyAppOwnerOrHigherSession(headers, appName); @@ -639,12 +637,12 @@ describe('verificationHelperUtils tests', () => { expect(isOwnerOrHigherSession).to.be.false; }); - it("should return false when requested with empty header data", async () => { + it('should return false when requested with empty header data', async () => { const headers = { zelidauth: { zelid: '', - signature: '' - } + signature: '', + }, }; const appName = 'PolkadotNode'; const isOwnerOrHigherSession = await verificationHelperUtils.verifyAppOwnerOrHigherSession(headers, appName); @@ -652,7 +650,7 @@ describe('verificationHelperUtils tests', () => { expect(isOwnerOrHigherSession).to.be.false; }); - it("should return false when requested with empty header ", async () => { + it('should return false when requested with empty header ', async () => { const headers = {}; const appName = 'PolkadotNode'; @@ -661,12 +659,12 @@ describe('verificationHelperUtils tests', () => { expect(isOwnerOrHigherSession).to.be.false; }); - it("should return true when requested with an empty app name", async () => { + it('should return true when requested with an empty app name', async () => { const headers = { zelidauth: { zelid: '1LZe3AUYQC4aT5YWLhgEcH1nLLdoKNBi9t', - signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=' - } + signature: 'H4bL1HhNXiYiHywCnUeptHtLQY/YiGmLt14N+BBNXRIKd6BkP+kFr9CvaGLELQxN1A31OXoy3SMBoHj2/OqiK6c=', + }, }; const appName = ''; const isOwnerOrHigherSession = await verificationHelperUtils.verifyAppOwnerOrHigherSession(headers, appName); From 5e194303dc238d9b4597226da17d10b4cfa47f88 Mon Sep 17 00:00:00 2001 From: Cabecinha84 <42519726+Cabecinha84@users.noreply.github.com> Date: Thu, 24 Feb 2022 20:34:27 +0000 Subject: [PATCH 33/41] Improve processInsight performance --- ZelBack/src/services/explorerService.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ZelBack/src/services/explorerService.js b/ZelBack/src/services/explorerService.js index 76e01cb45..54c0d3ebb 100644 --- a/ZelBack/src/services/explorerService.js +++ b/ZelBack/src/services/explorerService.js @@ -291,6 +291,8 @@ function decodeMessage(asm) { async function processInsight(blockDataVerbose, database) { // get Block Deltas information const txs = blockDataVerbose.tx; + const transactions = []; + const appsTransactions = []; // go through each transaction in deltas // eslint-disable-next-line no-restricted-syntax for (const tx of txs) { @@ -334,8 +336,7 @@ async function processInsight(blockDataVerbose, database) { // eslint-disable-next-line no-await-in-loop const result = await serviceHelper.findOneInDatabase(database, appsHashesCollection, querySearch, projectionSearch); // this search can be later removed if nodes rescan apps and reconstruct the index for unique if (!result) { - // eslint-disable-next-line no-await-in-loop - await serviceHelper.insertOneToDatabase(database, appsHashesCollection, appTxRecord); + appsTransactions.push(appTxRecord); appsService.checkAndRequestApp(message, tx.txid, blockDataVerbose.height, isFluxAppMessageValue); } else { throw new Error(`Found an existing hash app ${serviceHelper.ensureString(result)}`); @@ -364,10 +365,11 @@ async function processInsight(blockDataVerbose, database) { lockedAmount: senderInfo.satoshis || senderInfo.lockedAmount, height: blockDataVerbose.height, }; - // eslint-disable-next-line no-await-in-loop - await serviceHelper.insertOneToDatabase(database, fluxTransactionCollection, fluxTxData); + transactions.push(fluxTxData); } } + await serviceHelper.insertManyToDatabase(database, appsHashesCollection, appsTransactions); + await serviceHelper.insertManyToDatabase(database, fluxTransactionCollection, transactions); } async function processStandard(blockDataVerbose, database) { From 2c9c2a750af9fffaa096688f48dce2512a9d8551 Mon Sep 17 00:00:00 2001 From: Cabecinha84 <42519726+Cabecinha84@users.noreply.github.com> Date: Thu, 24 Feb 2022 20:45:55 +0000 Subject: [PATCH 34/41] Create insertManyToDatabase on serviceHelper --- ZelBack/src/services/serviceHelper.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ZelBack/src/services/serviceHelper.js b/ZelBack/src/services/serviceHelper.js index 833f26967..dd1e2c512 100644 --- a/ZelBack/src/services/serviceHelper.js +++ b/ZelBack/src/services/serviceHelper.js @@ -160,6 +160,11 @@ async function insertOneToDatabase(database, collection, value) { return result; } +async function insertManyToDatabase(database, collection, values) { + const result = await database.collection(collection).insertMany(values); + return result; +} + async function updateOneInDatabase(database, collection, query, update, options) { const passedOptions = options || {}; const result = await database.collection(collection).updateOne(query, update, passedOptions); @@ -326,6 +331,7 @@ module.exports = { findOneInDatabase, findOneAndUpdateInDatabase, insertOneToDatabase, + insertManyToDatabase, updateInDatabase, updateOneInDatabase, findOneAndDeleteInDatabase, From f70744ce320fbcf112c93043fafdb5f7410edeb4 Mon Sep 17 00:00:00 2001 From: Cabecinha84 <42519726+Cabecinha84@users.noreply.github.com> Date: Thu, 24 Feb 2022 20:51:04 +0000 Subject: [PATCH 35/41] Only call insert if there are things to insert --- ZelBack/src/services/explorerService.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ZelBack/src/services/explorerService.js b/ZelBack/src/services/explorerService.js index 54c0d3ebb..50639fa1b 100644 --- a/ZelBack/src/services/explorerService.js +++ b/ZelBack/src/services/explorerService.js @@ -368,8 +368,12 @@ async function processInsight(blockDataVerbose, database) { transactions.push(fluxTxData); } } - await serviceHelper.insertManyToDatabase(database, appsHashesCollection, appsTransactions); - await serviceHelper.insertManyToDatabase(database, fluxTransactionCollection, transactions); + if (appsTransactions.length > 0) { + await serviceHelper.insertManyToDatabase(database, appsHashesCollection, appsTransactions); + } + if (transactions.length > 0) { + await serviceHelper.insertManyToDatabase(database, fluxTransactionCollection, transactions); + } } async function processStandard(blockDataVerbose, database) { From b8b14359bda8ba86b865c7bd64f91f58a3c6803c Mon Sep 17 00:00:00 2001 From: TheTrunk Date: Fri, 25 Feb 2022 17:18:13 +0700 Subject: [PATCH 36/41] add options to insertMany ordered false --- ZelBack/src/services/explorerService.js | 7 +++++-- ZelBack/src/services/serviceHelper.js | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ZelBack/src/services/explorerService.js b/ZelBack/src/services/explorerService.js index 50639fa1b..7f8241214 100644 --- a/ZelBack/src/services/explorerService.js +++ b/ZelBack/src/services/explorerService.js @@ -368,11 +368,14 @@ async function processInsight(blockDataVerbose, database) { transactions.push(fluxTxData); } } + const options = { + ordered: false, + }; if (appsTransactions.length > 0) { - await serviceHelper.insertManyToDatabase(database, appsHashesCollection, appsTransactions); + await serviceHelper.insertManyToDatabase(database, appsHashesCollection, appsTransactions, options); } if (transactions.length > 0) { - await serviceHelper.insertManyToDatabase(database, fluxTransactionCollection, transactions); + await serviceHelper.insertManyToDatabase(database, fluxTransactionCollection, transactions, options); } } diff --git a/ZelBack/src/services/serviceHelper.js b/ZelBack/src/services/serviceHelper.js index dd1e2c512..017af7409 100644 --- a/ZelBack/src/services/serviceHelper.js +++ b/ZelBack/src/services/serviceHelper.js @@ -160,8 +160,8 @@ async function insertOneToDatabase(database, collection, value) { return result; } -async function insertManyToDatabase(database, collection, values) { - const result = await database.collection(collection).insertMany(values); +async function insertManyToDatabase(database, collection, values, options = {}) { + const result = await database.collection(collection).insertMany(values, options); return result; } From 035de3dc075d515fee57d1a4cfa6b30490550684 Mon Sep 17 00:00:00 2001 From: TheTrunk Date: Fri, 25 Feb 2022 17:31:17 +0700 Subject: [PATCH 37/41] add exception to not throw on duplicate key --- ZelBack/src/services/serviceHelper.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ZelBack/src/services/serviceHelper.js b/ZelBack/src/services/serviceHelper.js index 017af7409..3cef51b73 100644 --- a/ZelBack/src/services/serviceHelper.js +++ b/ZelBack/src/services/serviceHelper.js @@ -156,12 +156,20 @@ async function findOneAndUpdateInDatabase(database, collection, query, update, o } async function insertOneToDatabase(database, collection, value) { - const result = await database.collection(collection).insertOne(value); + const result = await database.collection(collection).insertOne(value).catch((error) => { + if (!(error.message && error.message.includes('duplicate key'))) { + throw error; + } + }); return result; } async function insertManyToDatabase(database, collection, values, options = {}) { - const result = await database.collection(collection).insertMany(values, options); + const result = await database.collection(collection).insertMany(values, options).catch((error) => { + if (!(error.message && error.message.includes('duplicate key'))) { + throw error; + } + }); return result; } From adca6e19c7dc180a7c492d55d92bb263ba635dc5 Mon Sep 17 00:00:00 2001 From: Cabecinha84 <42519726+Cabecinha84@users.noreply.github.com> Date: Fri, 25 Feb 2022 10:41:25 +0000 Subject: [PATCH 38/41] Add processBlock logs --- ZelBack/src/services/explorerService.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ZelBack/src/services/explorerService.js b/ZelBack/src/services/explorerService.js index 7f8241214..aa3a4b53e 100644 --- a/ZelBack/src/services/explorerService.js +++ b/ZelBack/src/services/explorerService.js @@ -497,7 +497,7 @@ async function processBlock(blockHeight, isInsightExplorer) { const verbosity = 2; const blockDataVerbose = await getVerboseBlock(blockHeight, verbosity); if (blockDataVerbose.height % 50 === 0) { - console.log(blockDataVerbose.height); + log.info(`Processing Explorer Block Height: ${blockDataVerbose.height}`); } if (isInsightExplorer) { // only process Flux transactions From 6c71bc59b447215e7eab829abc6af198d1bc312d Mon Sep 17 00:00:00 2001 From: TheTrunk Date: Fri, 25 Feb 2022 17:55:03 +0700 Subject: [PATCH 39/41] add node collateral cache --- ZelBack/src/services/explorerService.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ZelBack/src/services/explorerService.js b/ZelBack/src/services/explorerService.js index 7f8241214..fdfe04c4e 100644 --- a/ZelBack/src/services/explorerService.js +++ b/ZelBack/src/services/explorerService.js @@ -1,4 +1,5 @@ const config = require('config'); +const LRU = require('lru-cache'); const log = require('../lib/log'); const serviceHelper = require('./serviceHelper'); @@ -19,6 +20,13 @@ let operationBlocked = false; let initBPfromNoBlockTimeout; let initBPfromErrorTimeout; +// cache for nodes +const LRUoptions = { + max: 12000, // store 12k of nodes value forever, no ttl +}; + +const nodeCollateralCache = new LRU(LRUoptions); + async function getSenderTransactionFromDaemon(txid) { const verbose = 1; const req = { @@ -37,6 +45,10 @@ async function getSenderTransactionFromDaemon(txid) { } async function getSenderForFluxTxInsight(txid, vout) { + const nodeCacheExists = nodeCollateralCache.get(`${txid}-${vout}`); + if (nodeCacheExists) { + return nodeCacheExists; + } const db = serviceHelper.databaseConnection(); const database = db.db(config.database.daemon.database); const queryFluxTx = { @@ -72,6 +84,7 @@ async function getSenderForFluxTxInsight(txid, vout) { address: transactionOutput.scriptPubKey.addresses[0], satoshis: transactionOutput.valueSat, }; + nodeCollateralCache.set(`${txid}-${vout}`, adjustedTxContent); return adjustedTxContent; } } @@ -85,11 +98,16 @@ async function getSenderForFluxTxInsight(txid, vout) { }; return adjustedTxContent; } + nodeCollateralCache.set(`${txid}-${vout}`, txContent); const sender = txContent; return sender; } async function getSenderForFluxTx(txid, vout) { + const nodeCacheExists = nodeCollateralCache.get(`${txid}-${vout}`); + if (nodeCacheExists) { + return nodeCacheExists; + } const db = serviceHelper.databaseConnection(); const database = db.db(config.database.daemon.database); const query = { @@ -140,6 +158,7 @@ async function getSenderForFluxTx(txid, vout) { return adjustedTxContent; } const sender = txContent; + nodeCollateralCache.set(`${txid}-${vout}`, txContent); return sender; } From 140952216aeebdf44ac7273174ca086944427002 Mon Sep 17 00:00:00 2001 From: Tadeas Kmenta Date: Sat, 26 Feb 2022 11:16:51 +0700 Subject: [PATCH 40/41] check for correct version of app running instances remove obsolete --- ZelBack/src/services/appsService.js | 35 ++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/ZelBack/src/services/appsService.js b/ZelBack/src/services/appsService.js index 2e05eaaaa..4f8504d0a 100644 --- a/ZelBack/src/services/appsService.js +++ b/ZelBack/src/services/appsService.js @@ -5459,8 +5459,12 @@ async function trySpawningGlobalApplication() { // check if app is installed on the number of instances requested const minInstances = appSpecifications.instances || config.fluxapps.minimumInstances; // introduced in v3 of apps specs + const correctlyRunningInstances = runningAppList.filter((appInstance) => appInstance.hash === appSpecifications.hash); // app isntance has to be latest version of the app if (runningAppList.length >= minInstances) { - log.info(`Application ${randomApp} is already spawned on ${runningAppList.length} instances`); + log.info(`Application ${randomApp} is spawned on ${runningAppList.length} instances`); + } + if (correctlyRunningInstances.length >= minInstances) { + log.info(`Application ${randomApp} in latest version is running on ${correctlyRunningInstances.length} instances`); await serviceHelper.delay(adjustedDelay); trySpawningGlobalAppCache.set(randomApp, randomApp); trySpawningGlobalApplication(); @@ -5785,16 +5789,27 @@ async function checkAndRemoveApplicationInstance() { const appDetails = await getApplicationGlobalSpecifications(installedApp.name); if (appDetails) { log.info(`Application ${installedApp.name} is already spawned on ${runningAppList.length} instances. Checking removal availability..`); - const randomNumber = Math.floor((Math.random() * config.fluxapps.removal.probability)); - if (randomNumber === 0) { - log.warn(`Removing application ${installedApp.name} locally`); - // eslint-disable-next-line no-await-in-loop - await removeAppLocally(installedApp.name); - log.warn(`Application ${installedApp.name} locally removed`); - // eslint-disable-next-line no-await-in-loop - await serviceHelper.delay(config.fluxapps.removal.delay * 1000); // wait for 6 mins so we dont have more removals at the same time + // get our version of app and compare to global + const correctlyRunningInstances = runningAppList.filter((appInstance) => appInstance.hash === appDetails.hash); // app isntance has to be latest version of the app + if (correctlyRunningInstances.length > (minInstances + config.fluxapps.maximumAdditionalInstances)) { + log.info(`Application ${installedApp.name} is already spawned on ${runningAppList.length} with latest version. Checking removal availability..`); + let randomNumber = Math.floor((Math.random() * config.fluxapps.removal.probability)); + if (installedApp.hash !== appDetails.hash) { // application is obsolete on our system. Remove + log.warn(`Application ${installedApp.name} is obsolete. Removing...`); + randomNumber = 0; + } + if (randomNumber === 0) { + log.warn(`Removing application ${installedApp.name} locally`); + // eslint-disable-next-line no-await-in-loop + await removeAppLocally(installedApp.name); + log.warn(`Application ${installedApp.name} locally removed`); + // eslint-disable-next-line no-await-in-loop + await serviceHelper.delay(config.fluxapps.removal.delay * 1000); // wait for 6 mins so we dont have more removals at the same time + } else { + log.info(`Other Fluxes are evaluating application ${installedApp.name} removal.`); + } } else { - log.info(`Other Fluxes are evaluating application ${installedApp.name} removal.`); + log.info(`Application ${installedApp.name} is undergoing an update. Removal not proceeded`); } } } From 845563f32fd4aba2b550dad3e7c68cd8a50f46ca Mon Sep 17 00:00:00 2001 From: Tadeas Kmenta Date: Sat, 26 Feb 2022 11:35:32 +0700 Subject: [PATCH 41/41] v3.9.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ed2db66e0..b705cfc5a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "flux", - "version": "3.8.1", + "version": "3.9.0", "description": "Flux, Your Gateway to a Decentralized World", "repository": { "type": "git",