FLO_Twitter/app/web/home.js
sairajzero 174b9fddf6 Improved user login and stability of funtions
Old prompt based user login and server connect are replaced with login page
Improved stability and simplification of functions
Moved all superNode functions to app.js
Supernode mode will now work in all pages (home,profile,msg) instead of just home
2019-07-24 03:01:29 +05:30

254 lines
9.5 KiB
JavaScript

var profiles, following;
var selfWebsocket,followingWebSockets = [];
var privKey, modSuperNode, selfID;
function viewHome(){
if( sessionStorage.profiles === undefined || sessionStorage.privKey === undefined || sessionStorage.selfID === undefined || sessionStorage.serverPass === undefined || sessionStorage.superNodeList === undefined ){
alert("Login credentials failed! Returning to login page!");
window.location.href = "index.html";
return;
}
profiles = JSON.parse(sessionStorage.profiles);
console.log(profiles);
privKey = encrypt.retrieveShamirSecret(JSON.parse(sessionStorage.privKey));
selfID = sessionStorage.selfID;
superNodeList = JSON.parse(sessionStorage.superNodeList);
if(superNodeList.includes(selfID))
modSuperNode = true;
kBucketObj.launchKBucket().then(function(result){
console.log(result);
initselfWebSocket();
listProfiles();
pingSuperNodeforNewMsgs();
getFollowinglistFromIDB().then(result => {
following = result;
if(!following.includes(selfID))
following.push(selfID);
console.log(following);
displayTweetsFromIDB().then(result => {
connectToAllFollowing();
}).catch(error => {
console.log(error);
})
}).catch(error => {
console.log(error);
})
}).catch(function(error){
console.log(error.message);
});
}
function initselfWebSocket(){
selfWebsocket = new WebSocket("ws://"+location.host+"/ws");
selfWebsocket.onopen = (event) => {
console.log("Connecting");
var serverPass = encrypt.retrieveShamirSecret(JSON.parse(sessionStorage.serverPass));
selfWebsocket.send("$"+serverPass);
};
selfWebsocket.onclose = (event) => { console.log("DISCONNECTED") };
selfWebsocket.onmessage = (event) => {
console.log(event.data);
if(event.data[0] == '$')
return;
try{
data = JSON.parse(event.data);
if(data.follow && encrypt.verify(selfID, data.sign, profiles[data.floID].pubKey)){
var idb = indexedDB.open("FLO_Tweet");
idb.onsuccess = (event) => {
var db = event.target.result;
var obs = db.transaction("followers", "readwrite").objectStore("followers");
obs.add(data.sign,data.floID);
db.close();
};
selfWebsocket.send(`F${data.floID}`);
}else if(data.unfollow && encrypt.verify(selfID, data.sign, profiles[data.floID].pubKey)){
var idb = indexedDB.open("FLO_Tweet");
idb.onsuccess = (event) => {
var db = event.target.result;
var obs = db.transaction("followers", "readwrite").objectStore("followers");
obs.delete(data.floID);
db.close();
};
selfWebsocket.send(`U${data.floID}`);
}else if(data.message && data.to == selfID){
var msg = encrypt.decryptMessage(data.secret,data.pubVal)
if(encrypt.verify(msg,data.sign,profiles[data.from].pubKey))
storeMsg({time:data.time,floID:data.from,text:msg,type:'R'});
}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);
}
}else if(modSuperNode){
superNodeMode(data);
}
}catch(error){
console.log(error.message);
}
};
selfWebsocket.onerror = (event) => { console.log(event) };
}
function listProfiles(){
console.log("listProfiles");
document.getElementById("profileName").innerHTML=profiles[selfID].name;
document.getElementById("profileFloID").innerHTML='@'+selfID;
var profileList = document.getElementById("profileList");
profileList.innerHTML = "";
for (p in profiles){
var element = document.createElement("div");
element.setAttribute("class", "media");
element.innerHTML = `<a href="profile.html?floID=${p}"><div class="media-body">
<h5 class="media-heading">${profiles[p].name}</h5>
<small>@${p}</small>
</div></a>`
profileList.appendChild(element);
}
}
function postTweet(){
var tweetBox = document.getElementById("tweetBox");
var tweet = tweetBox.value;
tweetBox.value = "";
var time = (new Date).getTime();
var sign = encrypt.sign(tweet,privKey);
var data = JSON.stringify({floID:selfID,time:time,tweet:tweet,sign:sign});
console.log(data);
selfWebsocket.send(data);
getLastTweetCount(selfID).then(result => {
var SNdata = JSON.stringify({newSuperNodeTweet:true,floID:selfID,tid:result+1,data:data});
sendDataToSuperNode(selfID,SNdata);
}).catch(error => {
console.log(error);
});
}
function getFollowinglistFromIDB(){
return new Promise((resolve,reject) => {
var idb = indexedDB.open("FLO_Tweet");
idb.onerror = (event) => { reject("Error in opening IndexedDB!") };
idb.onsuccess = (event) => {
var db = event.target.result;
var obs = db.transaction("following", "readwrite").objectStore("following");
var getReq = obs.getAllKeys();
getReq.onsuccess = (event) => { resolve(event.target.result) }
getReq.onerror = (event) => { reject('Unable to read following list!') }
db.close();
};
});
}
function displayTweetsFromIDB(){
return new Promise((resolve,reject) => {
var idb = indexedDB.open("FLO_Tweet");
idb.onerror = (event) => { reject("Error in opening IndexedDB!") };
idb.onsuccess = (event) => {
var db = event.target.result;
var obs = db.transaction("tweets", "readwrite").objectStore("tweets");
var curReq = obs.openCursor();
curReq.onsuccess = (event) => {
var cursor = event.target.result;
if(cursor) {
if(cursor.value.floID == selfID || following.includes(cursor.value.floID))
createTweetElement(cursor.value.floID,cursor.value.time,cursor.value.data);
cursor.continue();
}else{
resolve("Displayed Tweets from IDB!");
}
}
curReq.onerror = (event) => { reject("Error in Reading tweets from IDB!") }
db.close();
};
});
}
function createTweetElement(floID,time,tweet){
var tweetDisplay = document.getElementById("tweetsContainer");
var element = document.createElement("div");
element.setAttribute("class", "media");
element.innerHTML = `
<div class="media-body">
<h4 class="media-heading">${profiles[floID].name} <small>@${floID}</small></h4>
<p>${tweet.replace(/\n/g, "<br/>")}</p>
<ul class="nav nav-pills nav-pills-custom">
<li><a href="#"><span class="glyphicon glyphicon-share-alt"></span></a></li>
<li><a href="#"><span class="glyphicon glyphicon-retweet"></span></a></li>
<li><a href="#"><span class="glyphicon glyphicon-star"></span></a></li>
<li><a href="#"><span class="glyphicon glyphicon-option-horizontal"></span></a></li>
<li><span class="timestamp pull-right">${getTime(time)}</span></li>
</ul>
</div>`;
tweetDisplay.insertBefore(element, tweetDisplay.firstChild);
}
function connectToAllFollowing(){
console.log("Connecting to All following servers...")
following.forEach(floid => {
console.log(floid)
followingWebSockets[floid] = new WebSocket("ws://"+profiles[floid].onionAddr+"/ws");
followingWebSockets[floid].onopen = (event) => {
console.log(`Connected to ${floid} Server!`);
getLastTweetCount(floid).then(result => {
followingWebSockets[floid].send(`>${result}`);
}).catch(error => {
console.log(error);
});
};
followingWebSockets[floid].onerror = (event) => {
console.log(`${floid} Server is offline!`);
//Ping SuperNode for any new tweets
pingSuperNodeforNewTweets(floid);
};
followingWebSockets[floid].onclose = (event) => { console.log(`Disconnected from ${floid} Server!`); };
followingWebSockets[floid].onmessage = (event) => {
console.log(event.data);
try{
var data = JSON.parse(event.data);
var id = data.id;
data = data.data;
if( floid!=data.floID || !encrypt.verify(data.tweet,data.sign,profiles[floid].pubKey))
return
storeTweet({floID:data.floID,time:data.time,data:data.tweet},id);
createTweetElement(data.floID,data.time,data.tweet);
}catch(error){
console.log(error.message);
}
};
});
}
function getLastTweetCount(floid){
return new Promise((resolve,reject) => {
var idb = indexedDB.open("FLO_Tweet");
idb.onsuccess = (event) => {
var db = event.target.result;
var lastTweet = db.transaction('lastTweet', "readwrite").objectStore('lastTweet');
var lastTweetReq = lastTweet.get(floid);
lastTweetReq.onsuccess = (event) => {
var result = event.target.result;
if(result === undefined)
result = 0;
resolve(result);
}
db.close();
};
});
}
function pingSuperNodeforNewMsgs(){
var data = JSON.stringify({viaMsgreq:true,floID:selfID});
sendDataToSuperNode(selfID,data);
}
function pingSuperNodeforNewTweets(floID){
getLastTweetCount(floID).then(result => {
var data = JSON.stringify({reqNewTweets:true,floID:floID,tid:result,requestor:selfID})
sendDataToSuperNode(floID,data);
}).catch(error => {
console.log(error);
});
}