From 03ab7876b6aec5a54f1fd9b7e07201fbd43b00ee Mon Sep 17 00:00:00 2001 From: who-biz <37732338+who-biz@users.noreply.github.com> Date: Tue, 2 May 2023 21:43:05 +0000 Subject: [PATCH] Add '/sender' endpoint, compat for POST methods - Not completely functioning yet, but basics are --- app_mongo.js | 185 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 181 insertions(+), 4 deletions(-) diff --git a/app_mongo.js b/app_mongo.js index cbd4ee9..91e8b33 100644 --- a/app_mongo.js +++ b/app_mongo.js @@ -34,6 +34,7 @@ const { MongoClient } = require('mongodb'); const mime = require('mime-types') const url = require('url') const path = require('path') +const qs = require('querystring') // where is subfolder with your public files like index.html const baseDirectory = __dirname +"/public" @@ -182,9 +183,9 @@ setInterval(()=>{ const requestListener = function (req, res) { - if(req.method=="GET") { + if(req.method=="GET") { - try { + try { console.log(req.url) @@ -234,9 +235,16 @@ const requestListener = function (req, res) { case "/listener": { listener(requestUrl, res) - break; + break; } // case '/listener' + case "/sender": { + res.writeHead(400) + res.end("HTTP method GET is not supported by this URL") + console.log("Error: GET is not permitted on \"sender\" URL, use POST instead") + break; + } // case '/sender' + default: { var fileStream = fs.createReadStream(fsPath) res.setHeader("Content-Type",mime.contentType(path.extname(fsPath))) @@ -245,7 +253,7 @@ const requestListener = function (req, res) { res.writeHead(200) }) fileStream.on('error',function(e) { - res.end('No that file') + res.end('File does not exist') }) } // default } @@ -255,6 +263,59 @@ const requestListener = function (req, res) { res.end() // end the response so browsers don't hang console.log(e.stack) } + + } else if (req.method=="POST") { + + try { + console.log(req.url) + + var requestUrl = url.parse(req.url,true) + + // need to use path.normalize so people can't access directories underneath baseDirectory + var fsPath = baseDirectory+path.normalize(requestUrl.pathname) + + console.log(fsPath) + console.log(requestUrl) + + switch (requestUrl.pathname) { + + case "/sender": { + var requestBody = ''; + req.on('data', function(data) { + requestBody += data; + if(requestBody.length > 1e7) { + res.writeHead(413, 'Request Entity Too Large', {'Content-Type': 'text/html'}); + res.end('413413: Request Entity Too Large'); + } + }); + req.on('end', function() { + var formData = qs.parse(requestBody); + var obj = JSON.parse(JSON.stringify(formData)); + console.log("requestBody = " + requestBody); + console.log("formData =" + obj); + sender(requestUrl, formData, res) + }); + break; + } // case '/sender' + + default: { + var fileStream = fs.createReadStream(fsPath) + res.setHeader("Content-Type",mime.contentType(path.extname(fsPath))) + fileStream.pipe(res) + fileStream.on('open', function() { + res.writeHead(200) + }) + fileStream.on('error',function(e) { + res.end('File does not exist') + }) + } // default + } // switch + + } catch(e) { + res.writeHead(500) + res.end() // end the response so browsers don't hang + console.log(e.stack) + } } } @@ -334,6 +395,122 @@ function listener(requestUrl, res){ } } +function sender(requestUrl, requestBody, res) { + + try { + // trick + let jsonUrl = JSON.parse(JSON.stringify(requestUrl.query)) + + console.log(jsonUrl) + + if(jsonUrl.hasOwnProperty("address")) { + + console.log("OK") + + var destination; + let split = jsonUrl.address.search('@'); + if (split >= 0) { + destination = jsonUrl.address.split('@') + destination = destination[0] + } else { + destination = jsonUrl.address; + } + console.log("destination = " + destination); + + // here we check address!!! + + // use externally rust program to verify addresses - it is the same which is used to verify signatures + const childadd = execFile(pathtoepicboxlib, ['verifyaddress', jsonUrl.address, destination], (erroradr, stdoutadr, stderradr) => + { + if (erroradr) { + throw erroradr + } + + var destinationValid = (stdoutadr === 'true'); + + if(destinationValid) { + console.log("Destination address is valid, moving on..."); + // nothing else in URL, move onto checking request body + } + }) // end child + } + + console.log(requestBody); + if (requestBody.hasOwnProperty("mapmessage") && requestBody.hasOwnProperty("from") && requestBody.hasOwnProperty("signature")) { + + console.log("OK") + + var fromAddress; + let split = requestBody.from.search('@'); + if (split >= 0) { + fromAddress = requestBody.from.split('@') + fromAddress = fromAddress[0] + } else { + fromAddress = requestBody.from; + } + console.log("fromAddress = " + fromAddress); + + // here we check address!!! + + // use externally rust program to verify addresses - it is the same which is used to verify signatures + const childadd = execFile(pathtoepicboxlib, ['verifyaddress', requestBody.address, fromAddress], (erroradr, stdoutadr, stderradr) => + { + if (erroradr) { + throw erroradr + } + + var senderAddressValid = (stdoutadr === 'true'); + + if(senderAddressValid) { + + // use rust program to verify signatures if they signet timenow by private key of address public key + const child = execFile(pathtoepicboxlib, ["verifysignature", fromAddress, requestBody.mapmessage, requestBody.signature], (error, stdout, stderr) => { + + if (error) { + throw error; + } + var signatureValid = (stdout === 'true'); + + if(signatureValid){ + // TODO: add encrypted data to DB + const db = mongoclient.db(dbName); + console.log("Signature OK - Valid"); + + res.writeHead(200) + res.end("lastSeen: 1311110615") + + //const collection = db.collection(collectionname); + + // show all slates where address is from query - sender and receiver + //collection.find({queue:from, replyto:json.address}).project({ + // _id:0, queue:1, replyto:1, made:1, payload:1, createdat:1, expiration:1 } + // ).toArray().then((SlatesMany => + //{ + // res.setHeader("Content-Type", "application/json") + // res.writeHead(200) + // res.end(JSON.stringify({slates:SlatesMany})) + //})) + } else { + res.writeHead(200) + res.end(JSON.stringify({error:true, message:"wrong signature"})) + } + }) // end child + } else { + res.writeHead(200) + res.end(JSON.stringify({error:true, message:"wrong address"})) + } + }) // end childad + } else { + res.writeHead(200) + res.end(JSON.stringify({error:true, message:"not enough data"})) + } + } catch (e) { + res.writeHead(500) + res.end() // end the response so browsers don't hang + console.log(e.stack) + } +} + // // HTTMl server creation with function for receives requests // Used by WebSocketServer