From 39118fc39299b88c7ea9ecf9018ff1d5efd44e7c Mon Sep 17 00:00:00 2001 From: sairajzero Date: Tue, 16 Jul 2019 14:16:31 +0530 Subject: [PATCH] Extending superNode functionality to Profile page --- app/web/app.js | 14 +++++ app/web/home.js | 130 ++++++++++++++++++++++++++++++++++++--------- app/web/profile.js | 124 ++++++++++++++++++++++++++---------------- 3 files changed, 198 insertions(+), 70 deletions(-) diff --git a/app/web/app.js b/app/web/app.js index 82f9af7..0f808b2 100644 --- a/app/web/app.js +++ b/app/web/app.js @@ -999,3 +999,17 @@ kBucketObj = { }) } } + +function sendDataToSuperNode(floID,data){ + kBucketObj.determineClosestSupernode(floID).then(result=>{ + var superNodeWS = new WebSocket("ws://"+profiles[result[0].floID].onionAddr+"/ws"); + superNodeWS.onopen = function(ev){ + console.log(`Connected to ${floID}'s SuperNode!`); + superNodeWS.send(data); + }; + superNodeWS.onerror = function(ev) {console.log(`${floid}'s SuperNode is offline!`);}; + superNodeWS.onclose = function(ev) {console.log(`Disconnected from ${floid}'s SuperNode!`);}; + }).catch(e => { + console.log(e.message); + }); + } \ No newline at end of file diff --git a/app/web/home.js b/app/web/home.js index 1d167cb..9baa276 100644 --- a/app/web/home.js +++ b/app/web/home.js @@ -23,6 +23,7 @@ function userDataStartUp(){ getSuperNodeListfromIDB().then(function(result){ console.log(result) superNodeList = result; + sessionStorage.superNodeList = JSON.stringify(superNodeList); kBucketObj.launchKBucket().then(function(result){ console.log(result) getuserID().then(function(result){ @@ -35,6 +36,7 @@ function userDataStartUp(){ alert(`${selfID}\nWelcome ${profiles[selfID].name}`) initselfWebSocket(); listProfiles(); + pingSuperNodeforNewMsgs(); getFollowinglistFromIDB().then(function(result){ following = result; if(!following.includes(selfID)) @@ -338,7 +340,21 @@ function initselfWebSocket(){ }else if(data.newSuperNodeTweet){ kBucketObj.determineClosestSupernode(data.floID).then(result=>{ if(result[0].floID == selfID) - storeSuperNodeTweet(data.data,data.tid); + SuperNode_storeSuperNodeTweet(data.data,data.tid); + }).catch(e => { + console.log(e.message); + }); + }else if(data.viaSuperNodeMsg){ + kBucketObj.determineClosestSupernode(data.to).then(result=>{ + if(result[0].floID == selfID) + SuperNode_storeViaSuperNodeMsg(data.from,data.to,data.data); + }).catch(e => { + console.log(e.message); + }); + }else if(data.viaMsgreq){ + kBucketObj.determineClosestSupernode(data.floID).then(result=>{ + if(result[0].floID == selfID) + SuperNode_sendviaMsgFromIDB(data.floID); }).catch(e => { console.log(e.message); }); @@ -536,35 +552,34 @@ function getLastTweetCount(floid){ ); } +function pingSuperNodeforNewMsgs(){ + var data = JSON.stringify({viaMsgreq:true,floID:selfID}); + sendDataToSuperNode(selfID,data); +} + function pingSuperNodeforNewTweets(floID){ - kBucketObj.determineClosestSupernode(floID).then(result=>{ - var superNodeWS = new WebSocket("ws://"+profiles[result[0].floID].onionAddr+"/ws"); - superNodeWS.onopen = function(ev){ - console.log(`Connected to ${floID}'s SuperNode!`); - getLastTweetCount(floID).then(function(result){ - var data = JSON.stringify({reqNewTweets:true,floID:floID,tid:result,requestor:selfID}) - superNodeWS.send(data); - }).catch(function(error){ - console.log(error.message); - }); - }; - superNodeWS.onerror = function(ev) {console.log(`${floid}'s SuperNode is offline!`);}; - superNodeWS.onclose = function(ev) {console.log(`Disconnected from ${floid}'s SuperNode!`);}; - }).catch(e => { - console.log(e.message); + getLastTweetCount(floID).then(function(result){ + var data = JSON.stringify({reqNewTweets:true,floID:floID,tid:result,requestor:selfID}) + sendDataToSuperNode(floID,data); + }).catch(function(error){ + console.log(error.message); }); } -function storeSuperNodeTweet(data,tid){ +function SuperNode_storeSuperNodeTweet(data,tid){ var idb = indexedDB.open("FLO_Tweet",2); idb.onerror = function(event) { console.log("Error in opening IndexedDB!"); }; idb.onupgradeneeded = function(event){ - var objectStore = event.target.result.createObjectStore("superNodeTweet",{ keyPath: 'tweetID' }); - objectStore.createIndex('floID', 'floID', { unique: false }); - objectStore.createIndex('tid', 'tid', { unique: false }); - objectStore.createIndex('data', 'data', { unique: false }); + var objectStore1 = event.target.result.createObjectStore("superNodeTweet",{ keyPath: 'tweetID' }); + objectStore1.createIndex('floID', 'floID', { unique: false }); + objectStore1.createIndex('tid', 'tid', { unique: false }); + objectStore1.createIndex('data', 'data', { unique: false }); + var objectStore2 = event.target.result.createObjectStore("viaSuperNodeMsg",{ keyPath: 'id',autoIncrement:true }); + objectStore2.createIndex('from', 'from', { unique: false }); + objectStore2.createIndex('to', 'to', { unique: false }); + objectStore2.createIndex('data', 'data', { unique: false }); } idb.onsuccess = function(event) { var db = event.target.result; @@ -576,6 +591,29 @@ function storeSuperNodeTweet(data,tid){ }; } +function SuperNode_storeViaSuperNodeMsg(from,to,data){ + var idb = indexedDB.open("FLO_Tweet",2); + idb.onerror = function(event) { + console.log("Error in opening IndexedDB!"); + }; + idb.onupgradeneeded = function(event){ + var objectStore1 = event.target.result.createObjectStore("superNodeTweet",{ keyPath: 'tweetID' }); + objectStore1.createIndex('floID', 'floID', { unique: false }); + objectStore1.createIndex('tid', 'tid', { unique: false }); + objectStore1.createIndex('data', 'data', { unique: false }); + var objectStore2 = event.target.result.createObjectStore("viaSuperNodeMsg",{ keyPath: 'id',autoIncrement :true }); + objectStore2.createIndex('from', 'from', { unique: false }); + objectStore2.createIndex('to', 'to', { unique: false }); + objectStore2.createIndex('data', 'data', { unique: false }); + } + idb.onsuccess = function(event) { + var db = event.target.result; + var obs = db.transaction("viaSuperNodeMsg", "readwrite").objectStore("viaSuperNodeMsg"); + obs.add({from:from,to:to,data:data}); + db.close(); + }; +} + function SuperNode_sendTweetsFromIDB(floID,tid,requestor){ return new Promise( function(resolve,reject){ @@ -588,10 +626,14 @@ function SuperNode_sendTweetsFromIDB(floID,tid,requestor){ reject("Error in opening IndexedDB!"); }; idb.onupgradeneeded = function(event){ - var objectStore = event.target.result.createObjectStore("superNodeTweet",{ keyPath: 'tweetID' }); - objectStore.createIndex('floID', 'floID', { unique: false }); - objectStore.createIndex('tid', 'tid', { unique: false }); - objectStore.createIndex('data', 'data', { unique: false }); + var objectStore1 = event.target.result.createObjectStore("superNodeTweet",{ keyPath: 'tweetID' }); + objectStore1.createIndex('floID', 'floID', { unique: false }); + objectStore1.createIndex('tid', 'tid', { unique: false }); + objectStore1.createIndex('data', 'data', { unique: false }); + var objectStore2 = event.target.result.createObjectStore("viaSuperNodeMsg",{ keyPath: 'id',autoIncrement:true }); + objectStore2.createIndex('from', 'from', { unique: false }); + objectStore2.createIndex('to', 'to', { unique: false }); + objectStore2.createIndex('data', 'data', { unique: false }); } idb.onsuccess = function(event) { var db = event.target.result; @@ -625,3 +667,41 @@ function SuperNode_sendTweetsFromIDB(floID,tid,requestor){ ); } +function SuperNode_sendviaMsgFromIDB(floID){ + var receiverWS = new WebSocket("ws://"+contacts[floID].onionAddr+"/ws"); + receiverWS.onopen = function(ev){ + var idb = indexedDB.open("FLO_Chat",2); + idb.onerror = function(event) { + console.log("Error in opening IndexedDB!"); + }; + idb.onupgradeneeded = function(event) { + var objectStore1 = event.target.result.createObjectStore("superNodeTweet",{ keyPath: 'tweetID' }); + objectStore1.createIndex('floID', 'floID', { unique: false }); + objectStore1.createIndex('tid', 'tid', { unique: false }); + objectStore1.createIndex('data', 'data', { unique: false }); + var objectStore2 = event.target.result.createObjectStore("viaSuperNodeMsg",{ keyPath: 'id',autoIncrement:true }); + objectStore2.createIndex('from', 'from', { unique: false }); + objectStore2.createIndex('to', 'to', { unique: false }); + objectStore2.createIndex('data', 'data', { unique: false }); + }; + idb.onsuccess = function(event) { + var db = event.target.result; + var obs = db.transaction("viaSuperNodeMsg", "readwrite").objectStore("viaSuperNodeMsg"); + obs.openCursor().onsuccess = function(event) { + var cursor = event.target.result; + if(cursor) { + if(cursor.value.to == floID){ + receiverWS.send(cursor.value.data); + cursor.delete(); + } + cursor.continue(); + }else{ + console.log('Sent All messages to '+floID) + } + } + db.close(); + }; + }; + receiverWS.onerror = function(ev) { console.log('Connection Error to '+floID) }; + receiverWS.onclose = function(ev) { console.log('Disconnected from '+floID) }; +} \ No newline at end of file diff --git a/app/web/profile.js b/app/web/profile.js index c6fa1b6..82da089 100644 --- a/app/web/profile.js +++ b/app/web/profile.js @@ -1,7 +1,7 @@ -var profileWebsocket, selfWebsocket; +var profileWebsocket, selfWebsocket,profileServerStatus; var profiles; -var floID, privKey, selfID; +var profileID, privKey, selfID; function viewProfile(){ if( sessionStorage.profiles === undefined || sessionStorage.privKey === undefined || sessionStorage.selfID === undefined || sessionStorage.serverPass === undefined){ @@ -14,19 +14,25 @@ function viewProfile(){ privKey = encrypt.retrieveShamirSecret(JSON.parse(sessionStorage.privKey)); selfID = sessionStorage.selfID; var url = new URL(window.location.href); - floID = url.searchParams.get("floID"); - listProfiles(); - displayProfile(floID); + profileID = url.searchParams.get("floID"); + superNodeList = JSON.parse(sessionStorage.superNodeList); + kBucketObj.launchKBucket().then(function(result){ + console.log(result) + listProfiles(); + displayProfile(profileID); + }).catch(function(error){ + console.log(error.message); + }); } -function displayProfile(floID){ - console.log(floID); +function displayProfile(profileID){ + console.log(profileID); var errorMsg; - if(!floID) + if(!profileID) errorMsg = "Select a Profile to display"; - else if(!validateAddr(floID)) + else if(!validateAddr(profileID)) errorMsg = "Invalid FLO ID"; - else if(!(floID in profiles)) + else if(!(profileID in profiles)) errorMsg = "FLO ID not registered to FLO Tweet"; if(errorMsg !== undefined){ @@ -35,15 +41,18 @@ function displayProfile(floID){ } console.log("displayProfile"); - document.getElementById("profileName").innerHTML=profiles[floID].name; - document.getElementById("profileFloID").innerHTML='@'+floID; + document.getElementById("profileName").innerHTML=profiles[profileID].name; + document.getElementById("profileFloID").innerHTML='@'+profileID; initselfWebSocket(); - displayTweetFromIDB(floID).then(function(result){ - connectToX(floID).then(function(result){ + displayTweetFromIDB(profileID).then(function(result){ + connectToX(profileID).then(function(result){ console.log(result); - getTweetsFromX(floID); + profileServerStatus = true; + getTweetsFromX(profileID); }).catch(function(error){ - console.log(error.message); + console.log(error); + pingSuperNodeforNewTweets(profileID); + profileServerStatus = false; }); }).catch(function(error){ console.log(error.message); @@ -116,7 +125,7 @@ function connectToX(floID){ resolve("Connected to Profile Server!"); }; profileWebsocket.onerror = function(ev) { - reject("Profile Server is offline!"); + reject("Profile Server is offline!"); }; profileWebsocket.onclose = function(ev) { console.log("Disconnected from Profile Server!") @@ -155,29 +164,19 @@ function storeTweet(data,id){ }; } +function pingSuperNodeforNewTweets(floID){ + getLastTweetCount(floID).then(function(result){ + var data = JSON.stringify({reqNewTweets:true,floID:floID,tid:result,requestor:selfID}) + sendDataToSuperNode(floID,data); + }).catch(function(error){ + console.log(error.message); + }); +} + function getTweetsFromX(floID){ return new Promise( function (resolve,reject){ - var idb = indexedDB.open("FLO_Tweet"); - idb.onerror = function(event) { - reject("Error in opening IndexedDB!"); - }; - idb.onsuccess = function(event) { - var db = event.target.result; - //window["wait"] = addrList.length; - var lastTweet = db.transaction('lastTweet', "readwrite").objectStore('lastTweet'); - //addrList.forEach(function(addr){ - new Promise( - function(res,rej){ - var lastTweetReq = lastTweet.get(floID); - lastTweetReq.onsuccess = function(event){ - var result = event.target.result; - if(result === undefined){ - result = 0; - } - res(result); - } - }).then(function(result){ + getLastTweetCount(floID).then(function(result){ console.log(profileWebsocket); profileWebsocket.send(`>${result}`); console.log("sent"); @@ -185,6 +184,24 @@ function getTweetsFromX(floID){ }).catch(function(error){ console.log(error.message); }); + } + ); +} + +function getLastTweetCount(floid){ + return new Promise( + function(resolve,reject){ + var idb = indexedDB.open("FLO_Tweet"); + idb.onsuccess = function(event) { + var db = event.target.result; + var lastTweet = db.transaction('lastTweet', "readwrite").objectStore('lastTweet'); + var lastTweetReq = lastTweet.get(floid); + lastTweetReq.onsuccess = function(event){ + var result = event.target.result; + if(result === undefined) + result = 0; + resolve(result); + } db.close(); }; } @@ -225,6 +242,13 @@ function initselfWebSocket(){ db.close(); }; selfWebsocket.send(`U${data.floID}`); + }else if(data.fromSuperNode && following.includes(data.floID)){ + var tid = data.tid; + data = JSON.parse(data.data); + if(encrypt.verify(data.tweet,data.sign,profiles[data.floID].pubKey)){ + storeTweet({floID:data.floID,time:data.time,data:data.tweet},tid); + createTweetElement(data.floID,data.time,data.tweet); + } } }catch(error){ console.log(error.message) @@ -238,30 +262,40 @@ function initselfWebSocket(){ function follow(){ var followBtn = document.getElementById("follow-button"); if(followBtn.value == 'follow'){ - var sign = encrypt.sign(floID,privKey); + var sign = encrypt.sign(profileID,privKey); var data = JSON.stringify({follow:true, floID:selfID, sign:sign}); - profileWebsocket.send(data); - selfWebsocket.send(`f${floID}-${sign}`) + if(profileServerStatus) + profileWebsocket.send(data); + else{ + var SNdata = JSON.stringify({viaSuperNodeMsg:true,from:selfID,to:profileID,data:data}) + sendDataToSuperNode(profileID,SNdata) + } + selfWebsocket.send(`f${profileID}-${sign}`) var idb = indexedDB.open("FLO_Tweet"); idb.onsuccess = function(event) { var db = event.target.result; var obs = db.transaction("following", "readwrite").objectStore("following"); - obs.add(sign,floID); + obs.add(sign,profileID); db.close(); }; followBtn.value = 'unfollow'; followBtn.innerHTML = "- Unfollow"; } else if(followBtn.value == 'unfollow'){ - var sign = encrypt.sign(floID,privKey); + var sign = encrypt.sign(profileID,privKey); var data = JSON.stringify({unfollow:true, floID:selfID, sign:sign}); - profileWebsocket.send(data); - selfWebsocket.send(`u${floID}`) + if(profileServerStatus) + profileWebsocket.send(data); + else{ + var SNdata = JSON.stringify({viaSuperNodeMsg:true,from:selfID,to:profileID,data:data}) + sendDataToSuperNode(profileID,SNdata) + } + selfWebsocket.send(`u${profileID}`) var idb = indexedDB.open("FLO_Tweet"); idb.onsuccess = function(event) { var db = event.target.result; var obs = db.transaction("following", "readwrite").objectStore("following"); - obs.delete(floID); + obs.delete(profileID); db.close(); }; followBtn.value = 'follow';