Compare commits

...

3 Commits

Author SHA1 Message Date
Sai Raj
18e18b882c
Update README.md 2020-08-10 13:57:30 +05:30
Sai Raj
62983c8f4f
Add files via upload 2020-08-10 13:56:24 +05:30
Vivek Teega
9e813c8c21 Uploading files for inspection 2020-08-10 12:46:44 +05:30
18 changed files with 58224 additions and 8 deletions

4
.config Normal file
View File

@ -0,0 +1,4 @@
SERVER_PWD=
BROWSER=firefox
PORT=
SERVER_PAGE=webAppServer.html

View File

@ -1,9 +1,44 @@
# TEDxKanke # webAppServer
TEDxKanke Event Management App This server is used to get the appObjects and generalData for the webApp clients without the need for blockchain or supernode cloud
### scanner-tedxkanke.html ## Instructions
This webpage is used to view and manage the content of TEDxKanke app
Uses floSight (for Blockchain data) and Supernode cloud
### monitor-tedxkanke.html ### To run the server
This is a fast loading webpage that gets the direct data from the webAppServer 1. Clone/download this repository
2. Add a strong `<server_password>` in `.config` file
3. Add the `<port>` in `.config` file for the server to run
4. open terminal in the directory and run `./start_webAppServer.sh`
### To use in client side
1. copy the floGlobals and webAppClient script tag to the webApp page
2. Add the server's `<website_url/ip_addr>:<port>` in floGlobals script tag
### Properties
#### sendGeneralData
webAppClient.sendGeneralData(message, type, options = {})
Sends a message to the cloud via webAppServer
* message: content of the message
* type: type of the message
#### requestGeneralData
webAppClient.requestGeneralData(type, vectorClock = '0')
Requests the generalData from webAppServer
* type: type of the message
* vectorClock: vectorClock after which the message should be requested (can be used with Date.now()) (default = '0')
* Returns an object (set of generalData)
#### requestObjectData
webAppClient.requestObjectData(keyPath)
Requests the objectData/appObjects from webAppServer
* path: (an Array) path of the required object (eg. \['Sample', Property1, property2..]
* Returns an Object/Array (requested path)
#### requestSubAdminList
webAppClient.requestSubAdminList()
Requests the subAdmin list of the application from webAppServer
* Returns an Array (of subAdmins)
### Architecture Diagram
![TEDxKanke-Architecture.png](util/TEDxKanke-Architecture.png)

13702
app/autoRefreshapp.html Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1073,4 +1073,4 @@
} }
</script> </script>
</body> </body>
</html> </html>

11603
app/scanner.html Normal file

File diff suppressed because it is too large Load Diff

121
app/webAppClient.html Normal file
View File

@ -0,0 +1,121 @@
<html>
<head>
<script id="floGlobals">
/* Constants for FLO blockchain operations !!Make sure to add this at begining!! */
const floGlobals = {
blockchain: "FLO",
adminID: "FKAEdnPfjXLHSYwrXQu377ugN4tXU7VGdf",
webAppURL: "<website_url/ip_addr>:<port>",
application: "TEST_MODE"
}
</script>
</head>
<body>
TEST_MODE (use console)
<script id="webAppClient">
//Add this to the client script to request data from floWebappServer
const webAppClient = {
util: {
sendData(data) {
return new Promise((resolve, reject) => {
var websocket = new WebSocket("wss://" + floGlobals.webAppURL + "/ws");
websocket.onmessage = (evt => {
if (evt.data == '$+') {
websocket.send(data);
resolve(`Data sent to webApp`);
} else if (evt.data == '$-')
reject(`webApp not available`)
else
reject(evt.data)
websocket.close();
})
websocket.onerror = (evt) => {
reject(`webApp server not found`)
};
})
},
requestData(request = []) {
return new Promise((resolve, reject) => {
var websocket = new WebSocket("wss://" + floGlobals.webAppURL + "/ws");
websocket.onmessage = (evt => {
if (evt.data == '$+') {
websocket.send(`?${JSON.stringify(request)}`);
} else if (evt.data == '$-') {
reject(`webApp not available`)
websocket.close()
} else {
resolve(JSON.parse(evt.data));
websocket.close();
}
})
websocket.onerror = (evt) => {
reject(`webApp server not found`)
};
})
}
},
sendGeneralData: function (message, type, options = {}) {
return new Promise((resolve, reject) => {
var data = {
senderID: myFloID,
receiverID: options.receiverID || floGlobals.adminID,
pubKey: myPubKey,
message: message,
sign: floCrypto.signData(JSON.stringify(message), myPrivKey),
application: options.application || floGlobals.application,
type: type,
comment: options.comment || ""
}
this.util.sendData(JSON.stringify(data), data.receiverID)
.then(result => resolve(result))
.catch(error => reject(error))
})
},
requestGeneralData: function (type, vectorClock = '0') {
if (typeof vectorClock !== 'string')
vectorClock.toString()
return new Promise((resolve, reject) => {
this.util.requestData([floGlobals.application, 'generalData', type, vectorClock])
.then(
result => {
if (result[0])
resolve(result[1])
else
reject(result[1])
}).catch(error => reject(error))
})
},
requestObjectData: function (keyPath) {
return new Promise((resolve, reject) => {
this.util.requestData([floGlobals.application, 'appObjects'].concat(keyPath)).then(
result => {
if (result[0])
resolve(result[1])
else
reject(result[1])
}).catch(error => reject(error))
})
},
requestSubAdminList: function(){
return new Promise((resolve, reject) => {
this.util.requestData([floGlobals.application, 'subAdmins']).then(
result => {
if (result[0])
resolve(result[1])
else
reject(result[1])
}).catch(error => reject(error))
})
}
}
</script>
</body>
</html>

282
app/webAppServer.html Normal file
View File

@ -0,0 +1,282 @@
<html>
<head>
<title>FLO webApp Server</title>
<script id="onLoadStartUp">
function onLoadStartUp() {
const apps = ['TEDxKanke']
webAppServer.setServeAppList(apps)
var consoleClear = setInterval(console.clear, 60 * 60000) // clear console every 1 hr
webAppServer.initWebSocket()
.then(result => console.log(result))
.catch(error => console.error(error))
}
</script>
</head>
</html>
<body onload="onLoadStartUp()">
<script id="compactIDB">
/* Compact IndexedDB operations */
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
if (!window.indexedDB)
window.alert("Your browser doesn't support a stable version of IndexedDB.")
const compactIDB = {
setDefaultDB: function (dbName) {
this.dbName = dbName;
},
initDB: function (dbName, objectStores = {}) {
return new Promise((resolve, reject) => {
this.dbName = this.dbName || dbName;
var idb = indexedDB.open(dbName);
idb.onerror = (event) => {
reject("Error in opening IndexedDB!");
};
idb.onupgradeneeded = (event) => {
var db = event.target.result;
for (obs in objectStores) {
var objectStore = db.createObjectStore(obs, objectStores[obs].options ||
{});
if (objectStores[obs].indexes && typeof objectStores[obs].indexes ===
'object')
for (i in objectStores[obs].indexes)
objectStore.createIndex(i, i, objectStores[obs].indexes[i] ||
{});
}
}
idb.onsuccess = (event) => {
var db = event.target.result;
if (JSON.stringify(Object.values(db.objectStoreNames).sort()) === JSON
.stringify(Object.keys(
objectStores).sort()))
resolve("Initiated IndexedDB");
else
reject("IndexedDB already exist with different ObjectStores!");
db.close();
}
});
},
openDB: function (dbName = this.dbName) {
return new Promise((resolve, reject) => {
var idb = indexedDB.open(dbName);
idb.onerror = (event) => reject("Error in opening IndexedDB!");
idb.onsuccess = (event) => resolve(event.target.result);
});
},
deleteDB: function (dbName = this.dbName) {
return new Promise((resolve, reject) => {
var deleteReq = indexedDB.deleteDatabase(dbName);;
deleteReq.onerror = (event) => reject("Error deleting database!");
deleteReq.onsuccess = (event) => resolve("Database deleted successfully");
});
},
addData: function (obsName, data, key = false, dbName = this.dbName) {
return new Promise((resolve, reject) => {
this.openDB(dbName).then(db => {
var obs = db.transaction(obsName, "readwrite").objectStore(obsName);
let addReq = (key ? obs.add(data, key) : obs.add(data));
addReq.onsuccess = (evt) => resolve(`Add data successful`);
addReq.onerror = (evt) => reject(
`Add data unsuccessful [${evt.target.error.name}] ${evt.target.error.message}`
);
db.close();
}).catch(error => reject(error));
});
},
removeData: function (obsName, key, dbName = this.dbName) {
return new Promise((resolve, reject) => {
this.openDB(dbName).then(db => {
var obs = db.transaction(obsName, "readwrite").objectStore(obsName);
let delReq = obs.delete(key);
delReq.onsuccess = (evt) => resolve(`Removed Data ${key}`);
delReq.onerror = (evt) => reject(
`Remove data unsuccessful [${evt.target.error.name}] ${evt.target.error.message}`
);
db.close();
}).catch(error => reject(error));
});
},
readData: function (obsName, key, dbName = this.dbName) {
return new Promise((resolve, reject) => {
this.openDB(dbName).then(db => {
var obs = db.transaction(obsName, "readonly").objectStore(obsName);
let getReq = obs.get(key);
getReq.onsuccess = (evt) => resolve(evt.target.result);
getReq.onerror = (evt) => reject(
`Read data unsuccessful [${evt.target.error.name}] ${evt.target.error.message}`
);
db.close();
}).catch(error => reject(error));
});
},
readAllData: function (obsName, dbName = this.dbName) {
return new Promise((resolve, reject) => {
this.openDB(dbName).then(db => {
var obs = db.transaction(obsName, "readonly").objectStore(obsName);
var tmpResult = {}
let curReq = obs.openCursor();
curReq.onsuccess = (evt) => {
var cursor = evt.target.result;
if (cursor) {
tmpResult[cursor.primaryKey] = cursor.value;
cursor.continue();
} else
resolve(tmpResult);
}
curReq.onerror = (evt) => reject(
`Read-All data unsuccessful [${evt.target.error.name}] ${evt.target.error.message}`
);
db.close();
}).catch(error => reject(error));
});
},
searchData: function (obsName, patternEval, dbName = this.dbName) {
return new Promise((resolve, reject) => {
this.openDB(dbName).then(db => {
var obs = db.transaction(obsName, "readonly").objectStore(obsName);
var filteredResult = {}
let curReq = obs.openCursor();
curReq.onsuccess = (evt) => {
var cursor = evt.target.result;
if (cursor) {
if (patternEval(cursor.primaryKey, cursor.value))
filteredResult[cursor.primaryKey] = cursor.value;
cursor.continue();
} else
resolve(filteredResult);
}
curReq.onerror = (evt) => reject(
`Search unsuccessful [${evt.target.error.name}] ${evt.target.error.message}`
);
db.close();
}).catch(error => reject(error));
});
}
}
</script>
<script id="webAppServer">
const webAppServer = {
util: {
objectDataFetch(object, path) {
var pos = object;
path.forEach(p => pos = pos[p])
return pos
},
getNextGeneralData: function (generalData, vectorClock) {
var filteredResult = []
for (var i = 0; i < generalData.length; i++)
if (generalData[i].vectorClock > vectorClock)
filteredResult.push(generalData[i])
return filteredResult
},
getFilterString: function(application, type, comment = undefined){
var filterStr = JSON.stringify({application: application, type: type, comment: comment})
return filterStr
}
},
serveAppList: [],
setServeAppList: function(appList = []){
this.serveAppList = appList
},
initWebSocket: function () {
return new Promise((resolve, reject) => {
try {
console.log("Attempting to connect to websocket server")
this.webSocket = new WebSocket("ws://" + location.host + "/ws");
this.webSocket.onopen = (evt) => {
console.log("Connected to websocket server")
this.webSocket.send("$" + location.hash.substr(1));
};
this.webSocket.onclose = (evt) => {
console.log("Disconnected from websocket server");
this.initWebSocket()
.then(result => console.log(result))
.catch(error => console.error(error))
}
this.webSocket.onmessage = (evt) => {
if (evt.data[0] == '$') {
if (evt.data == '$Access Granted!')
resolve("Access Granted!");
else if (evt.data == '$Access Denied!')
reject("Access Denied!");
else
console.log(evt.data.substr(1))
}
else if (evt.data[0] == '?') {
var request = evt.data.substr(1).split(" ");
var requestor = request[0]
request = JSON.parse(request[1])
try{
if (!this.serveAppList.includes(request[0]))
throw Error("This application is not served by the webApp")
if(request[1] == "appObjects"){
compactIDB.readData(request[1], request[2], request[0]).then(result => {
var response = [true, this.util.objectDataFetch(result, request.slice(3))]
console.log(request, response)
this.webSocket.send(`${requestor} ${JSON.stringify(response)}`)
})
}
else if (request[1] == "generalData"){
var filterStr = this.util.getFilterString(request[0], request[2])
compactIDB.readData(request[1], filterStr, request[0]).then(result => {
var response = [true, this.util.getNextGeneralData(result, request[3])]
console.log(request, response)
this.webSocket.send(`${requestor} ${JSON.stringify(response)}`)
})
}
else if(request[1] == "subAdmins"){
compactIDB.readAllData(request[1], request[0]).then(result => {
var response = [true, Object.keys(result)]
console.log(request, response)
this.webSocket.send(`${requestor} ${JSON.stringify(response)}`)
})
}
else
throw Error('Invalid Request! Only subAdmins, appObjects and generalData can be requested')
}catch(error){
response = [false, error.message]
this.webSocket.send(`${requestor} ${JSON.stringify(response)}`)
}
} else {
var data = JSON.parse(evt.data)
if (this.serveAppList.includes(data.application))
floSupernode.sendData(JSON.stringify(data), data.receiverID)
.then(result => resolve(result))
.catch(error => reject(error))
}
};
this.webSocket.onerror = (evt) => {
reject("Error! Unable to connect websocket server");
};
} catch (error) {
reject(error)
}
})
}
}
</script>
</body>

BIN
app/webSocketServer.bin Normal file

Binary file not shown.

2
logs/Readme.md Normal file
View File

@ -0,0 +1,2 @@
All logs are stored in this directory
NOTE: DO NOT delete this directory

18
logs/app.log Normal file
View File

@ -0,0 +1,18 @@
Wed Feb 26 11:50:36 UTC 2020 : Starting webApp
Wed Feb 26 12:18:40 UTC 2020 : Starting webApp
Mon Mar 2 13:13:38 UTC 2020 : Starting webApp
Mon Mar 2 13:16:18 UTC 2020 : Starting webApp
Mon Mar 2 13:30:00 UTC 2020 : Starting webApp
Tue Mar 3 09:26:12 UTC 2020 : Starting webApp
Mon Mar 16 13:33:08 UTC 2020 : Starting webApp
Mon Mar 16 13:41:39 UTC 2020 : Starting webApp
Fri Apr 17 20:05:31 UTC 2020 : Starting webApp
Fri Apr 17 20:06:34 UTC 2020 : Starting webApp
Fri Jun 12 20:43:11 UTC 2020 : Starting webApp
Fri Jun 12 20:46:12 UTC 2020 : Starting webApp
Fri Jun 12 20:47:56 UTC 2020 : Starting webApp
Sat Jun 13 16:16:40 UTC 2020 : Starting webApp
Mon Jun 15 17:15:13 UTC 2020 : Starting webApp
Mon Aug 10 06:22:47 UTC 2020 : Starting webApp
Mon Aug 10 06:25:58 UTC 2020 : Starting webApp
Mon Aug 10 06:42:05 UTC 2020 : Starting webApp

18
logs/browser.log Normal file
View File

@ -0,0 +1,18 @@
Wed Feb 26 11:50:36 UTC 2020
Wed Feb 26 12:18:40 UTC 2020
Mon Mar 2 13:13:38 UTC 2020
Mon Mar 2 13:16:18 UTC 2020
Mon Mar 2 13:30:00 UTC 2020
Tue Mar 3 09:26:12 UTC 2020
Mon Mar 16 13:33:08 UTC 2020
Mon Mar 16 13:41:39 UTC 2020
Fri Apr 17 20:05:31 UTC 2020
Fri Apr 17 20:06:34 UTC 2020
Fri Jun 12 20:43:11 UTC 2020
Fri Jun 12 20:46:12 UTC 2020
Fri Jun 12 20:47:56 UTC 2020
Sat Jun 13 16:16:40 UTC 2020
Mon Jun 15 17:15:13 UTC 2020
Mon Aug 10 06:22:47 UTC 2020
Mon Aug 10 06:25:58 UTC 2020
Mon Aug 10 06:42:05 UTC 2020

9008
logs/server.log Normal file

File diff suppressed because it is too large Load Diff

20
start_webAppServer.sh Normal file
View File

@ -0,0 +1,20 @@
#!/bin/sh
current_date=$(date)
echo "$current_date : Starting webApp" >> logs/app.log
#Read configurations
IFS="="
while read -r var value
do
export "$var"="${value}"
done < .config
#Start the app
echo $current_date >> logs/server.log
app/webSocketServer.bin $PORT $SERVER_PWD >> logs/server.log &
echo $current_date >> logs/browser.log
$BROWSER --headless "http://localhost:$PORT/$SERVER_PAGE#$SERVER_PWD" >> logs/browser.log &
$BROWSER --headless "http://localhost:$PORT/autoRefreshapp.html" >> logs/browser.log &
wait

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

16548
util/mongoose.c Normal file

File diff suppressed because it is too large Load Diff

6683
util/mongoose.h Normal file

File diff suppressed because it is too large Load Diff

172
util/websocket.c Normal file
View File

@ -0,0 +1,172 @@
/*
* Copyright (c) 2014 Cesanta Software Limited
* All rights reserved
*/
#include "mongoose.h"
static sig_atomic_t s_signal_received = 0;
static struct mg_serve_http_opts s_http_server_opts;
static char *s_http_port, *server_pwd;
static struct mg_connection *node = NULL;
static void signal_handler(int sig_num) {
signal(sig_num, signal_handler); // Reinstantiate signal handler
s_signal_received = sig_num;
}
//Display Message in console/terminal
static void display(struct mg_connection *nc, char type[25]){
char addr[32];
mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr), MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
printf("%s\t%s\n", addr, type);
}
//Broadcast incoming message (from nc to all)
static void broadcast(struct mg_connection *nc, const struct mg_str msg) {
char addr[32];
mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr), MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
printf("%s\tBroadcast\t[%d]\n", addr, (int)msg.len);
struct mg_connection *c;
for (c = mg_next(nc->mgr, NULL); c != NULL; c = mg_next(nc->mgr, c)) {
if (c == nc) continue; /* Don't send to the sender. */
mg_send_websocket_frame(c, WEBSOCKET_OP_TEXT, msg.p, msg.len);
}
}
//Unicast message (to nc)
static void unicast(struct mg_connection *nc, const struct mg_str msg) {
char addr[32];
mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr), MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
printf("%s\tUnicast\t[%d]\n", addr, (int)msg.len);
if(nc != NULL)
mg_send_websocket_frame(nc, WEBSOCKET_OP_TEXT, msg.p, msg.len);
}
//Forward message (from nc to supernode)
static void unicast_forward(struct mg_connection *nc, const struct mg_str msg) {
char addr[32];
mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr), MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
printf("%s\tForward\t[%d]\n", addr, (int)msg.len);
if(node != NULL)
mg_send_websocket_frame(node, WEBSOCKET_OP_TEXT, msg.p, msg.len);
else
printf("webApp_node is offline!\n");
}
//Request message (from nc to supernode)
static void unicast_request(struct mg_connection *nc, const struct mg_str msg) {
if(node == NULL){
printf("webApp_node is offline!\n");
return;
}
char addr[32], buf[500];
mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr), MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
printf("%s\tRequest\t[%d]\n", addr, (int)msg.len-1);
snprintf(buf, sizeof(buf), "?%s %.*s", addr, (int) msg.len-1, msg.p+1);
mg_send_websocket_frame(node, WEBSOCKET_OP_TEXT, buf, strlen(buf));
}
//Reply message (from node)
static void unicast_reply(const struct mg_str msg) {
if(node == NULL){
printf("webApp_node is offline!\n");
return;
}
//Get receiver address from msg
char receiverAddr[32];
int index = (int)(strchr(msg.p, ' ') - msg.p) + 1;
snprintf(receiverAddr, sizeof(receiverAddr), "%.*s", index - 1, msg.p);
printf("%s\tReply\t[%d]\n", receiverAddr, (int)msg.len - index);
//send msg to receiver
struct mg_connection *c;
for (c = mg_next(node->mgr, NULL); c != NULL; c = mg_next(node->mgr, c)) {
char addr[32];
mg_sock_addr_to_str(&c->sa, addr, sizeof(addr), MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
if (!strcmp(receiverAddr,addr))
mg_send_websocket_frame(c, WEBSOCKET_OP_TEXT, msg.p + index, msg.len - index);
}
}
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
switch (ev) {
case MG_EV_WEBSOCKET_HANDSHAKE_DONE: {
/*New websocket connection*/
display(nc, "+Connected+");
if(node!=NULL)
unicast(nc, mg_mk_str("$+"));
else
unicast(nc, mg_mk_str("$-"));
break;
}
case MG_EV_WEBSOCKET_FRAME: {
struct websocket_message *wm = (struct websocket_message *) ev_data;
/* New websocket message*/
struct mg_str d = {(char *) wm->data, wm->size};
if (d.p[0] == '$'){
char pass[100];
snprintf(pass, sizeof(pass), "%.*s",(int)d.len-1, &d.p[1]);
if(!strcmp(pass,server_pwd)){
if(node!=NULL)
unicast(node,mg_mk_str("$Another login is encountered! Please close/refresh this window"));
else
broadcast(nc, mg_mk_str("$+"));
node = nc;
unicast(node,mg_mk_str("$Access Granted!"));
display(nc, "*Became webApp_node*");
}else
unicast(nc,mg_mk_str("$Access Denied!"));
}
else if (d.p[0] == '?')
unicast_request(nc,d);
else if (nc == node)
unicast_reply(d);
else
unicast_forward(nc,d);
break;
}
case MG_EV_HTTP_REQUEST: {
mg_serve_http(nc, (struct http_message *) ev_data, s_http_server_opts);
break;
}
case MG_EV_CLOSE: {
/* Disconnect websocket*/
if(nc == node){
node = NULL;
display(nc,"!webApp_node Disconnected!");
broadcast(nc, mg_mk_str("$-"));
}else
display(nc, "-Disconnected-");
break;
}
}
}
int main(int argc, char** argv) {
s_http_port = argv[1];
server_pwd = argv[2];
struct mg_mgr mgr;
struct mg_connection *nc;
signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler);
setvbuf(stdout, NULL, _IOLBF, 0);
setvbuf(stderr, NULL, _IOLBF, 0);
mg_mgr_init(&mgr, NULL);
nc = mg_bind(&mgr, s_http_port, ev_handler);
mg_set_protocol_http_websocket(nc);
s_http_server_opts.document_root = "app/"; // Serve current directory
s_http_server_opts.enable_directory_listing = "no";
printf("Started on port %s\n", s_http_port);
while (s_signal_received == 0) {
mg_mgr_poll(&mgr, 200);
}
mg_mgr_free(&mgr);
return 0;
}