Skip to content

Commit 47cc983

Browse files
author
jbenguira
committed
cloned from ws-trail
1 parent 30ac920 commit 47cc983

30 files changed

+2648
-0
lines changed

Diff for: .gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
memorystate.json
2+
core
3+
14
# Logs
25
logs
36
*.log

Diff for: API/DB.js

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
const { Pool, Client } = require('pg')
2+
const pool = new Pool({
3+
user: 'postgres',
4+
password: '8ed89611-dff5-444f-867c-c66098a349cd',
5+
host: '172.17.0.1',
6+
database: 'ws_trail',
7+
port: 5432,
8+
max: 4
9+
})
10+
11+
module.exports.SaveEvent = async function (data, sourceIP, country) {
12+
13+
var userID = data.uid;
14+
var context = data.ctx;
15+
var eventType = data.type;
16+
var eventTitle = data.title;
17+
var eventValue = data.val;
18+
var eventData = data.data;
19+
var wlid = data.wlid;
20+
21+
if ( country != null && country != ""){
22+
if ( eventData == null ){
23+
eventData = {};
24+
}
25+
eventData.country = country;
26+
}
27+
28+
var SQL = `INSERT INTO Logs (time, userID, context, eventType, eventTitle, eventValue, eventData, sourceIP, wlid)
29+
VALUES (NOW(), '${Clean(userID)}', '${Clean(context)}', '${Clean(eventType)}', '${Clean(eventTitle)}',
30+
'${Clean(eventValue)}', '${Clean(JSON.stringify(eventData))}', '${sourceIP}', '${Clean(wlid)}' ) RETURNING time;`
31+
32+
//console.log(SQL);
33+
34+
var rez = null;
35+
try{
36+
rez = await pool.query(SQL);
37+
}
38+
catch(ex){
39+
console.log("Crash in SQL Query for SaveEvent: " + SQL);
40+
var obj = { count: 0, command: "INVALID_QUERY", time: 0 };
41+
return obj
42+
}
43+
//console.log(rez);
44+
var obj = { count: rez.rowCount, command: rez.command, time: rez.rows[0].time };
45+
return obj
46+
}
47+
48+
module.exports.Query = async function (SQL, sourceIP) {
49+
var rez = await pool.query(SQL);
50+
//console.log(rez);
51+
var obj = { count: rez.rowCount, rows: rez.rows };
52+
return obj
53+
}
54+
55+
module.exports.StartOrUpdateSession = async function (data, sourceIP, userAgent) {
56+
57+
var userID = data.uid;
58+
59+
var context = data.ctx;
60+
if ( context == null ){
61+
context = "";
62+
}
63+
64+
var wlid = data.wlid;
65+
66+
if ( wlid == null || wlid == "" ){
67+
wlid = -1;
68+
}
69+
else{
70+
try{
71+
wlid = parseInt(wlid);
72+
}catch(ex){}
73+
}
74+
75+
76+
var SQLSearch = `SELECT * FROM sessions WHERE lastupdate > ( now()::timestamp - INTERVAL '1 min' )::timestamp ORDER BY id desc LIMIT 1`;
77+
var rezSearch = await pool.query(SQLSearch);
78+
79+
if ( rezSearch.rowCount == 0 ){
80+
var SQL = `INSERT INTO sessions (start_time, is_active, wlid, userid, context, total_time, active_time, idle_time, user_agent, sourceip, lastupdate)
81+
VALUES (NOW(), '1', '${Clean(wlid)}', '${Clean(userID)}', '${Clean(context)}', 0, 0, 0, '${Clean(userAgent)}', '${sourceIP}', NOW() ) RETURNING id;`
82+
var rez = await pool.query(SQL);
83+
//console.log(rez);
84+
var obj = { count: rez.rowCount, command: rez.command, sessionID: rez.rows[0].id };
85+
return obj
86+
}
87+
else{
88+
var timeDiffInMinutes = `extract(epoch from (NOW()::timestamp - start_time::timestamp))::integer`;
89+
var SQL = `UPDATE sessions SET is_active = '1', total_time = ${timeDiffInMinutes}, lastupdate = NOW() WHERE id = '${rezSearch.rows[0].id}';`
90+
var rez = await pool.query(SQL);
91+
//console.log(rez);
92+
var obj = { count: rez.rowCount, command: rez.command, sessionID: rezSearch.rows[0].id };
93+
return obj
94+
}
95+
96+
}
97+
98+
module.exports.UpdateSession = async function (sessionID, active_time, is_active) {
99+
100+
var timeDiffInMinutes = `extract(epoch from (NOW() - start_time::timestamp))::integer`;
101+
102+
var SQL = `UPDATE sessions SET is_active = '${Clean(is_active)}', total_time = ${timeDiffInMinutes}, active_time = active_time + ${active_time}, idle_time = (${timeDiffInMinutes}) - (active_time + ${active_time}), lastupdate = NOW() WHERE id = '${sessionID}';`
103+
//console.log(SQL);
104+
105+
var rez = await pool.query(SQL);
106+
107+
var obj = { count: rez.rowCount, command: rez.command, sessionID: sessionID };
108+
return obj
109+
110+
}
111+
112+
module.exports.CloseSession = async function (sessionID) {
113+
114+
/*
115+
var timeDiffInMinutes = `(DATE_PART('day', end_time::timestamp - start_time::timestamp) * 24 +
116+
DATE_PART('hour', end_time::timestamp - start_time::timestamp)) * 60 +
117+
DATE_PART('minute', end_time::timestamp - start_time::timestamp)`;
118+
*/
119+
120+
var timeDiffInMinutes = `extract(epoch from (NOW()::timestamp - start_time::timestamp))::integer`;
121+
122+
var SQL = `UPDATE sessions SET end_time = NOW(), is_active = '0', total_time = ${timeDiffInMinutes}, idle_time = (${timeDiffInMinutes}) - (active_time), lastupdate = NOW() WHERE id = '${sessionID}';`
123+
var rez = await pool.query(SQL);
124+
//console.log(rez);
125+
var obj = { count: rez.rowCount, command: rez.command, sessionID: sessionID };
126+
return obj
127+
128+
}
129+
130+
function Clean(txt){
131+
if ( txt == null ){ return ""; }
132+
else{ return (txt + "").replace(/\'/g, "''"); }
133+
}

Diff for: API/REST/GenerateJWT.js

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
var jwt = require('jsonwebtoken');
2+
var JWTKey = require("../../appconfig.json").JWTKey;
3+
var hardcodedAPIKey = require("../../appconfig.json").ApiKey;
4+
5+
exports.handler = async (event, context, callback) => {
6+
7+
var beginPipeline = process.hrtime();
8+
9+
//debug
10+
//var body = {"uid":"120", "token": "123615z1ef88136zg5e1"};
11+
12+
var ApiKey = event.headers["x-api-key"];
13+
14+
//PROD
15+
var body = null;
16+
try{
17+
body = JSON.parse(event.body);
18+
}
19+
catch(ex){
20+
callback(null, {
21+
status: 400,
22+
content: "Invalid content provided, posted body must be in JSON"
23+
});
24+
return;
25+
}
26+
27+
28+
var uid = body.uid;
29+
//if ( ApiKey != hardcodedAPIKey ){
30+
if ( ApiKey != hardcodedAPIKey ){
31+
//console.log(event);
32+
callback(null, {
33+
status: 400,
34+
content: "Invalid token provided"
35+
});
36+
return;
37+
}
38+
39+
var token = jwt.sign(body, JWTKey);
40+
41+
42+
const nanoSeconds = process.hrtime(beginPipeline).reduce((sec, nano) => sec * 1e9 + nano);
43+
var durationMS = (nanoSeconds/1000000);
44+
45+
var processTime = durationMS.toFixed(2) + "ms";
46+
47+
callback(null, {
48+
status: 200,
49+
content: {"jwt": token},
50+
headers:{
51+
"processTime": processTime,
52+
"Content-Type": "application/json"
53+
}
54+
});
55+
56+
};

Diff for: API/REST/Query.js

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
var DB = require("../DB.js");
2+
var hardcodedAPIKey = require("../../appconfig.json").ApiKey;
3+
4+
exports.handler = async (event, context, callback) => {
5+
6+
var beginPipeline = process.hrtime();
7+
8+
//debug
9+
//var body = {"uid":"120", "ctx":"", "start":"", "end":"", "offset": 0, "token": "123615z1ef88136zg5e1"};
10+
var ApiKey = event.headers["x-api-key"];
11+
12+
//PROD
13+
var body = null;
14+
try{
15+
body = JSON.parse(event.body);
16+
}
17+
catch(ex){
18+
callback(null, {
19+
status: 400,
20+
content: "Invalid content provided, posted body must be in JSON"
21+
});
22+
return;
23+
}
24+
25+
var uid = body.uid;
26+
var ctx = body.ctx;
27+
var start = body.start;
28+
var end = body.end;
29+
30+
var offset = body.offset;
31+
var pageSize = 200;
32+
if ( offset == null || offset == ""){
33+
offset = 0;
34+
}
35+
36+
var pageSize = body.pageSize;
37+
if ( pageSize == null || pageSize == ""){
38+
pageSize = 25;
39+
}
40+
41+
var eventType = body.eventType;
42+
if ( eventType == null || eventType == ""){
43+
eventType = "";
44+
}
45+
46+
var showSession = body.session;
47+
if ( showSession == null || showSession == ""){
48+
showSession = "";
49+
}
50+
51+
var wlid = body.wlid;
52+
if ( wlid == null || wlid == ""){
53+
wlid = "";
54+
}
55+
56+
if ( ApiKey != hardcodedAPIKey ){
57+
callback(null, {
58+
status: 400,
59+
content: "Invalid token provided"
60+
});
61+
return;
62+
}
63+
64+
//TODO: ensure user is allowed to query this uid & ctx!
65+
66+
var SQL = "SELECT * FROM logs WHERE 1=1 ";
67+
if ( uid != null && uid != "" ){
68+
SQL += " AND userID = '" + Clean(uid) + "' ";
69+
}
70+
if ( ctx != null && ctx != "" ){
71+
SQL += " AND context = '" + Clean(ctx) + "' ";
72+
}
73+
if ( start != null && start != "" ){
74+
SQL += " AND time >= '" + Clean(start) + "' ";
75+
}
76+
if ( end != null && end != "" ){
77+
SQL += " AND time <= '" + Clean(end) + "' ";
78+
}
79+
80+
if ( eventType != "") {
81+
SQL += " AND eventtype = '" + Clean(eventType) + "' ";
82+
}
83+
84+
if ( eventType != "Session" && showSession == false ) {
85+
SQL += " AND eventtype != 'Session' ";
86+
}
87+
88+
if ( wlid != "") {
89+
SQL += " AND wlid = '" + Clean(wlid) + "' ";
90+
}
91+
92+
//ORDER
93+
SQL += " ORDER BY time desc "
94+
95+
//add a LIMIT & OFFSET
96+
SQL += " LIMIT " + pageSize + " OFFSET " + Clean(offset);
97+
98+
99+
100+
var obj = await DB.Query(SQL, event.ip);
101+
102+
const nanoSeconds = process.hrtime(beginPipeline).reduce((sec, nano) => sec * 1e9 + nano);
103+
var durationMS = (nanoSeconds/1000000);
104+
105+
obj.processTime = durationMS.toFixed(2) + "ms";
106+
107+
callback(null, {
108+
status: 200,
109+
content: obj,
110+
headers:{
111+
"processTime": obj.processTime,
112+
"Content-Type": "application/json; charset=utf-8"
113+
}
114+
});
115+
116+
};
117+
118+
119+
120+
function Clean(txt){
121+
if ( txt == null ){
122+
return "";
123+
}
124+
else{
125+
return (txt + "").replace(/\'/g, "''");
126+
}
127+
}

0 commit comments

Comments
 (0)