const path = require ( 'path' ) ;
const express = require ( 'express' ) ;
const app = express ( ) ;
const staticPath = path . join ( _ _dirname , "/public" ) ;
const fs = require ( 'fs' ) ;
var bodyParser = require ( 'body-parser' )
const cassandra = require ( 'cassandra-driver' ) ;
const client = new cassandra . Client ( {
contactPoints : [ '127.0.0.1:9042' ] ,
localDataCenter : 'datacenter1' ,
keyspace : 'glink'
} ) ;
let id = 1 ; /* Ideally should initialize id to be nextFromDB or write to file and read */
const port = 63342 ; // Port that the server listens on */
const RADIUS _OF _EARTH _IN _MILES = 3958.7614580848 ;
app . use ( bodyParser . json ( ) ) ;
app . use ( bodyParser . urlencoded ( {
extended : true
} ) ) ;
app . use ( express . static ( staticPath ) ) ;
const GLINK _SIZE = 6 ;
function getRandomGLink ( ) {
let glink = "" ;
glink = newString ( GLINK _SIZE ) ;
validateLink ( glink ) ;
return glink ;
}
function validateLink ( glink ) {
let qry = "SELECT id FROM data WHERE glink = ? allow filtering" ;
client . execute ( qry , [ glink ] , { } , ( err , result ) => {
if ( err ) {
console . log ( err . message ) ;
glink = null ;
}
if ( result . rows . length === 0 ) {
console . log ( "Done" ) ;
} else {
console . log ( glink ) ;
glink = getRandomGLink ( ) ;
}
} ) ;
return glink ;
}
function newString ( n ) {
let str = "" ;
let symbols = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ;
for ( let i = 0 ; i < n ; i ++ ) {
str += symbols . charAt ( Math . floor ( Math . random ( ) * 52 ) ) ;
}
return str ;
}
function nextId ( ) {
let next = id ;
id = id + 1 ;
return next ;
}
function filter ( path ) {
if ( path . match ( new RegExp ( "^/[a-zA-Z]+/*$" ) ) ) {
if ( path . charAt ( 0 ) === '/' ) {
path = path . substring ( 1 ) ;
}
return path ;
} else {
console . log ( "failed check. path is " + path ) ;
return null ;
}
}
function checkFileExistsSync ( fp ) {
let exists = true ;
try {
fs . accessSync ( fp , fs . constants . F _OK ) ;
} catch ( e ) {
exists = false ;
}
return exists ;
}
function calculateDistance ( lat1 , lat2 , long1 , long2 ) {
console . log ( lat1 + " " + lat2 + " " + long1 + " " + long2 ) ;
lat1 = lat1 * ( Math . PI / 180 ) ;
lat2 = lat2 * ( Math . PI / 180 ) ;
long1 = long1 * ( Math . PI / 180 ) ;
long2 = long2 * ( Math . PI / 180 ) ;
/* 2 asin(((lat2 - lat1)/2) ^ 2)*/
return ( 2 * Math . asin ( Math . sqrt ( Math . pow ( Math . sin ( ( lat2 - lat1 ) / 2 ) , 2 ) + Math . pow ( Math . sin ( ( long2 - long1 ) / 2 ) , 2 ) * Math . cos ( lat1 ) * Math . cos ( lat2 ) ) ) * RADIUS _OF _EARTH _IN _MILES ) ;
}
// app.get('/', (request, response) => {
// response.render("index.html");
// })
app . get ( '/node_modules/' , ( request , response ) => {
response . redirect ( "./error.html" ) ;
} )
app . get ( '/public/' , ( request , response ) => {
response . redirect ( "./error.html" ) ;
} )
const query = "INSERT INTO data (id, url, glink, time, isGeo, radius, latitude, longitude) VALUES (?, ?, ?, toTimestamp(now()), ?, ?, ?, ?)" ;
app . post ( '/__add' , function ( req , res ) {
let input _url = req . body . url ;
let input _glink = req . body . glink ;
let input _checkbox = req . body . restricted ;
let input _radius = req . body . radiusSelect ;
let input _latitude = req . body . latitude ;
let input _longitude = req . body . longitude ;
let geoBool = false ;
let geoString = "off" ;
//console.log("Received query " + input_url + " and " + input_glink);
if ( input _checkbox ) {
geoString = "on" ;
geoBool = true ;
} else {
input _radius = null ;
input _latitude = null ;
input _longitude = null ;
}
if ( input _glink === "" ) {
input _glink = getRandomGLink ( ) ;
let currID = nextId ( ) ;
console . log ( currID , input _url , input _glink , geoBool , input _radius , input _latitude , input _longitude )
client . execute ( query , [ currID , input _url , input _glink , geoBool , input _radius , input _latitude , input _longitude ] , { prepare : true } , function ( err , result ) {
if ( err ) {
res . send ( "<html><body><p style=\"font-family:Rubik; color:red;\">" + err . message + "</p></body></html>" ) ;
} else {
res . send ( "<html><head><link rel=\"stylesheet\" href=\"./css/response.css\"></head>" +
"<body><p class=\"para\">" +
"New entry has been added with geolocation turned " + geoString + " and url = " + req . body . url + " and glink = " +
"</p>" +
"<input type=\"text\" value=\"localhost:63342/" + input _glink + "\" readOnly=\"true\" id=\"myInput\" class=\"textbox\">" +
"<div class=\"tooltip\">" +
"<button onClick=\"myFunction()\" onMouseOut=\"outFunc()\">" +
"<span class=\"tooltiptext\" id=\"myTooltip\">Copy to clipboard</span>" +
"Copy text" +
"</button>" +
"</div>" +
"<script src=\"./src/response.js\"></script>" +
"</body></html>" ) ;
}
} ) ;
} else {
let selectQuery = "SELECT id FROM data where glink = ? allow filtering" ;
console . log ( input _glink ) ;
client . execute ( selectQuery , [ input _glink ] , { } , function ( err , result ) {
if ( result . rows . length === 0 ) {
let currID = nextId ( ) ;
console . log ( "values are: " + currID , input _url , input _glink , geoBool , input _radius , input _latitude , input _longitude ) ;
client . execute ( query , [ currID , input _url , input _glink , geoBool , input _radius , input _latitude , input _longitude ] , { prepare : true } , function ( err , result ) {
if ( err ) {
res . send ( "<html><body><p style=\"font-family:Rubik; font-size:large; color:red;\">" + err . message + "</p></body></html>" ) ;
} else {
res . send ( "<html><head><link rel=\"stylesheet\" href=\"./css/response.css\"></head>" +
"<body><p class=\"para\">" +
"New entry has been added with geolocation turned " + geoString + " and url = " + req . body . url + " and glink = " +
"</p>" +
"<input type=\"text\" value=\"localhost:63342/" + req . body . glink + "\" readOnly=\"true\" id=\"myInput\" class=\"textbox\">" +
"<div class=\"tooltip\">" +
"<button onClick=\"myFunction()\" onMouseOut=\"outFunc()\">" +
"<span class=\"tooltiptext\" id=\"myTooltip\">Copy to clipboard</span>" +
"Copy text" +
"</button>" +
"</div>" +
"<script src=\"./src/response.js\"></script>" +
"</body></html>" ) ;
}
} ) ;
} else {
res . send ( "<html><body><p style=\"font-family:Rubik; font-size: 20px; color:red;\">This glink has already been registered. Please try a different glink</p></body></html>" ) ;
}
} ) ;
}
} )
app . post ( '/__check' , function ( req , res ) {
let user _latitude = req . body . latitude ;
let user _longitude = req . body . longitude ;
let req _path = req . body . glink ;
let selQry = "select url, latitude, longitude, radius from data where glink = ? allow filtering" ;
client . execute ( selQry , [ req _path ] , { } , function ( err , result ) {
if ( result . rows . length === 0 ) {
res . redirect ( "/error.html" ) ;
} else {
let page = result . rows [ 0 ] [ "url" ] ;
let latitude = result . rows [ 0 ] [ "latitude" ] ;
let longitude = result . rows [ 0 ] [ "longitude" ] ;
let radius = result . rows [ 0 ] [ "radius" ] ;
console . log ( user _latitude + user _longitude ) ;
let distance = calculateDistance ( user _latitude , latitude , user _longitude , longitude ) ;
console . log ( distance + " " + radius ) ;
if ( distance < radius ) {
console . log ( "inside radius" ) ;
res . writeHead ( 301 , { Location : page } ) ;
res . end ( ) ;
} else {
res . redirect ( "./error.html " ) ;
console . log ( "Outside radius" ) ;
}
}
} )
} )
/* Redirect requests to corresponding entry in database */
app . get ( '/*' , ( request , response , cb ) => {
console . log ( "Entered" ) ;
let original _request = request . path ;
console . log ( original _request ) ;
if ( original _request . charAt ( original _request . length - 1 ) === '/' && original _request . length > 1 ) {
original _request = original _request . substring ( 0 , original _request . length - 1 ) ;
}
let req _path = filter ( original _request ) ;
if ( ! req _path ) {
if ( checkFileExistsSync ( original _request ) ) {
response . redirect ( original _request ) ;
} else {
response . redirect ( "/error.html" ) ;
return cb ( "" ) ;
}
} else {
let geoQry = "select isGeo from data where glink = ? allow filtering" ;
client . execute ( geoQry , [ req _path ] , { } , function ( err , result ) {
if ( result . rows . length === 0 ) {
response . redirect ( "/error.html" ) ;
} else {
let isGeo = result . rows [ 0 ] [ "isgeo" ] ;
if ( isGeo ) {
response . send ( "<html><head></head><body><p style='color:red;'>Redirecting you to the website! Please wait ...</p><form id=\"form\" action=\"/__check\" method=\"post\"><input type=\"hidden\" name=\"latitude\" id=\"latitude\"><input type=\"hidden\" name=\"longitude\" id=\"longitude\"><input type=\"hidden\" name=\"glink\" id=\"glink\" value=\"" + req _path + "\"></form><script src=\"./src/redirect.js\"></script></body></html>" ) ;
response . end ( ) ;
} else {
let selQry = "select url from data where glink = ? allow filtering" ;
client . execute ( selQry , [ req _path ] , { } , function ( err , result ) {
if ( result . rows . length === 0 ) {
response . redirect ( "/error.html" ) ;
} else {
let page = result . rows [ 0 ] [ "url" ] ;
console . log ( page ) ;
response . writeHead ( 301 , { Location : page } ) ;
response . end ( ) ;
}
} )
}
}
} )
}
} )
app . listen ( port , function ( ) {
console . log ( "server listening on port 63342" ) ;
} )
/** Validate url and glink on client side as well */
/** Validate to make sure request is a file before sending it */